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

reg_proxy.h

00001 ////////////////////////////////////////////////////////////////////////
00002 // Boilerplate code for proxying arbitrary types via arbitrary
00003 // proxy functors.
00004 // It is compatible with ALL types which can be proxied via an
00005 // existing functor.
00006 // License: Public Domain
00007 // Author: stephan@s11n.net
00008 ////////////////////////////////////////////////////////////////////////
00009 
00010 ////////////////////////////////////////////////////////////////////////
00011 // NOTE: this file does not use a conventional BLAH_H_INCLUDED guard.
00012 // Yes, that's on purpose.
00013 ////////////////////////////////////////////////////////////////////////
00014 // Boilerplate code for a
00015 // proxies.
00016 //
00017 //
00018 // The s11n header files are expected to have been included by the
00019 // time this file is ever included.
00020 //
00021 //
00022 // Sample usage:
00023 //
00024 // #define S11N_TYPE std::map<Foo,Bar>
00025 // #define S11N_NAME "std::map<Foo,Bar>"
00026 // #include [this file]
00027 //
00028 // // repeat for each type:
00029 // #define S11N_TYPE std::map<Foo *,Bar *>
00030 // #define S11N_NAME "std::map<Foo*,Bar*>"
00031 // #define S11N_SERIALIZE_FUNCTOR some_functor_name
00032 // #include [this file]
00033 //
00034 // If S11N_TYPE is a subtype of another Serializable,
00035 // and should be available via that base-type's classloader
00036 // (Yes, you normally WANT this) then define this macro:
00037 //
00038 //   S11N_BASE_TYPE
00039 //
00040 // to the type name of S11N_TYPE's BaseType base type.
00041 //
00042 // Not setting S11N_BASE_TYPE is functionaly identical
00043 // to setting it to S11N_TYPE.
00044 //
00045 // Optionally, also define one or both of:
00046 // #define S11N_SERIALIZE_FUNCTOR some_serializer_functor
00047 // #define S11N_DESERIALIZE_FUNCTOR some_deserializer_functor
00048 //
00049 // If S11N_DESERIALIZE_FUNCTOR is defined, that is used
00050 // as the Deserialization proxy, otherwise the first
00051 // functor is used for both cases.
00052 //
00053 // If neither are set then no functor proxy is installed - the type is
00054 // on it's own!
00055 //
00056 // After each include all of these macros are unset so that they may
00057 // be immediately re-used for another registration.
00058 ////////////////////////////////////////////////////////////////////////
00059 ////////////////////////////////////////////////////////////////////////
00060 // General notes:
00061 //
00062 // By s11n convention S11N_NAME should contain no spaces, even for
00063 // template types. Thus, please use:
00064 //
00065 //    "std::list<std::list<foo*>>"
00066 //
00067 // instead of:
00068 //
00069 //     "std::list<std::<list<foo *> >"
00070 //
00071 // C++ needs a space between "> >", but s11n does not.
00072 // That said, s11n DOESN'T CARE what class names you use, as long
00073 // as you're consistent.
00074 //
00075 ////////////////////////////////////////////////////////////////////////
00076 
00077 
00078 #ifndef S11N_TYPE
00079 #    error "S11N_TYPE is not set. Set it to the type you want to proxy before including this file!"
00080 #endif
00081 
00082 #ifndef S11N_NAME
00083 #    error "S11N_NAME must be set to the string form of S11N_TYPE"
00084 #endif
00085 
00086 #ifndef S11N_BASE_TYPE
00087 #    define S11N_BASE_TYPE S11N_TYPE
00088 #endif
00089 
00090 #ifndef S11N_SERIALIZE_FUNCTOR
00091 #    error "S11N_SERIALIZE_FUNCTOR must be set to the name of a functor which will handle requests on behalf of S11N_TYPE."
00092 #endif
00093 
00094 
00095 #ifndef S11N_DESERIALIZE_FUNCTOR
00096 #  define S11N_DESERIALIZE_FUNCTOR S11N_SERIALIZE_FUNCTOR
00097 #endif
00098 
00099 ////////////////////////////////////////////////////////////////////////
00100 // set up the type name registry
00101 #define NAME_TYPE S11N_TYPE
00102 #define TYPE_NAME S11N_NAME
00103 #include <s11n/name_type.h>
00104 ////////////////////////////////////////////////////////////////////////
00105 
00106 namespace { // anonymous namespace is important for complex linking reasons.
00107 
00108 
00109 #ifndef s11n_PROXY_REG_CONTEXT_DEFINED
00110 #define s11n_PROXY_REG_CONTEXT_DEFINED 1
00111         ///////////////////////////////////////////////////////////////
00112         // we must not include this more than once per compilation unit
00113         ///////////////////////////////////////////////////////////////
00114         // A unique (per Context/per compilation unit) space to assign
00115         // a bogus value for classloader registration purposes (see
00116         // the classloader docs for a full description of how this
00117         // works).
00118         template <typename Context>
00119         struct proxy_reg_context
00120         {
00121                 static bool placeholder;
00122         };
00123         template <typename Context> bool proxy_reg_context<Context>::placeholder = false;
00124 #endif
00125 // !s11n_PROXY_REG_CONTEXT_DEFINED
00126 ////////////////////////////////////////////////////////////////////////////////
00127 
00128             
00129 
00130 
00131         ////////////////////////////////////////////////////////////////////////
00132         // Register a factory with the classloader (this could be done any
00133     // number of ways, actually):
00134     bool proxy_reg_context< S11N_TYPE >::placeholder=
00135             (s11n::classloader_register<
00136                  S11N_BASE_TYPE ,
00137                  S11N_TYPE
00138                  >( ::classname< S11N_TYPE >() )
00139                  ,true);
00140 
00141 #ifdef S11N_SERIALIZE_FUNCTOR
00142         ////////////////////////////////////////////////////////////////////////
00143         // give s11n de/serialize implementations for S11N_TYPE:
00144     template <> struct s11n_api_marshaler< S11N_TYPE >
00145         {
00146                 typedef S11N_TYPE serializable_type;
00147                 typedef S11N_SERIALIZE_FUNCTOR serialize_proxy_type;
00148                 typedef S11N_DESERIALIZE_FUNCTOR deserialize_proxy_type;
00149                 template <typename NodeType>
00150                 static bool serialize( NodeType &dest, const serializable_type & src )
00151                 {
00152                         dest.impl_class( ::classname< S11N_TYPE >() );
00153                         //dest.impl_class( ::clname::classname( &src ) );
00154                         return serialize_proxy_type()( dest, src );
00155                 }
00156 
00157                 template <typename NodeType>
00158                 static bool deserialize( const NodeType & src, serializable_type & dest ) 
00159                 {
00160                         return deserialize_proxy_type()( src, dest );
00161                 }
00162 
00163         }; // struct s11n_api_marshaler< S11N_TYPE >
00164 
00165 
00166 #endif // S11N_SERIALIZE_FUNCTOR
00167 } // anon namespace 
00168 
00169 ////////////////////////////////////////////////////////////////////////////////
00170 // end proxy code for [S11N_TYPE]
00171 ////////////////////////////////////////////////////////////////////////////////
00172 
00173 #undef S11N_TYPE
00174 #undef S11N_NAME
00175 
00176 #ifdef S11N_BASE_TYPE
00177 #  undef S11N_BASE_TYPE
00178 #endif
00179 
00180 #ifdef S11N_SERIALIZE_FUNCTOR
00181 #    undef S11N_SERIALIZE_FUNCTOR
00182 #endif
00183 
00184 #ifdef S11N_DESERIALIZE_FUNCTOR
00185 #    undef S11N_DESERIALIZE_FUNCTOR
00186 #endif
00187 

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