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 Jul 20 10:46:48 2004 for s11n by doxygen 1.3.7