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