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