|
From: stephan b. <sg...@us...> - 2004-12-24 00:57:34
|
Update of /cvsroot/pclasses/pclasses2/include/pclasses In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24381 Added Files: FactoryReg.h Log Message: egg --- NEW FILE: FactoryReg.h --- //////////////////////////////////////////////////////////////////////// // FactoryReg.h // A "supermacro"-style classloader registration snippet for P::Factory. //////////////////////////////////////////////////////////////////////// // Macros to be set before including this file: // // PFACREG_TYPE: type to be registered. // // PFACREG_TYPE_NAME: string name to register PFACREG_TYPE with. // // PFACREG_TYPE_INTERFACE: base-most type of PFACREG_TYPE. // Defaults to PFACREG_TYPE. // // OPTIONAL/special-case macros: // // PFACREG_TYPE_IS_ABSTRACT: // This macro should be used only when PFACREG_TYPE is an abstract type. // If PFACREG_TYPE is an abstract base class, define this // macro to any value. If this is set then a no-op specialization // of P::Hook::FactoryCreateHook<> is installed so no calls to // new PFACREG_TYPE will be made by the default factories. // // // All of the above macros are #undef'd by this file, so it may be // included multiple times in succession. //////////////////////////////////////////////////////////////////////// #ifndef PFACREG_TYPE # error "You must define PFACREG_TYPE before including this file." #endif #ifndef PFACREG_TYPE_NAME # error "You must define PFACREG_TYPE_NAME before including this file." #endif #ifndef PFACREG_TYPE_INTERFACE # define PFACREG_TYPE_INTERFACE PFACREG_TYPE #endif # ifdef PFACREG_TYPE_IS_ABSTRACT // install a specialization of Factory's default factory type, // so that we won't try to instantiation a PFACREG_TYPE object. // Remember that this code will only happen when // ( PFACREG_TYPE_INTERFACE == PFACREG_TYPE ) // assuming the user doesn't mis-use the supermacro API. namespace P { namespace Hook { template <> struct FactoryCreateHook< PFACREG_TYPE_INTERFACE , PFACREG_TYPE > { typedef PFACREG_TYPE_INTERFACE * result_type; typedef PFACREG_TYPE actual_type; static result_type create() { return 0; } }; } } // namespace P::Hook # endif // PFACREG_TYPE_IS_ABSTRACT namespace { # ifndef p_FACTORY_REG_CONTEXT_DEFINED # define p_FACTORY_REG_CONTEXT_DEFINED 1 /////////////////////////////////////////////////////////////// // we must not include this more than once per compilation unit /////////////////////////////////////////////////////////////// // A unique (per Context/per compilation unit) space to assign // a bogus value for classloader registration purposes (see // the classloader docs for a full description of how this // works). template <typename Context> struct pfactory_reg_context { static bool placeholder; }; template <typename Context> bool pfactory_reg_context<Context>::placeholder = false; # endif // !p_FACTORY_REG_CONTEXT_DEFINED # define FACTORY_FUNCTION_ ::P::Hook::FactoryCreateHook< PFACREG_TYPE_INTERFACE , PFACREG_TYPE >::create //////////////////////////////////////////////////////////////////////// // Register a factory with the classloader: bool pfactory_reg_context< PFACREG_TYPE >::placeholder= ( P::NamedTypeFactory< PFACREG_TYPE_INTERFACE >::instance().registerFactory( PFACREG_TYPE_NAME, FACTORY_FUNCTION_ ), true); # undef FACTORY_FUNCTION_ } // anon namespace #ifdef PFACREG_TYPE_IS_ABSTRACT # undef PFACREG_TYPE_IS_ABSTRACT #endif #undef PFACREG_TYPE #undef PFACREG_TYPE_INTERFACE #undef PFACREG_TYPE_NAME |