Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

factory_reg.hpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////
00002 // A "supermacro"-style classloader registration snippet for the
00003 // s11n::fac layer.
00004 ////////////////////////////////////////////////////////////////////////
00005 // Macros to be set before including this file:
00006 //
00007 // S11N_FACREG_TYPE: type to be registered.
00008 //
00009 // S11N_FACREG_TYPE_NAME: string name to register S11N_FACREG_TYPE with.
00010 //
00011 // S11N_FACREG_INTERFACE_TYPE: base-most type of S11N_FACREG_TYPE.
00012 // Defaults to S11N_FACREG_TYPE.
00013 //
00014 // OPTIONAL/special-case macros:
00015 //
00016 // S11N_FACREG_TYPE_IS_ABSTRACT:
00017 // This macro should be used only when S11N_FACREG_TYPE is an abstract type.
00018 // If S11N_FACREG_TYPE is an abstract base class, define this
00019 // macro to any value. If this is set then a no-op specialization
00020 // of P::Hook::create_hook<> is installed so no calls to 
00021 // new S11N_FACREG_TYPE will be made by the default factories. 
00022 //
00023 //
00024 // All of the above macros are #undef'd by this file, so it may be
00025 // included multiple times in succession.
00026 ////////////////////////////////////////////////////////////////////////
00027 
00028 #ifndef S11N_FACREG_TYPE
00029 #  error "You must define S11N_FACREG_TYPE before including this file."
00030 #endif
00031 
00032 #ifndef S11N_FACREG_TYPE_NAME
00033 #  error "You must define S11N_FACREG_TYPE_NAME before including this file."
00034 #endif
00035 
00036 #ifndef S11N_FACREG_INTERFACE_TYPE
00037 #  define S11N_FACREG_INTERFACE_TYPE S11N_FACREG_TYPE
00038 #endif
00039 
00040 
00041 #ifdef S11N_FACREG_TYPE_IS_ABSTRACT
00042 // Install a specialization of Factory's default factory type,
00043 // so that we won't try to instantiate a S11N_FACREG_TYPE object.
00044 // For the non-abstract case we will rely on the default create_hook
00045 // implementation (or a client-installed specialization).
00046 namespace s11n { namespace fac {
00047     /**
00048        create_hook specialization to install a no-op
00049        factory. Intended for use with abastract types.
00050     */
00051     template <>
00052     struct S11N_EXPORT_API create_hook< S11N_FACREG_INTERFACE_TYPE , S11N_FACREG_TYPE >
00053     {
00054         typedef S11N_FACREG_INTERFACE_TYPE * result_type;
00055         typedef S11N_FACREG_TYPE actual_type;
00056         /** Returns 0. */
00057         static result_type create()
00058         {
00059             return 0;
00060         }
00061     };
00062 } } // namespace s11n::fac
00063 #endif // S11N_FACREG_TYPE_IS_ABSTRACT
00064 
00065 namespace {
00066 
00067 #  ifndef s11n_FACTORY_REG_CONTEXT_DEFINED
00068 #  define s11n_FACTORY_REG_CONTEXT_DEFINED 1
00069     ///////////////////////////////////////////////////////////////
00070     // we must not include this more than once per compilation unit
00071     /**
00072        A unique (per Context/per compilation unit) space to assign
00073        a bogus value for classloader registration purposes (see
00074        the classloader docs for a full description of how this
00075        works).
00076     */
00077     template <typename Context>
00078     struct S11N_EXPORT_API s11n_factory_reg_context
00079     {
00080         s11n_factory_reg_context()
00081         {
00082             if( true == placeholder ); // weird workaround, just to reference the var. 
00083         }
00084         /**
00085            Placeholder variable for automatic factory
00086            registration.
00087         */
00088         static bool placeholder;
00089     };
00090 #  endif // !s11n_FACTORY_REG_CONTEXT_DEFINED
00091 
00092     /**
00093        Placeholder variable for automatic factory registration.
00094     */
00095     template <>
00096     bool /* do we need S11N_EXPORT_API here??? */
00097     s11n_factory_reg_context< S11N_FACREG_TYPE >::placeholder= (
00098                                     ::s11n::fac::register_factory< S11N_FACREG_INTERFACE_TYPE >(
00099                                                                std::string( S11N_FACREG_TYPE_NAME ),
00100                                                                ::s11n::fac::create_hook<
00101                                                                S11N_FACREG_INTERFACE_TYPE,
00102                                                                S11N_FACREG_TYPE
00103                                                                >::create
00104                                     ),
00105                                       true);
00106     // DAMN, that's fugly!
00107 } // anon namespace
00108 
00109 #ifdef S11N_FACREG_TYPE_IS_ABSTRACT
00110 #  undef S11N_FACREG_TYPE_IS_ABSTRACT
00111 #endif
00112 #undef S11N_FACREG_TYPE
00113 #undef S11N_FACREG_INTERFACE_TYPE
00114 #undef S11N_FACREG_TYPE_NAME

Generated on Sun Dec 18 18:30:27 2005 for libs11n-1.2.2 by  doxygen 1.4.4