#include
#include
#include
#include
#ifndef NEW_PTR_MAX_PARAMS
#define NEW_PTR_MAX_PARAMS 16
#endif // NEW_PTR_MAX_PARAMS
#define NEW_PTR_PARAM_DECL(z, n, _) BOOST_PP_COMMA_IF(n) A ## n const & a ## n
class new_ptr_access {
private:
template
static void destroy(T* pT) {
typedef char typeMustBeCompleteType[sizeof(T) ? 1 : -1];
(void)sizeof(typeMustBeCompleteType);
delete pT;
}
#define NEW_PTR_ACCESS_CREATE_FUNCTION(z, n, _) \
template< class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class A) > \
static boost::shared_ptr create(BOOST_PP_REPEAT(n, NEW_PTR_PARAM_DECL, _)) { \
return boost::shared_ptr(new T(BOOST_PP_ENUM_PARAMS(n, a)), destroy); \
} \
BOOST_PP_REPEAT(BOOST_PP_INC(NEW_PTR_MAX_PARAMS), NEW_PTR_ACCESS_CREATE_FUNCTION, _)
#undef NEW_PTR_ACCESS_CREATE_FUNCTION
#define NEW_PTR_ACCESS_FRIEND_DECL(z, n, _) \
template \
friend boost::shared_ptr new_ptr(BOOST_PP_REPEAT(n, NEW_PTR_PARAM_DECL, _)); \
BOOST_PP_REPEAT(BOOST_PP_INC(NEW_PTR_MAX_PARAMS), NEW_PTR_ACCESS_FRIEND_DECL, _)
#undef NEW_PTR_ACCESS_FRIEND_DECL
private:
new_ptr_access();
};
#define NEW_PTR_FUNCTION_DECL(z, n, _) \
template< class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)> \
boost::shared_ptr new_ptr(BOOST_PP_REPEAT(n, NEW_PTR_PARAM_DECL, _)) { \
return new_ptr_access::create(BOOST_PP_ENUM_PARAMS(n, a)); \
} \
BOOST_PP_REPEAT(BOOST_PP_INC(NEW_PTR_MAX_PARAMS), NEW_PTR_FUNCTION_DECL, _)
#undef NEW_PTR_FUNCTION_DECL
#undef NEW_PTR_PARAM_DECL
#undef NEW_PTR_DECL
An example:
class foo {
private:
foo()
: name_("My Name")
{ }
foo(const std::string name)
: name_(name)
{ }
foo(int i, int j)
: name_("I & J")
{ }
~foo() { }
friend class new_ptr_access;
public:
const std::string& name() const { return name_; }
private:
std::string name_;
};
shared_ptr bar1 = new_ptr();
shared_ptr bar2 = new_ptr("example");
shared_ptr bar3 = new_ptr(1, 2);
delete bar1.get(); // won't compile
foo stackInstance("example"); // won't compile
foo* heapInstance = new foo("example") // won't compile