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

reg_map_serializable.h

00001 ////////////////////////////////////////////////////////////////////////
00002 // supermacro for registering std::maps.
00003 // It's functionally identical to using reg_proxy.h except that it 
00004 // adds a proxy for the map's value_type, which is necessary for
00005 // some deserialization operations.
00006 ////////////////////////////////////////////////////////////////////////
00007 // Usage:
00008 // Exactly as for reg_proxy.h, except leave of the
00009 // S11N_[DE]SERIALIZER_FUNCTOR assignment.
00010 //
00011 // Note: this cannot be implemented in terms of simply including
00012 // the reg_proxy.h calls for a map and a pair because of the way
00013 // the supermacro arguments are unset during each call, which means
00014 // we cannot expand the map's S11N_TYPE to S11N_TYPE::value_type.
00015 // Thus, we do this the hard way and implement a whole SAM by hand.
00016 // At least it's only once for all map types. :/
00017 ////////////////////////////////////////////////////////////////////////
00018 
00019 #ifndef S11N_TYPE
00020 #    error "S11N_TYPE is not set. Set it to the type you want to proxy before including this file!"
00021 #endif
00022 
00023 #ifndef S11N_NAME
00024 #    error "S11N_NAME must be set to the string form of S11N_TYPE"
00025 #endif
00026 
00027 #include <s11n/map.h> // map-related s11n funcs
00028 
00029 ////////////////////////////////////////////////////////////////////////
00030 // internal macros:
00031 #define S11N_SERIALIZE_FUNCTOR s11n::map::map_serializer_proxy
00032 #define S11N_VALUE_TYPE_SERIALIZE_FUNCTOR s11n::map::pair_serializer_proxy
00033 #define S11N_VALUE_TYPE S11N_TYPE::value_type
00034 #define S11N_VALUE_TYPE_NAME "pair"
00035 
00036 ////////////////////////////////////////////////////////////////////////
00037 // set up the type name registry
00038 #define NAME_TYPE S11N_TYPE
00039 #define TYPE_NAME S11N_NAME
00040 #include <s11n/name_type.h>
00041 #define NAME_TYPE S11N_VALUE_TYPE
00042 #define TYPE_NAME S11N_VALUE_TYPE_NAME
00043 #include <s11n/name_type.h>
00044 ////////////////////////////////////////////////////////////////////////
00045 
00046 
00047 namespace { // anonymous namespace is important for complex linking reasons.
00048 
00049 
00050 #ifndef s11n_MAP_REG_CONTEXT_DEFINED
00051 #define s11n_MAP_REG_CONTEXT_DEFINED 1
00052 #include <s11n/debuggering_macros.h> // CERR
00053 #include <iostream> // cerr
00054         ///////////////////////////////////////////////////////////////
00055         // we must not include this more than once per compilation unit
00056         ///////////////////////////////////////////////////////////////
00057         // A unique (per Context/per compilation unit) space to assign
00058         // a bogus value for classloader registration purposes (see
00059         // the classloader docs for a full description of how this
00060         // works).
00061         template <typename Context>
00062         struct map_reg_context
00063         {
00064                 typedef Context context;
00065                 static bool placeholder;
00066                 static void reg()
00067                 {
00068                         CERR << "Warning: this type is unspecialized, which mean no registration "
00069                              << "has been made for the context type ["<<::classname< context >() << "]\n"
00070                              << "This type is:\n"<<::classname<map_reg_context<context> >() << "\n";
00071                         
00072                 }
00073         };
00074         template <typename Context> bool map_reg_context<Context>::placeholder = false;
00075 #endif
00076 // !s11n_MAP_REG_CONTEXT_DEFINED
00077 ////////////////////////////////////////////////////////////////////////////////
00078 
00079             
00080 
00081 
00082         ////////////////////////////////////////////////////////////////////////
00083         // Register a factory with the classloader (this could be done any
00084     // number of ways, actually):
00085         template <>
00086         struct map_reg_context< S11N_TYPE >
00087         {
00088                 static bool placeholder;
00089                 static void reg()
00090                 {
00091                         s11n::classloader_register<
00092                                 S11N_TYPE,
00093                                 S11N_TYPE
00094                                 >( ::classname< S11N_TYPE >() );
00095 
00096                         s11n::classloader_register<
00097                                 S11N_VALUE_TYPE,
00098                                 S11N_VALUE_TYPE
00099                                 >( ::classname< S11N_VALUE_TYPE >() );
00100 
00101                 }
00102         };
00103 
00104     bool map_reg_context< S11N_TYPE >::placeholder= (map_reg_context< S11N_TYPE >::reg(),true);
00105 
00106         ////////////////////////////////////////////////////////////////////////
00107         // give s11n de/serialize implementations for S11N_TYPE:
00108     template <> struct s11n_api_marshaler< S11N_TYPE >
00109         {
00110                 typedef S11N_TYPE serializable_type;
00111                 typedef S11N_SERIALIZE_FUNCTOR serialize_proxy_type;
00112                 typedef serialize_proxy_type deserialize_proxy_type;
00113                 template <typename NodeType>
00114                 static bool serialize( NodeType &dest, const serializable_type & src )
00115                 {
00116                         dest.impl_class( ::classname< S11N_TYPE >() );
00117                         //dest.impl_class( ::clname::classname( &src ) );
00118                         return serialize_proxy_type()( dest, src );
00119                 }
00120 
00121                 template <typename NodeType>
00122                 static bool deserialize( const NodeType & src, serializable_type & dest ) 
00123                 {
00124                         return deserialize_proxy_type()( src, dest );
00125                 }
00126         }; // struct s11n_api_marshaler< S11N_TYPE >
00127 
00128         ////////////////////////////////////////////////////////////
00129         // proxy the map's value_type
00130     template <> struct s11n_api_marshaler< S11N_VALUE_TYPE >
00131         {
00132                 typedef S11N_VALUE_TYPE serializable_type;
00133                 typedef S11N_VALUE_TYPE_SERIALIZE_FUNCTOR serialize_proxy_type;
00134                 typedef serialize_proxy_type deserialize_proxy_type;
00135                 template <typename NodeType>
00136                 static bool serialize( NodeType &dest, const serializable_type & src )
00137                 {
00138                         dest.impl_class( ::classname< S11N_VALUE_TYPE >() );
00139                         return serialize_proxy_type()( dest, src );
00140                 }
00141 
00142                 template <typename NodeType>
00143                 static bool deserialize( const NodeType & src, serializable_type & dest ) 
00144                 {
00145                         return deserialize_proxy_type()( src, dest );
00146                 }
00147         }; // struct s11n_api_marshaler< S11N_VALUE_TYPE >
00148 
00149 } // anon namespace 
00150 
00151 ////////////////////////////////////////////////////////////////////////////////
00152 // end proxy code for [S11N_TYPE]
00153 ////////////////////////////////////////////////////////////////////////////////
00154 
00155 #undef S11N_TYPE
00156 #undef S11N_NAME
00157 #undef S11N_SERIALIZE_FUNCTOR
00158 #undef S11N_VALUE_TYPE
00159 #undef S11N_VALUE_TYPE_NAME
00160 #undef S11N_VALUE_TYPE_SERIALIZE_FUNCTOR

Generated on Thu Jun 16 16:18:12 2005 for s11n by  doxygen 1.4.3-20050530