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 create_hook<> is installed so no calls to (new S11N_FACREG_TYPE) will
00021 // 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 #include <s11n.net/s11n/export.hpp>
00041 
00042 #ifdef S11N_FACREG_TYPE_IS_ABSTRACT
00043 // Install a specialization of Factory's default factory type,
00044 // so that we won't try to instantiate a S11N_FACREG_TYPE object.
00045 // For the non-abstract case we will rely on the default create_hook
00046 // implementation (or a client-installed specialization).
00047 namespace s11n { namespace fac {
00048     /**
00049        create_hook specialization to install a no-op
00050        factory. Intended for use with abastract types.
00051     */
00052     template <>
00053     struct S11N_EXPORT_API create_hook< S11N_FACREG_INTERFACE_TYPE , S11N_FACREG_TYPE >
00054     {
00055         typedef S11N_FACREG_INTERFACE_TYPE * result_type;
00056         typedef S11N_FACREG_TYPE actual_type;
00057         /** Returns 0. */
00058         static result_type create()
00059         {
00060             return 0;
00061         }
00062     };
00063 } } // namespace s11n::fac
00064 #endif // S11N_FACREG_TYPE_IS_ABSTRACT
00065 
00066 namespace {
00067 
00068 #  ifndef s11n_FACTORY_REG_CONTEXT_DEFINED
00069 #  define s11n_FACTORY_REG_CONTEXT_DEFINED 1
00070     ///////////////////////////////////////////////////////////////
00071     // we must not include this more than once per compilation unit
00072     /**
00073        A unique (per Context/per compilation unit) space to assign
00074        a bogus value for classloader registration purposes (see
00075        the classloader docs for a full description of how this
00076        works).
00077     */
00078     template <typename Context>
00079     struct S11N_EXPORT_API s11n_factory_reg_context
00080     {
00081         s11n_factory_reg_context()
00082         {
00083             if( true == placeholder ); // weird workaround, just to reference the var. 
00084         }
00085         /**
00086            Placeholder variable for automatic factory
00087            registration.
00088         */
00089         static bool placeholder;
00090     };
00091 #  endif // !s11n_FACTORY_REG_CONTEXT_DEFINED
00092 
00093     /**
00094        Placeholder variable for automatic factory registration.
00095     */
00096     template <>
00097     bool /* do we need S11N_EXPORT_API here??? */
00098     s11n_factory_reg_context< S11N_FACREG_TYPE >::placeholder= (
00099                                     ::s11n::fac::register_factory< S11N_FACREG_INTERFACE_TYPE >(
00100                                                                std::string( S11N_FACREG_TYPE_NAME ),
00101                                                                ::s11n::fac::create_hook<
00102                                                                S11N_FACREG_INTERFACE_TYPE,
00103                                                                S11N_FACREG_TYPE
00104                                                                >::create
00105                                     ),
00106                                       true);
00107     // DAMN, that's fugly!
00108 } // anon namespace
00109 
00110 #ifdef S11N_FACREG_TYPE_IS_ABSTRACT
00111 #  undef S11N_FACREG_TYPE_IS_ABSTRACT
00112 #endif
00113 #undef S11N_FACREG_TYPE
00114 #undef S11N_FACREG_INTERFACE_TYPE
00115 #undef S11N_FACREG_TYPE_NAME

Generated on Sun Apr 27 13:16:04 2008 for libs11n by  doxygen 1.5.3