#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