00001 #ifndef s11n_S11N_TRAITS_HPP_INCLUDED 00002 #define s11n_S11N_TRAITS_HPP_INCLUDED 1 00003 00004 00005 #include <vector> 00006 #include <map> 00007 00008 #include <s11n.net/s11n/classload.hpp> // default classloader/factory implementation. 00009 #include <s11n.net/s11n/export.hpp> // S11N_EXPORT_API 00010 #include <s11n.net/s11n/type_traits.hpp> 00011 00012 namespace s11n { 00013 00014 /** 00015 node_traits encapsulates information relevant to Data 00016 Nodes, much in the same way that std::char_traits 00017 encapsulates character type information. 00018 00019 The default implementation works with 00020 s11n::s11n_node or API-compatible 00021 types. Specializations may be defined to work with 00022 other node types. 00023 00024 By using node_traits, instead of directly accessing a 00025 Node's API, client code may remain blissfully ignorant of 00026 the underlying node type. 00027 00028 All API docs for this class which do not explicitely say 00029 "this implementation" (or similar) apply to all 00030 specializations of this type. They act as the "requirements 00031 document" for implementors of specializations. 00032 00033 Changes from 1.0.x to 1.1.x: 00034 00035 - Removed begin() and end(), because they are just as 00036 easily accessed via children().begin/end(), and it was not 00037 easy to remember if they returned iterators to the children 00038 or the properties. 00039 00040 - Removed iterator typedefs, as they are (almost) as easily 00041 accessed via the appropriate container's typedefs. Again, this 00042 was to avoid confusion between the properties and children 00043 iterator types. 00044 */ 00045 template <typename NodeT> 00046 struct S11N_EXPORT_API node_traits 00047 { 00048 public: 00049 /** 00050 The same as NodeT. 00051 */ 00052 typedef NodeT node_type; 00053 00054 /** 00055 The type uses to store properties for node_type 00056 objects. 00057 */ 00058 typedef typename node_type::map_type property_map_type; 00059 00060 00061 /** 00062 The type used to store children of node_type 00063 objects. 00064 */ 00065 typedef typename node_type::child_list_type child_list_type; 00066 00067 00068 00069 00070 /** 00071 Returns a new node_type. The caller owns the 00072 returned pointer. 00073 00074 It is illegal for this function to return 0. If it 00075 cannot create a node for some reason, it must throw 00076 an exception. 00077 */ 00078 static node_type * create() 00079 { 00080 return new node_type; 00081 } 00082 00083 /** 00084 Returns a new node_type with the given name. The 00085 caller owns the returned pointer. 00086 00087 See create() for the no-null-return rule. 00088 */ 00089 static node_type * create( const std::string & nodename ) 00090 { 00091 node_type * n = create(); 00092 name( *n, nodename ); 00093 return n; 00094 } 00095 00096 00097 /** 00098 Sets the property key to the given value in 00099 the given node. 00100 00101 ValueT must support complementary ostream<< and 00102 istream>> operators. 00103 */ 00104 template <typename ValueT> 00105 static void set( node_type & node, 00106 const std::string & key, 00107 const ValueT & value ) 00108 { 00109 node.set( key, value ); 00110 } 00111 00112 /** 00113 Unsets (removes) the given property from node. It 00114 is not an error to unset an non-existing key. 00115 */ 00116 static void unset( node_type & node, 00117 const std::string & key ) 00118 { 00119 node.unset( key ); 00120 } 00121 00122 /** 00123 Returns true if node contains a property 00124 named key, else returns false. 00125 */ 00126 static bool is_set( const node_type & node, 00127 const std::string & key ) 00128 { 00129 return node.is_set( key ); 00130 } 00131 00132 00133 /** 00134 Returns an immutable reference to the node's map of properties. 00135 */ 00136 static const property_map_type & properties( const node_type & node ) 00137 { 00138 return node.properties(); 00139 } 00140 00141 /** 00142 Returns a mutable reference to the node's map of properties. 00143 */ 00144 static property_map_type & properties( node_type & node ) 00145 { 00146 return node.properties(); 00147 } 00148 00149 /** 00150 Returns the value of the property with the given 00151 key, or default_value if that property does not 00152 exist or cannot be lexically cast to type ValueT. 00153 00154 ValueT must support complementary ostream<< and 00155 istream>> operators. 00156 */ 00157 template <typename ValueT> 00158 static ValueT 00159 get( const node_type & node, 00160 const std::string & key, 00161 const ValueT & default_value ) 00162 { 00163 return node.template get<ValueT>( key, default_value ); 00164 } 00165 00166 /** 00167 Returns a mutable list of children 00168 belonging to node. 00169 */ 00170 static child_list_type & children( node_type & node ) 00171 { 00172 return node.children(); 00173 } 00174 00175 /** 00176 Returns an immutable list of children 00177 belonging to node. 00178 */ 00179 static const child_list_type & children( const node_type & node ) 00180 { 00181 return node.children(); 00182 } 00183 00184 /** 00185 Sets the class name of the type for which node 00186 holds serialized data. 00187 */ 00188 static void class_name( node_type & node, const std::string & classname ) 00189 { 00190 node.class_name( classname ); 00191 } 00192 00193 00194 /** 00195 Returns the class name of the type for which node 00196 holds serialized data. 00197 */ 00198 static std::string class_name( const node_type & node ) 00199 { 00200 return node.class_name(); 00201 } 00202 00203 /** 00204 Sets node's name. See the s11n lib manual for what 00205 conventions to follow. In short: the "variable name" 00206 rules from most programming languages are a good 00207 guideline. 00208 */ 00209 static void name( node_type & node, const std::string & name ) 00210 { 00211 node.name( name ); 00212 } 00213 00214 00215 /** 00216 Returns node's name. 00217 */ 00218 static std::string name( const node_type & node ) 00219 { 00220 return node.name(); 00221 } 00222 00223 /** 00224 Removes all children and properties from node, 00225 freeing up their resources. Whether the node's 00226 name() and class_name() are cleared is 00227 implementation-defined. In practice, those are 00228 overwritten by algos as needed, so it has not been 00229 a concern. 00230 */ 00231 static void clear( node_type & node ) 00232 { 00233 node.clear(); 00234 } 00235 00236 /** 00237 Returns true if this object has no properties 00238 and no children. The name() and class_name() 00239 are *not* considered. 00240 00241 Added in version 1.1.3. 00242 */ 00243 static bool empty( const node_type & node ) 00244 { 00245 return node.empty(); 00246 } 00247 00248 /** 00249 Swaps all publically-visible internal state of lhs 00250 with that of rhs. This includes: 00251 00252 - class_name() 00253 00254 - name() 00255 00256 - children() 00257 00258 - properties() 00259 00260 Added in version 1.1.3. 00261 */ 00262 static void swap( node_type & lhs, node_type & rhs ) 00263 { 00264 return lhs.swap( rhs ); 00265 } 00266 00267 }; // end node_traits<> 00268 00269 00270 // /** 00271 // An unfortunate necessity. 00272 // */ 00273 // template <typename NodeT> 00274 // struct S11N_EXPORT_API node_traits<NodeT const> : node_traits<NodeT> {}; 00275 00276 00277 /** 00278 A default serialization proxy, which simply 00279 forwards de/serialize calls to an interface 00280 implemented as two overloaded member functions 00281 SerializableType::operator()( NodeT ). 00282 */ 00283 struct S11N_EXPORT_API default_serialize_functor 00284 { 00285 /** 00286 Serialize src to dest using src.operator()( dest ). 00287 00288 The serialize operator must look like: 00289 00290 bool operator()( NodeT & ) const; 00291 00292 It may be virtual or a function template. 00293 */ 00294 template <typename NodeT, typename SerializableType> 00295 bool operator()( NodeT & dest, const SerializableType & src ) const 00296 { 00297 return src.operator()( dest ); 00298 } 00299 00300 /** 00301 Deserialize dest from src using dest.operator()( src ). 00302 00303 The deserialize operator must look like: 00304 00305 bool operator()( const NodeT & ); 00306 00307 It may be virtual or a function template. 00308 */ 00309 template <typename NodeT, typename DeserializableType> 00310 bool operator()( const NodeT & src, DeserializableType & dest ) const 00311 { 00312 return dest.operator()( src ); 00313 } 00314 }; 00315 00316 00317 /** 00318 A default implementation for 00319 s11n_traits::cleanup_functor. Compatible implementations 00320 and specializations must follow the conventions defined for 00321 this class. 00322 00323 This implementation is only suitable for cleaning up types 00324 which manage any child pointers which are assigned to them 00325 during deserialization. For example, std:: containers do 00326 not own their pointers, and therefor require a 00327 specialization of this type to clean them up. 00328 00329 SerializableType must be a Serializable and may be 00330 pointer-qualified. 00331 00332 The library manual goes into more detail about what this 00333 type is for. 00334 00335 The operations of this class are declared as throw() because 00336 of their logical role in the destruction process, and destructors 00337 are not generally allowed to throw. 00338 */ 00339 template <typename SerializableType> 00340 struct default_cleanup_functor 00341 { 00342 typedef typename type_traits<SerializableType>::type serializable_type; 00343 00344 /** 00345 Default implementation does nothing, though we 00346 should arguably assign to a default-constructed 00347 object. 00348 00349 Specializations must do any cleanup they need to 00350 here. For example, container specializations must 00351 a) deallocate any heap-based entries and b) empty 00352 the list. Specializations are free to do a 00353 default-assign, as mentioned above, but are not 00354 required to. Specializations for containers must 00355 recursively use s11n_trait::cleanup_functor for 00356 the contained types, to ensure that they can properly 00357 clean up containers holding other containers. 00358 */ 00359 void operator()( serializable_type & ) const throw() 00360 { 00361 } 00362 00363 }; 00364 00365 /** 00366 s11n_traits encapsulates information about what 00367 type(s) are responsible for handling de/serialize 00368 operations for a given type, plus the factory for 00369 that type. It should be specialized to define 00370 various aspects of serialization for a given type. 00371 00372 The interface shown here is the bare minimum which 00373 s11n_traits specializations must implement. 00374 Specializations may optionally add to the 00375 interface, but client code is discouraged from 00376 relying on any extensions. 00377 00378 This type is stateless, and specializations are 00379 expected to be stateless (at least, they will 00380 be treated as if they are). 00381 00382 Client code is not expected to need to use this 00383 type directly, except for purposes of plugging in 00384 their types into the s11n framework. More 00385 specifically, it is not expected that Serializables 00386 will use this type. 00387 00388 Parameterized on: 00389 00390 SerializableT: the base-most Serializable 00391 type. This is the base-most point of reference for 00392 classloading and "template typing". Subclasses of 00393 SerializableT are assumed to be handleable via the 00394 same de/serialize interface as SerializableT. 00395 00396 InterfaceType is the base Serializable interface which 00397 SerializableT is assumed to subclass. The default is 00398 SerializableT. This type is required for cases where 00399 SerializableT wants to register with multiple Serializable 00400 interfaces. 00401 00402 Changes from 1.0.x to 1.1.x: 00403 00404 - Added class_name() member to replace the ::classname() 00405 family of code in 1.1.0. 00406 00407 - cleanup_functor added in 1.1.3. 00408 00409 - InterfaceType added in 1.2.7/1.3.1. 00410 00411 */ 00412 00413 template <typename SerializableT, typename InterfaceType = SerializableT> 00414 struct S11N_EXPORT_API s11n_traits 00415 { 00416 /** 00417 The s11n framework instantiates an s11n_traits 00418 object at some points to allow the traits object 00419 to do things like factory registration. 00420 */ 00421 s11n_traits(){} 00422 ~s11n_traits(){} 00423 00424 /** 00425 The InterfaceType. Added in 1.3.1. This is needed 00426 for cases where a Serializable wants to be registered 00427 with several Serializable interfaces. If we don't 00428 have this key then ODR violations happen on the second 00429 and subsequent registration. 00430 */ 00431 typedef InterfaceType serializable_interface_type; 00432 00433 /** 00434 The type of object we want to [de]serialize. 00435 */ 00436 typedef SerializableT serializable_type; 00437 00438 /** 00439 Type which will be used to instantiate new objects 00440 of serializable_type. It must implement: 00441 00442 serializable_type * operator()( const std::string & classname ) const; 00443 00444 It is expected to return, polymorphically if 00445 possible, a new serializable_type on success or 0 00446 on failure. 00447 00448 The default factory_type works with types 00449 registered via the s11n::cl::classload() 00450 family of functions. 00451 */ 00452 typedef ::s11n::cl::object_factory<serializable_interface_type> factory_type; 00453 00454 /** 00455 Functor type implementing serialize code. 00456 00457 Must implement: 00458 00459 bool operator()( SomeNodeType & dest, const base_type & src ) const; 00460 00461 */ 00462 typedef ::s11n::default_serialize_functor serialize_functor; 00463 00464 /** 00465 Functor type implementing deserialize code. 00466 00467 Must implement: 00468 00469 bool operator()( const SomeNodeType & src, base_type & dest ) const; 00470 */ 00471 typedef ::s11n::default_serialize_functor deserialize_functor; 00472 00473 /** 00474 This type is used to clean up a partial deserialized object 00475 on error. If this functor, and all specializations it calls, 00476 do their part, we can make much better exception guarantees, 00477 theoretically avoiding any leaks due to exceptions thrown 00478 during deserialization. 00479 00480 cleanup_functor must follow the conventions laid out by 00481 s11n::default_cleanup_functor<serializable_type>. 00482 */ 00483 typedef ::s11n::default_cleanup_functor<serializable_type> cleanup_functor; 00484 00485 /** 00486 As of s11n 1.1, specializations must define the 00487 class_name() function. This implementation returns 00488 a useless, unspecified class name. Specializations 00489 must return the class name of serializable_type, 00490 preferably polymorphically (polymorphic naming is 00491 unfortunately not possible without some client-side 00492 help). 00493 00494 instance_hint is a HINT to this class as to the 00495 actual instance we want the name for, and may be 00496 0. It is provided so that class hierarchies which 00497 have virtual functions like className() can make 00498 those available to the core library via s11n_traits 00499 specializations. 00500 00501 Specializations MUST accept 0 as a valid 00502 instance_hint value are are NEVER REQUIRED to pay 00503 any attention to instance_hint. The default 00504 implementation does nothing with it. 00505 00506 Design notes: 00507 00508 - It really should take a default value of 0 for 00509 instance_hint, but the idea of relying on a default 00510 value, considering things like how template 00511 specializations should define them and subclassing 00512 (though that is not an issue *here*), gives me the 00513 willies. Too much room for error there. 00514 00515 - Also, we could probably argue that it should 00516 return a const string. 00517 00518 - We could argue that it should return an empty string 00519 instead of a useless one. i don't want to to generate 00520 output which might break parsers, though. 00521 00522 */ 00523 static const std::string class_name( const serializable_type * /* instance_hint */ ) 00524 { 00525 return "unknown"; 00526 } 00527 00528 }; // end s11n_traits<> 00529 00530 // template <typename SerializableT> 00531 // struct S11N_EXPORT_API s11n_traits<SerializableT> : s11n_traits<SerializableT,SerializableT> 00532 // {}; 00533 00534 00535 /** 00536 A general specialization to treat (T*) as (T) for s11n_traits 00537 purposes. This is necessary for some template argument resolution 00538 to work as desired. 00539 00540 Added in 1.1.3. 00541 */ 00542 template <typename T> 00543 struct S11N_EXPORT_API s11n_traits<T *> : public s11n_traits<T> {}; 00544 00545 00546 } // namespace s11n 00547 00548 00549 #endif // s11n_S11N_TRAITS_HPP_INCLUDED