Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members

reg_serializable.h

00001 ////////////////////////////////////////////////////////////////////////
00002 // "supermacro" registering "default serializable" types.
00003 // It is compatible with all types which have serialization operators().
00004 //
00005 // License: Public Domain
00006 // Author: stephan@s11n.net
00007 //
00008 // This file does not use a conventional BLAH_H_INCLUDED guard.
00009 // Yes, that's on purpose.
00010 //
00011 // The s11n header files are expected to have been included by the
00012 // time this file is ever included.
00013 //
00014 // Sample usage:
00015 //
00016 // #define S11N_TYPE MySubtype
00017 // #define S11N_BASE_TYPE MyBase  // defaults to S11N_TYPE
00018 // #define S11N_NAME "MySubtype"
00019 // // optional:
00020 // // #define S11N_SERIALIZE_FUNCTION member_func_name // default= operator()
00021 // // #define S11N_DESERIALIZE_FUNCTION member_func_name // default= operator()
00022 // #include [this file]
00023 //
00024 // Repeat for each type. If MyBase is abstract, also define this
00025 // when registering MyBase:
00026 //
00027 // #define S11N_ABSTRACT_BASE
00028 //
00029 // That is ONLY necessary when registering MyBase, not when
00030 // registering a subclass.
00031 //
00032 // After each include all of these macros are unset so that they may
00033 // be immediately re-used for another registration.
00034 //
00035 ////////////////////////////////////////////////////////////////////////
00036 // General notes:
00037 //
00038 // By s11n convention S11N_NAME should contain no spaces, even for
00039 // template types. Thus, please use:
00040 //
00041 //    "std::list<std::list<foo*>>"
00042 //
00043 // instead of:
00044 //
00045 //     "std::list<std::<list<foo *> >"
00046 //
00047 // C++ needs a space between "> >", but s11n does not.
00048 // That said, s11n DOESN'T CARE what class names you use, as long
00049 // as you're consistent.
00050 //
00051 ////////////////////////////////////////////////////////////////////////
00052 
00053 #define DEBUG_REG 0
00054 #if DEBUG_REG
00055 #  include <s11n/debuggering_macros.h>
00056 #endif
00057 
00058 
00059 #ifndef S11N_TYPE
00060 #    error "S11N_TYPE is not set. Set it to the type you want to proxy before including this file!"
00061 #endif
00062 
00063 #ifndef S11N_NAME
00064 #    error "S11N_NAME must be set to the string form of S11N_TYPE"
00065 #endif
00066 
00067 
00068 #ifndef S11N_BASE_TYPE
00069 #  define S11N_BASE_TYPE S11N_TYPE
00070 // ARGUABLE!!!!!!
00071 // #    error "S11N_BASE_TYPE is not set. Set it before including this file!"
00072 #endif
00073 
00074 
00075 #ifndef S11N_SERIALIZE_FUNCTION
00076 #  define S11N_SERIALIZE_FUNCTION operator()
00077 #endif
00078 
00079 #ifndef S11N_DESERIALIZE_FUNCTION
00080 #  define S11N_DESERIALIZE_FUNCTION operator()
00081 #endif
00082 
00083 ////////////////////////////////////////////////////////////////////////
00084 // set up the type name registry
00085 #define NAME_TYPE S11N_TYPE
00086 #define TYPE_NAME S11N_NAME
00087 #include <s11n/name_type.h>
00088 ////////////////////////////////////////////////////////////////////////
00089 
00090 
00091 namespace { // anonymous namespace is important for complex linking reasons.
00092 
00093 
00094 
00095 #ifndef s11n_SERIALIZER_REG_CONTEXT_DEFINED
00096 #define s11n_SERIALIZER_REG_CONTEXT_DEFINED 1
00097         ///////////////////////////////////////////////////////////////
00098         // we must not include this more than once per compilation unit
00099         ///////////////////////////////////////////////////////////////
00100         // A unique (per Context/per compilation unit) space to assign
00101         // a bogus value for classloader registration purposes (see
00102         // the classloader docs for a full description of how this
00103         // works).
00104         template <typename Context>
00105         struct serializer_reg_context
00106         {
00107                 typedef Context context;
00108                 static bool placeholder;
00109                 static void reg()
00110                 {
00111                         CERR << "ACHTUNG: " << ::classname< serializer_reg_context<context> >()
00112                              << " is not specialized, which means that registration hasn't been done.\n"
00113                              << "For instructions see: " << __FILE__ << "\n";
00114                         abort();
00115                 }
00116 
00117         };
00118         template <typename Context> bool serializer_reg_context<Context>::placeholder = false;
00119 #endif //  !s11n_SERIALIZER_REG_CONTEXT_DEFINED
00120 
00121         template <>
00122         struct serializer_reg_context< S11N_TYPE >
00123         {
00124                 typedef S11N_TYPE context;
00125                 static bool placeholder;
00126                 static void reg()
00127                 {
00128 #if DEBUG_REG
00129                         CERR << "\nRegistering Serializable: " << S11N_NAME << "\n"
00130                              << "::classname<>() says: " << ::classname< S11N_TYPE >() << "\n"
00131                                 ;
00132 #endif // DEBUG_REG
00133 
00134 #ifdef S11N_ABSTRACT_BASE
00135                         cllite::register_abstract_base< S11N_BASE_TYPE >( ::classname< context >() );
00136 #  undef S11N_ABSTRACT_BASE
00137 #else
00138                         cllite::register_factory< S11N_BASE_TYPE, S11N_TYPE >( ::classname< context >() );
00139                         cllite::register_factory< S11N_TYPE, S11N_TYPE >( ::classname< context >() );
00140 #endif
00141                 }
00142         };
00143 
00144         bool serializer_reg_context< S11N_TYPE >::placeholder = (
00145                                                               serializer_reg_context< S11N_TYPE >::reg()
00146                                                               ,
00147                                                               true
00148                                                               );
00149 // serializer_reg_context 
00150 ////////////////////////////////////////////////////////////////////////////////
00151 
00152         ////////////////////////////////////////////////////////////////////////
00153         // Note that the code below is useless for abstract types, but:
00154         //
00155         // a) it's difficult to avoid with the macro (without adding
00156         // to the client interface)
00157         //
00158         // b) such types will never be instantiated, so this code
00159         // simply won't do anything. Not as if dead code is *good*,
00160         // but hey.
00161         ////////////////////////////////////////////////////////////////////////
00162             
00163         ////////////////////////////////////////////////////////////////////////
00164         // give s11n de/serialize implementations for S11N_TYPE:
00165         ////////////////////////////////////////////////////////////////////////
00166     template <> struct s11n_api_marshaler< S11N_TYPE >
00167         {
00168                 typedef S11N_TYPE serializable_type;
00169                 template <typename NodeType>
00170                 static bool serialize( NodeType &dest, const serializable_type & src )
00171                 {
00172                         dest.impl_class( ::classname< S11N_TYPE >() ); // only good for monomorphs
00173                         //dest.impl_class( ::clname::classname( &src ) );
00174                         return src.S11N_SERIALIZE_FUNCTION( dest );
00175                 }
00176 
00177                 template <typename NodeType>
00178                 static bool deserialize( const NodeType & src, serializable_type & dest ) 
00179                 {
00180                         return dest.S11N_DESERIALIZE_FUNCTION( src );
00181                 }
00182 
00183         }; // struct s11n_api_marshaler< S11N_TYPE >
00184 
00185 } // anon namespace 
00186 
00187 ////////////////////////////////////////////////////////////////////////////////
00188 // end proxy code for [S11N_TYPE]
00189 ////////////////////////////////////////////////////////////////////////////////
00190 #undef S11N_TYPE
00191 #undef S11N_BASE_TYPE
00192 #undef S11N_NAME
00193 #undef S11N_SERIALIZE_FUNCTION
00194 #undef S11N_DESERIALIZE_FUNCTION
00195 #undef DEBUG_REG
00196 

Generated on Tue Oct 26 18:25:59 2004 for s11n by  doxygen 1.3.9.1