00001 #ifndef s11n_net_s11n_v1_1_MAP_HPP_INCLUDED 00002 #define s11n_net_s11n_v1_1_MAP_HPP_INCLUDED 1 00003 //////////////////////////////////////////////////////////////////////// 00004 // Declarations for s11n algos for dealing with std::map and std::pair 00005 // types, or compatible. 00006 //////////////////////////////////////////////////////////////////////// 00007 00008 #include <map> 00009 #include <list> 00010 #include <utility> // pair 00011 00012 #include <iterator> // insert_iterator 00013 #include <algorithm> // for_each() 00014 00015 namespace s11n { 00016 00017 00018 00019 /** 00020 The s11n::map namespace defines functors and algorithms for 00021 working with std::map, std::pair, and 00022 conventions-compatible containers. 00023 */ 00024 namespace map { 00025 00026 00027 00028 /** 00029 00030 serialize_streamable_map() is intended for use as a 00031 serialization proxy for the s11n framework. It 00032 de/serializes objects of type <tt>std::map<X,Y></tt> 00033 into a destination node. 00034 00035 NodeType must be node_traits<NodeType>-compliant. 00036 00037 MapType must conform to std::map conventions and 00038 it's key_type and mapped_type must both be Value Types 00039 which are i/ostreamable (this includes all PODs and 00040 std::string). Pointers as keys or values are not 00041 supported by this functor. 00042 00043 Unlike serialize_map(), this function cannot work on 00044 std::multimaps because it uses NodeType's properties 00045 to hold key/value pairs. The NodeType conventions 00046 specify unique keys for properties, making them 00047 incompatible for generic use with multimap containers 00048 and this algorithm. serialize_map() stores each stored 00049 item as its own object, where duplicate names are 00050 allowed, so it is not affected by this limitation. 00051 00052 Always returns true. 00053 00054 ACHTUNG: return type changed in 0.9.12. 00055 */ 00056 00057 template <typename NodeType, typename MapType> 00058 bool serialize_streamable_map( NodeType & dest, const MapType & src ); 00059 00060 /** 00061 Exactly like serialize_streamable_map(dest,src) except that a subnode, 00062 named subnodename, of dest is created to store the data. 00063 00064 ACHTUNG: return type changed in 0.9.12. 00065 00066 As of version 1.1.3, this function guarantees that dest 00067 is not modified if the serialization fails. 00068 */ 00069 template <typename NodeType, typename MapType> 00070 bool serialize_streamable_map( NodeType & dest, const std::string & subnodename, const MapType & src ); 00071 00072 struct serialize_streamable_map_f : ::s11n::serialize_binary_f_tag, ::s11n::deserialize_binary_f_tag 00073 { 00074 template <typename NodeType, typename MapType> 00075 bool operator()( NodeType & dest, const MapType & src ) const 00076 { 00077 return serialize_streamable_map<NodeType,MapType>( dest, src ); 00078 } 00079 template <typename NodeType, typename MapType> 00080 bool operator()( NodeType & dest, const std::string & subnodename, const MapType & src ) const 00081 { 00082 return serialize_streamable_map<NodeType,MapType>( dest, subnodename, src ); 00083 } 00084 }; 00085 /** 00086 This is the converse of serialize_streamable_map(). It tries to 00087 read in all properties stored in src and stick them into 00088 dest. 00089 00090 NodeType must support begin() and end() and they must 00091 return iterators to pair<X,Y>, where X and Y must 00092 meet the same requirements as the key and value types for 00093 MapType in serialize_streamable_map(). MapType must support: 00094 00095 void insert( MapType::value_type ); 00096 00097 (Duh.) 00098 00099 Always returns true, because the nature of 00100 stream-based conversion makes it quite difficult to 00101 generically know if there is an error. In practice, 00102 such operations essentially always succeed, at 00103 least for POD-like types. 00104 00105 ACHTUNG: return type changed in 0.9.12. 00106 00107 */ 00108 template <typename NodeType, typename MapType> 00109 bool deserialize_streamable_map( const NodeType & src, MapType & dest ); 00110 00111 00112 /** 00113 Exactly like deserialize_streamable_map(dest,src) except 00114 that a subnode of dest, named subnodename, is sought to 00115 pull the data from. 00116 */ 00117 template <typename NodeType, typename MapType> 00118 bool deserialize_streamable_map( const NodeType & src, const std::string & subnodename, MapType & dest ); 00119 00120 struct deserialize_streamable_map_f : ::s11n::serialize_binary_f_tag, ::s11n::deserialize_binary_f_tag 00121 { 00122 template <typename NodeType, typename MapType> 00123 bool operator()( const NodeType & src, MapType & dest ) const 00124 { 00125 return deserialize_streamable_map<NodeType,MapType>( src, dest ); 00126 } 00127 template <typename NodeType, typename MapType> 00128 bool operator()( const NodeType & src, const std::string & subnodename, MapType & dest ) const 00129 { 00130 return deserialize_streamable_map<NodeType,MapType>( src, subnodename, dest ); 00131 } 00132 }; 00133 00134 /** 00135 Serializes a std::pair-compatible type into a "custom" 00136 format, suitable for saving pairs in standard XML 00137 (de/serialize_streamable_map() can't do this when keys are 00138 not valid XML keys, e.g., numeric). Use 00139 deserialize_streamable_pair() to decode the data. 00140 00141 The destination node gets these two properties: 00142 00143 - first = src.first 00144 00145 - second = src.second 00146 00147 PairType must comply with: 00148 00149 - first/second types must be i/o streamable (i.e., 00150 convertable to strings). 00151 00152 Returns true on success... and never fails. Honestly. It'll 00153 fail at compile-time if it's going to fail. 00154 00155 use deserialize_streamable_pair() to convert them back to pairs, 00156 or fish out the "first" and "second" properties manually. 00157 */ 00158 template <typename NodeType, typename PairType> 00159 bool serialize_streamable_pair( NodeType & dest, const PairType & src ); 00160 00161 /** 00162 A functor equivalent of serialize_streamable_pair(). 00163 00164 Added in version 1.1.3. 00165 */ 00166 struct serialize_streamable_pair_f : ::s11n::serialize_binary_f_tag 00167 { 00168 template <typename NodeType, typename PairType> 00169 inline bool operator()( NodeType & dest, const PairType & src ) const 00170 { 00171 return serialize_streamable_pair<NodeType,PairType>( dest, src ); 00172 } 00173 }; 00174 00175 /** 00176 The quasi-counterpart of serialize_streamable_pair(). It's 00177 non-conventional args and return type are a result of 00178 map::value_type having a const .first element, which 00179 prohibits us assigning to it. See deserialize_pair() for 00180 more info on that. 00181 00182 As of version 1.1.3, this function throws an 00183 s11n_exception if src does not have two properties 00184 named 'first' and 'second'. 00185 */ 00186 template <typename PairType, typename NodeType> 00187 PairType deserialize_streamable_pair( const NodeType & src ); 00188 00189 00190 /** 00191 Overloaded form with conventional argument ordering. 00192 It is NOT suitable for use with PairTypes from map-like containers, 00193 as those have const keys. 00194 00195 This function throws an s11n_exception if src does 00196 not have two properties named 'first' and 'second', 00197 in which case dest is not modified. 00198 00199 Added in 1.1.3. 00200 */ 00201 template <typename NodeType, typename PairType> 00202 bool deserialize_streamable_pair( const NodeType & src, PairType & dest ); 00203 00204 /** 00205 A functor equivalent of deserialize_streamable_pair(). 00206 00207 Added in version 1.1.3. 00208 */ 00209 struct deserialize_streamable_pair_f : ::s11n::serialize_binary_f_tag 00210 { 00211 template <typename NodeType, typename PairType> 00212 inline bool operator()( const NodeType & src, PairType & dest ) const 00213 { 00214 return deserialize_streamable_pair<NodeType,PairType>( src, dest ); 00215 } 00216 }; 00217 00218 /** 00219 Similar to serialize_streamable_map(), but puts 00220 each key/value pair into it's own node, using 00221 serialize_streamable_pair(). The end effect is that 00222 it's output is more verbose, but may be compatible 00223 with more file formats, regardless of the actual 00224 key type. e.g., numeric keys are not supported by 00225 standard XML (though they are by the s11n XML 00226 parsers), and this algorithm structures the data 00227 such that this is not a problem. 00228 00229 Returns the number of pairs stored. 00230 00231 MapType must meet these conditions: 00232 00233 value_type must be a pair containing i/ostreamable types 00234 (e.g. PODs/strings) with no pointer qualifiers. 00235 00236 ACHTUNG: return type changed in 0.9.12. 00237 00238 */ 00239 00240 template <typename NodeType, typename MapType> 00241 bool serialize_streamable_map_pairs( NodeType & dest, const MapType & src ); 00242 00243 /** 00244 A functor equivalent of serialize_streamable_map_pairs(). 00245 00246 Added in version 1.1.3. 00247 */ 00248 struct serialize_streamable_map_pairs_f : ::s11n::serialize_binary_f_tag 00249 { 00250 template <typename NodeType, typename MapType> 00251 inline bool operator()( NodeType & dest, const MapType & src ) const 00252 { 00253 return serialize_streamable_map_pairs<NodeType,MapType>( dest, src ); 00254 } 00255 }; 00256 00257 /** 00258 The load-time counterpart to serialize_streamable_map_pairs(). 00259 00260 ACHTUNG: return type changed in 0.9.12. 00261 00262 If it returns false, a child failed to 00263 deserialize. In this case, dest is not modified 00264 (version 1.1.3+) or in an undefined state (versions 00265 older than 1.1.3). On success, dest.swap() is used 00266 to populate the map, so dest will lose any contents 00267 it had before calling this function. There is one 00268 exception to this: if src contains no content for 00269 this algorithm, true is returned without modifying 00270 dest. In practice, dest is always empty when passed 00271 to this function, so this small difference should 00272 matter little. 00273 00274 An empty src is not an error. 00275 00276 In versions prior to 1.1.3, this function was 00277 documented as returning true on empty content, but 00278 actually (erroneously) returned false. This would show up 00279 when de/serializing empty maps. 00280 00281 */ 00282 template <typename NodeType, typename MapType> 00283 bool deserialize_streamable_map_pairs( const NodeType & src, MapType & dest ); 00284 00285 /** 00286 A functor equivalent of deserialize_streamable_map_pairs(). 00287 00288 Added in version 1.1.3. 00289 */ 00290 struct deserialize_streamable_map_pairs_f : ::s11n::serialize_binary_f_tag 00291 { 00292 template <typename NodeType, typename MapType> 00293 inline bool operator()( const NodeType & src, MapType & dest ) const 00294 { 00295 return deserialize_streamable_map_pairs<NodeType,MapType>( src, dest ); 00296 } 00297 }; 00298 00299 /** 00300 serialize_pair() can serialize any std::pair type which 00301 meets these conditions: 00302 00303 - PairType's first_type and second_type types must both be 00304 Serializables. They may be pointer or value types. 00305 00306 - PairType may not be a pointer type. 00307 00308 If serialization of one child fails, the whole 00309 process fails and neither child is added to the 00310 dest node. The error, possibly an exception, is 00311 propagated back to the caller. 00312 00313 ACHTUNG: never pass the same destination container 00314 more than once or you will get duplicate and/or 00315 incorrect data. 00316 00317 */ 00318 template <typename NodeType, typename PairType> 00319 bool serialize_pair( NodeType & dest, const PairType & src ); 00320 00321 /** 00322 A functor equivalent of serialize_pair(). 00323 00324 Added in version 1.1.3. 00325 */ 00326 struct serialize_pair_f : ::s11n::serialize_binary_f_tag 00327 { 00328 template <typename NodeType, typename PairType> 00329 inline bool operator()( NodeType & dest, const PairType & src ) const 00330 { 00331 return serialize_pair<NodeType,PairType>( dest, src ); 00332 } 00333 }; 00334 00335 /** 00336 The counterpart to serialize_pair(). 00337 00338 Note: std::map<X,Y>::value_type is not the 00339 same as pair<X,Y>, but is pair<const 00340 X,Y>, so you cannot simply iterate over a map 00341 and pass each pair to this function, because this 00342 function cannot assign to the first element of such 00343 a pair. 00344 00345 Exceptions: this function propagates exceptions if 00346 an underlying call to deserialize() throws. If it 00347 throws then dest is not modified. Read on for more 00348 gory detail... 00349 00350 If the assignment operations for 00351 PairType::first_type or PairType::second_type throw 00352 then dest may be modified if this function throws. 00353 00354 Versions prior to 1.1.3 had a destroy-on-error 00355 policy, such that objects this function allocates 00356 were deleted on error. For this to work as 00357 expected, without memory leaks, algorithms which 00358 this function calls must clean up in the face of 00359 exceptions. As it turns out, this is a tricky 00360 situation, because deserialization can allocate 00361 arbitrary objects which might or might not need 00362 special clean-up. For example, deserializing a 00363 pair<int,list<vector<double*>>*> will cause doubles 00364 and lists to be allocated on the heap, and if this function 00365 deletes a list containing the vectors which contain 00366 those doubles, those pointers leak. 00367 00368 Thus... 00369 00370 As of 1.1.3, s11n_traits<PairType>::cleanup_functor 00371 is used to do cleanup when an an error occurs. This 00372 allows us to keep dest unmodified in the face on an 00373 error. For this to work properly, the two 00374 s11n_traits::cleanup_functors for 00375 PairType::first_type and PairType::second_type must 00376 implement proper behaviour. 00377 */ 00378 template <typename NodeType, typename PairType> 00379 bool deserialize_pair( const NodeType & src, PairType & dest ); 00380 00381 /** 00382 A functor equivalent of deserialize_pair(). 00383 00384 Added in version 1.1.3. 00385 */ 00386 struct deserialize_pair_f : ::s11n::deserialize_binary_f_tag 00387 { 00388 template <typename NodeType, typename PairType> 00389 inline bool operator()( const NodeType & src, PairType & dest ) const 00390 { 00391 return deserialize_pair<NodeType,PairType>( src, dest ); 00392 } 00393 }; 00394 00395 00396 /** 00397 Serialize the given map into dest. MapType's pairs must be 00398 Serializable and must contain Serializable types, but their 00399 "pointerness" is irrelevant. 00400 00401 See deserialize_map() for important info. 00402 00403 If serialization of a child fails, the child is not 00404 added to dest and false is returned or any 00405 exception is propagated back to the caller. The 00406 dest list might be in a partially-populated state, 00407 in either case. 00408 00409 If this function throws, dest may be in a 00410 partially-filled state. 00411 00412 ACHTUNG: never pass the same destination container 00413 to this function more than once or you will get 00414 duplicate and/or incorrect data. 00415 00416 As of version 1.1.3, this function throws an s11n_exception 00417 if dest is not empty. The reason for this is to enforce 00418 that clients do not accidentally re-use the same (populated) 00419 node for serialization of multiple objects, which would cause 00420 deserialization of the container to fail. 00421 */ 00422 template <typename NodeType, typename MapType> 00423 bool serialize_map( NodeType & dest, const MapType & src ); 00424 00425 00426 00427 /** 00428 Identical to the two-argument form, but creates a 00429 subnode of dest, named subnodename, and serializes 00430 to that node. 00431 00432 If serialization into the new child node fails, the 00433 child node is not added to dest and the error 00434 (possibly an exception) is propagated back to the 00435 caller. 00436 */ 00437 00438 template <typename NodeType, typename MapType> 00439 bool serialize_map( NodeType & dest, const std::string & subnodename, const MapType & src ); 00440 00441 /** 00442 A functor equivalent of serialize_map(). 00443 00444 Added in version 1.1.3. 00445 */ 00446 struct serialize_map_f : ::s11n::serialize_binary_f_tag 00447 { 00448 template <typename NodeType, typename MapType> 00449 inline bool operator()( NodeType & dest, const MapType & src ) const 00450 { 00451 return serialize_map<NodeType,MapType>( dest, src ); 00452 } 00453 00454 template <typename NodeType, typename MapType> 00455 inline bool operator()( NodeType & dest, const std::string & subnodename, const MapType & src ) const 00456 { 00457 return serialize_map<NodeType,MapType>( dest, subnodename, src ); 00458 } 00459 }; 00460 00461 /** 00462 The counterpart of serializer_map(), deserializes src into the 00463 given map. MapType must be Serializable and contain pairs 00464 which themselves are Serializables... ad inifinitum.. 00465 00466 As of 1.1.3, this function relies on s11n_traits::cleanup_functor 00467 for proper cleanup in the face of failed deserialization. 00468 See deserialize_pair() for details. Assuming that cleanup 00469 routines are in place, this function can now guaranty that 00470 dest is not modified if deserialization fails. However, 00471 dest must be empty when it is passed to this function, 00472 or on success its contents may very well go missing. 00473 00474 Minor caveat: 00475 00476 This operation will only work with maps containing std::pair 00477 types, not map-like classes which use a different pair 00478 type. :( The reason is that map<X,Y>::value_type is 00479 not a pair of (X,Y), but (const Y,Y), which means we cannot 00480 use the map's value_type for a deser operation because we 00481 cannot assign to its .first element (i.e., can't 00482 deserialize it). To get around that we "manually" create a 00483 new std::pair type using map's key_type and mapped_type 00484 typedefs, which "loses" the constness for us so we can 00485 assign to the first_type during deserialization, and then 00486 insert that pair into the deserializing map. 00487 00488 MapType must: 00489 00490 - not be a pointer type. 00491 00492 - have a swap() member function, to support the 00493 no-change-on-error feature. 00494 */ 00495 template <typename NodeType, typename MapType> 00496 bool deserialize_map( const NodeType & src, MapType & dest ); 00497 00498 00499 /** 00500 Identical to the two-argument form, but tries to 00501 deserialize from a subnode of src named 00502 subnodename. If no such node is found then false is 00503 returned, otherwise the result of 00504 deserialize_map(thechild,dest) is returned. 00505 */ 00506 template <typename NodeType, typename MapType> 00507 bool deserialize_map( const NodeType & src, const std::string & subnodename, MapType & dest ); 00508 00509 /** 00510 A functor equivalent of deserialize_map(). 00511 00512 Added in version 1.1.3. 00513 */ 00514 struct deserialize_map_f : ::s11n::deserialize_binary_f_tag 00515 { 00516 template <typename NodeType, typename MapType> 00517 inline bool operator()( const NodeType & src, MapType & dest ) const 00518 { 00519 return deserialize_map<NodeType,MapType>( src, dest ); 00520 } 00521 00522 template <typename NodeType, typename MapType> 00523 inline bool operator()( const NodeType & src, const std::string & subnodename, MapType & dest ) const 00524 { 00525 return deserialize_map<NodeType,MapType>( src, subnodename, dest ); 00526 } 00527 }; 00528 00529 00530 /** 00531 A proxy for de/serializing pair types holding two 00532 i/ostreamable components. It is NOT usable with 00533 pairs from map-like containers because those keys are 00534 const, and thus we cannot assign to them. 00535 00536 Added in 1.1.3. 00537 */ 00538 struct streamable_pair_serializable_proxy : ::s11n::serialize_binary_f_tag, ::s11n::deserialize_binary_f_tag 00539 { 00540 /** 00541 Serializes src to dest. 00542 00543 ACHTUNG: never pass the same destination container 00544 to this operator more than once or you will get 00545 duplicate and/or incorrect data. 00546 00547 SerializableType must be a std::pair<X,Y>, 00548 or compatible. X may not be a contst type. 00549 00550 See serialize_streamable_pair() for more details. 00551 00552 */ 00553 template <typename NodeType, typename SerializableType> 00554 inline bool operator()( NodeType & dest, const SerializableType & src ) const 00555 { 00556 return serialize_streamable_pair( dest, src ); 00557 } 00558 00559 /** 00560 Deserializes dest from src. See the serialize operator 00561 for requirements placed on SerializableType. 00562 00563 See deserialize_streamable_pair() for more details. 00564 */ 00565 template <typename NodeType, typename SerializableType> 00566 inline bool operator()( const NodeType & src, SerializableType & dest ) const 00567 { 00568 return deserialize_streamable_pair( src, dest ); 00569 } 00570 }; 00571 00572 00573 00574 00575 /** 00576 pair_serializable_proxy is a Serializable Proxy for 00577 std::pairs. 00578 */ 00579 struct pair_serializable_proxy : ::s11n::serialize_binary_f_tag, 00580 ::s11n::deserialize_binary_f_tag 00581 { 00582 /** 00583 See ::s11n::map::serialize_pair(). 00584 */ 00585 template <typename NodeType, typename PairType> 00586 inline bool operator()( NodeType & dest, const PairType & src ) const 00587 { 00588 return serialize_pair( dest, src ); 00589 } 00590 /** 00591 See ::s11n::map::deserialize_pair(). 00592 */ 00593 template <typename NodeType, typename PairType> 00594 inline bool operator()( const NodeType & src, PairType & dest ) const 00595 { 00596 return deserialize_pair( src, dest ); 00597 } 00598 }; 00599 00600 00601 00602 /** 00603 A proxy which can serialize std::maps which contain Streamable 00604 Types. 00605 00606 It uses de/serialize_streamable_map(), so see those 00607 functions for details. 00608 */ 00609 struct streamable_map_serializable_proxy : ::s11n::serialize_binary_f_tag, 00610 ::s11n::deserialize_binary_f_tag 00611 { 00612 /** 00613 Serializes src to dest. 00614 00615 ACHTUNG: never pass the same destination container 00616 to this operator more than once or you will get 00617 duplicate and/or incorrect data. 00618 */ 00619 template <typename NodeType, typename SerializableType> 00620 inline bool operator()( NodeType & dest , const SerializableType & src ) const 00621 { 00622 return serialize_streamable_map( dest, src ); 00623 } 00624 00625 /** 00626 Deserializes dest from src. 00627 */ 00628 template <typename NodeType, typename SerializableType> 00629 inline bool operator()( const NodeType & src , SerializableType & dest ) const 00630 { 00631 return deserialize_streamable_map( src, dest ); 00632 } 00633 }; 00634 00635 00636 00637 /** 00638 map_serializable_proxy is a Serialization Proxy for std::maps. 00639 00640 See de/serialize_map(): this functor simply wraps those. 00641 00642 */ 00643 struct map_serializable_proxy : ::s11n::serialize_binary_f_tag, 00644 ::s11n::deserialize_binary_f_tag 00645 { 00646 00647 /** 00648 Serializes src into dest. Returns true on success, 00649 false on error. Uses serialize_map(), so see that 00650 function for details. 00651 */ 00652 template <typename NodeType, typename MapType> 00653 inline bool operator()( NodeType & dest , const MapType & src ) const 00654 { 00655 return serialize_map( dest, src ); 00656 } 00657 /** 00658 Deserializes src into dest. Returns true on 00659 success, false on error. Uses serialize_map(), so 00660 see that function for details. 00661 */ 00662 template <typename NodeType, typename MapType> 00663 inline bool operator()( const NodeType & src , MapType & dest ) const 00664 { 00665 return deserialize_map( src, dest ); 00666 } 00667 }; 00668 00669 00670 } // namespace map 00671 } // namespace s11n 00672 00673 #include <s11n.net/s11n/proxy/mapish.tpp> // implementations for template code 00674 #endif // s11n_net_s11n_v1_1_MAP_HPP_INCLUDED