1 /*
2 * Copyright (C) 2005-2008 by Dr. Marc Boris Duerner
3 * Copyright (C) 2011 by Tommi Maekitalo
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * As a special exception, you may use this file as part of a free
11 * software library without restriction. Specifically, if other files
12 * instantiate templates or use macros or inline functions from this
13 * file, or you compile this file and link it with other files to
14 * produce an executable, this file does not by itself cause the
15 * resulting executable to be covered by the GNU General Public
16 * License. This exception does not however invalidate any other
17 * reasons why the executable file might be covered by the GNU Library
18 * General Public License.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29 #ifndef cxxtools_SerializationInfo_h
30 #define cxxtools_SerializationInfo_h
31
32 #include <cxxtools/api.h>
33 #include <cxxtools/string.h>
34 #include <cxxtools/convert.h>
35 #include <cxxtools/serializationerror.h>
36 #include <vector>
37 #include <set>
38 #include <map>
39 #include <list>
40 #include <deque>
41 #include <limits>
42 #include <typeinfo>
43 #include <cxxtools/config.h>
44
45 namespace cxxtools
46 {
47
48 /** @brief Represents arbitrary types during serialization.
49 */
50 class CXXTOOLS_API SerializationInfo
51 {
52 typedef std::vector<SerializationInfo> Nodes;
53
54 public:
55 enum Category {
56 Void = 0, Value = 1, Object = 2, Array = 6
57 };
58
59 class Iterator;
60 class ConstIterator;
61
62 #ifdef HAVE_LONG_LONG
63 typedef long long int_type;
64 #else
65 typedef long int_type;
66 #endif
67 #ifdef HAVE_UNSIGNED_LONG_LONG
68 typedef unsigned long long unsigned_type;
69 #else
70 typedef unsigned long unsigned_type;
71 #endif
72
73 public:
74 SerializationInfo();
75
76 SerializationInfo(const SerializationInfo& si);
77
~SerializationInfo()78 ~SerializationInfo()
79 { _releaseValue(); }
80
81 void reserve(size_t n);
82
category()83 Category category() const
84 {
85 return _category;
86 }
87
setCategory(Category cat)88 void setCategory(Category cat)
89 {
90 _category = cat;
91 }
92
parent()93 SerializationInfo* parent()
94 {
95 return _parent;
96 }
97
parent()98 const SerializationInfo* parent() const
99 {
100 return _parent;
101 }
102
typeName()103 const std::string& typeName() const
104 {
105 return _type;
106 }
107
setTypeName(const std::string & type)108 void setTypeName(const std::string& type)
109 {
110 _type = type;
111 }
112
name()113 const std::string& name() const
114 {
115 return _name;
116 }
117
setName(const std::string & name)118 void setName(const std::string& name)
119 {
120 _name = name;
121 }
122
123 /** @brief Serialization of flat data-types
124 */
setValue(const String & value)125 void setValue(const String& value) { _setString(value); }
setValue(const std::string & value)126 void setValue(const std::string& value) { _setString8(value); }
setValue(const char * value)127 void setValue(const char* value) { _setString8(value); }
setValue(Char value)128 void setValue(Char value) { _setString(String(1, value)); }
setValue(wchar_t value)129 void setValue(wchar_t value) { _setString(String(1, value)); }
setValue(bool value)130 void setValue(bool value) { _setBool(value) ; }
setValue(char value)131 void setValue(char value) { _setChar(value) ; }
setValue(unsigned char value)132 void setValue(unsigned char value) { _setUInt(value) ; }
setValue(short value)133 void setValue(short value) { _setInt(value) ; }
setValue(unsigned short value)134 void setValue(unsigned short value) { _setUInt(value) ; }
setValue(int value)135 void setValue(int value) { _setInt(value) ; }
setValue(unsigned int value)136 void setValue(unsigned int value) { _setUInt(value) ; }
setValue(long value)137 void setValue(long value) { _setInt(value) ; }
setValue(unsigned long value)138 void setValue(unsigned long value) { _setUInt(value) ; }
139 #ifdef HAVE_LONG_LONG
setValue(long long value)140 void setValue(long long value) { _setInt(value) ; }
141 #endif
142 #ifdef HAVE_UNSIGNED_LONG_LONG
setValue(unsigned long long value)143 void setValue(unsigned long long value) { _setUInt(value) ; }
144 #endif
145
setValue(float value)146 void setValue(float value) { _setFloat(value); }
setValue(double value)147 void setValue(double value) { _setFloat(value); }
setValue(long double value)148 void setValue(long double value) { _setFloat(value); }
149 void setNull();
150
151 /** @brief Deserialization of flat data-types
152 */
153 void getValue(String& value) const;
154 void getValue(std::string& value) const;
getValue(Char & value)155 void getValue(Char& value) const { value = _getWChar(); }
getValue(wchar_t & value)156 void getValue(wchar_t& value) const { value = _getWChar(); }
getValue(bool & value)157 void getValue(bool& value) const { value = _getBool(); }
getValue(char & value)158 void getValue(char& value) const { value = _getChar(); }
getValue(signed char & value)159 void getValue(signed char& value) const
160 { value = static_cast<signed char>(_getInt("signed char", std::numeric_limits<signed char>::min(), std::numeric_limits<signed char>::max())); }
getValue(unsigned char & value)161 void getValue(unsigned char& value) const
162 { value = static_cast<signed char>(_getUInt("unsigned char", std::numeric_limits<unsigned char>::max())); }
getValue(short & value)163 void getValue(short& value) const
164 { value = static_cast<short>(_getInt("short", std::numeric_limits<short>::min(), std::numeric_limits<short>::max())); }
getValue(unsigned short & value)165 void getValue(unsigned short& value) const
166 { value = static_cast<unsigned short>(_getUInt("unsigned short", std::numeric_limits<unsigned short>::max())); }
getValue(int & value)167 void getValue(int& value) const
168 { value = static_cast<int>(_getInt("int", std::numeric_limits<int>::min(), std::numeric_limits<int>::max())); }
getValue(unsigned int & value)169 void getValue(unsigned int& value) const
170 { value = static_cast<unsigned int>(_getUInt("unsigned int", std::numeric_limits<unsigned int>::max())); }
getValue(long & value)171 void getValue(long& value) const
172 { value = static_cast<long>(_getInt("long", std::numeric_limits<long>::min(), std::numeric_limits<long>::max())); }
getValue(unsigned long & value)173 void getValue(unsigned long& value) const
174 { value = static_cast<unsigned long>(_getUInt("unsigned long", std::numeric_limits<unsigned long>::max())); }
175 #ifdef HAVE_LONG_LONG
getValue(long long & value)176 void getValue(long long& value) const
177 { value = static_cast<long long>(_getInt("long long", std::numeric_limits<long long>::min(), std::numeric_limits<long long>::max())); }
178 #endif
179 #ifdef HAVE_UNSIGNED_LONG_LONG
getValue(unsigned long long & value)180 void getValue(unsigned long long& value) const
181 { value = static_cast<unsigned long long>(_getUInt("unsigned long long", std::numeric_limits<unsigned long long>::max())); }
182 #endif
getValue(float & value)183 void getValue(float& value) const
184 { value = static_cast<float>(_getFloat("float", std::numeric_limits<float>::max())); }
getValue(double & value)185 void getValue(double& value) const
186 { value = static_cast<double>(_getFloat("double", std::numeric_limits<double>::max())); }
getValue(long double & value)187 void getValue(long double& value) const
188 { value = static_cast<long double>(_getFloat("long double", std::numeric_limits<long double>::max())); }
189
190 /** @brief Serialization of flat member data-types
191 */
192 template <typename T>
addValue(const std::string & name,const T & value)193 SerializationInfo& addValue(const std::string& name, const T& value)
194 {
195 SerializationInfo& info = this->addMember(name);
196 info.setValue(value);
197 return info;
198 }
199
200 /** @brief Serialization of member data
201 */
202 SerializationInfo& addMember(const std::string& name);
203
204 /** @brief Deserialization of member data
205
206 @throws SerializationError when member is not found.
207 */
208 const SerializationInfo& getMember(const std::string& name) const;
209
210 /** @brief Deserialization of member data
211
212 @throws std::range_error when index is too large
213 */
214 const SerializationInfo& getMember(unsigned idx) const;
215
216 /** @brief Deserialization of member data.
217
218 @return true if member is found, false otherwise.
219 The passed value is not modified when the member was not found.
220 */
221 template <typename T>
getMember(const std::string & name,T & value)222 bool getMember(const std::string& name, T& value) const
223 {
224 const SerializationInfo* si = findMember(name);
225 if (si == 0)
226 return false;
227 *si >>= value;
228 return true;
229 }
230
231 /** @brief Find member data by name
232
233 This method returns the data for an object with the name \a name.
234 or null if it is not present.
235 */
236 const SerializationInfo* findMember(const std::string& name) const;
237
238 /** @brief Find member data by name
239
240 This method returns the data for an object with the name \a name.
241 or null if it is not present.
242 */
243 SerializationInfo* findMember(const std::string& name);
244
memberCount()245 size_t memberCount() const
246 {
247 return _nodes.size();
248 }
249
250 Iterator begin();
251
252 Iterator end();
253
254 ConstIterator begin() const;
255
256 ConstIterator end() const;
257
258 SerializationInfo& operator =(const SerializationInfo& si);
259
260 void clear();
261
262 void swap(SerializationInfo& si);
263
isNull()264 bool isNull() const { return _t == t_none && _category == Void; }
isString()265 bool isString() const { return _t == t_string; }
isString8()266 bool isString8() const { return _t == t_string8; }
isChar()267 bool isChar() const { return _t == t_char; }
isBool()268 bool isBool() const { return _t == t_bool; }
isInt()269 bool isInt() const { return _t == t_int; }
isUInt()270 bool isUInt() const { return _t == t_uint; }
isFloat()271 bool isFloat() const { return _t == t_float; }
272
273 void dump(std::ostream& out, const std::string& praefix = std::string()) const;
274
275 protected:
setParent(SerializationInfo & si)276 void setParent(SerializationInfo& si)
277 { _parent = &si; }
278
279 private:
280 SerializationInfo* _parent;
281 Category _category;
282 std::string _name;
283 std::string _type;
284
285 void _releaseValue();
286 void _setString(const String& value);
287 void _setString8(const std::string& value);
288 void _setString8(const char* value);
289 void _setChar(char value);
290 void _setBool(bool value);
291 void _setInt(int_type value);
292 void _setUInt(unsigned_type value);
293 void _setFloat(long double value);
294
295 bool _getBool() const;
296 wchar_t _getWChar() const;
297 char _getChar() const;
298 int_type _getInt(const char* type, int_type min, int_type max) const;
299 unsigned_type _getUInt(const char* type, unsigned_type max) const;
300 long double _getFloat(const char* type, long double max) const;
301
302 union U
303 {
304 char _s[sizeof(String) >= sizeof(std::string) ? sizeof(String) : sizeof(std::string)];
305 char _c;
306 bool _b;
307 int_type _i;
308 unsigned_type _u;
309 long double _f;
310 } _u;
311
_StringPtr()312 String* _StringPtr() { return reinterpret_cast<String*>(_u._s); }
_String()313 String& _String() { return *_StringPtr(); }
_StringPtr()314 const String* _StringPtr() const { return reinterpret_cast<const String*>(_u._s); }
_String()315 const String& _String() const { return *_StringPtr(); }
_String8Ptr()316 std::string* _String8Ptr() { return reinterpret_cast<std::string*>(_u._s); }
_String8()317 std::string& _String8() { return *_String8Ptr(); }
_String8Ptr()318 const std::string* _String8Ptr() const { return reinterpret_cast<const std::string*>(_u._s); }
_String8()319 const std::string& _String8() const { return *_String8Ptr(); }
320
321 enum T
322 {
323 t_none,
324 t_string,
325 t_string8,
326 t_char,
327 t_bool,
328 t_int,
329 t_uint,
330 t_float
331 } _t;
332
333 Nodes _nodes; // objects/arrays
334 };
335
336
337 class SerializationInfo::Iterator
338 {
339 public:
340 Iterator();
341
342 Iterator(const Iterator& other);
343
344 Iterator(SerializationInfo* info);
345
346 Iterator& operator=(const Iterator& other);
347
348 Iterator& operator++();
349
350 SerializationInfo& operator*();
351
352 SerializationInfo* operator->();
353
354 bool operator!=(const Iterator& other) const;
355
356 bool operator==(const Iterator& other) const;
357
358 private:
359 SerializationInfo* _info;
360 };
361
362
363 class SerializationInfo::ConstIterator
364 {
365 public:
366 ConstIterator();
367
368 ConstIterator(const ConstIterator& other);
369
370 ConstIterator(const SerializationInfo* info);
371
372 ConstIterator& operator=(const ConstIterator& other);
373
374 ConstIterator& operator++();
375
376 const SerializationInfo& operator*() const;
377
378 const SerializationInfo* operator->() const;
379
380 bool operator!=(const ConstIterator& other) const;
381
382 bool operator==(const ConstIterator& other) const;
383
384 private:
385 const SerializationInfo* _info;
386 };
387
388
Iterator()389 inline SerializationInfo::Iterator::Iterator()
390 : _info(0)
391 {}
392
393
Iterator(const Iterator & other)394 inline SerializationInfo::Iterator::Iterator(const Iterator& other)
395 : _info(other._info)
396 {}
397
398
Iterator(SerializationInfo * info)399 inline SerializationInfo::Iterator::Iterator(SerializationInfo* info)
400 : _info(info)
401 {}
402
403
404 inline SerializationInfo::Iterator& SerializationInfo::Iterator::operator=(const Iterator& other)
405 {
406 _info = other._info;
407 return *this;
408 }
409
410
411 inline SerializationInfo::Iterator& SerializationInfo::Iterator::operator++()
412 {
413 ++_info;
414 return *this;
415 }
416
417
418 inline SerializationInfo& SerializationInfo::Iterator::operator*()
419 {
420 return *_info;
421 }
422
423
424 inline SerializationInfo* SerializationInfo::Iterator::operator->()
425 {
426 return _info;
427 }
428
429
430 inline bool SerializationInfo::Iterator::operator!=(const Iterator& other) const
431 {
432 return _info != other._info;
433 }
434
435
436 inline bool SerializationInfo::Iterator::operator==(const Iterator& other) const
437 {
438 return _info == other._info;
439 }
440
441
ConstIterator()442 inline SerializationInfo::ConstIterator::ConstIterator()
443 : _info(0)
444 {}
445
446
ConstIterator(const ConstIterator & other)447 inline SerializationInfo::ConstIterator::ConstIterator(const ConstIterator& other)
448 : _info(other._info)
449 {}
450
451
ConstIterator(const SerializationInfo * info)452 inline SerializationInfo::ConstIterator::ConstIterator(const SerializationInfo* info)
453 : _info(info)
454 {}
455
456
457 inline SerializationInfo::ConstIterator& SerializationInfo::ConstIterator::operator=(const ConstIterator& other)
458 {
459 _info = other._info;
460 return *this;
461 }
462
463
464 inline SerializationInfo::ConstIterator& SerializationInfo::ConstIterator::operator++()
465 {
466 ++_info;
467 return *this;
468 }
469
470
471 inline const SerializationInfo& SerializationInfo::ConstIterator::operator*() const
472 {
473 return *_info;
474 }
475
476
477 inline const SerializationInfo* SerializationInfo::ConstIterator::operator->() const
478 {
479 return _info;
480 }
481
482
483 inline bool SerializationInfo::ConstIterator::operator!=(const ConstIterator& other) const
484 {
485 return _info != other._info;
486 }
487
488
489 inline bool SerializationInfo::ConstIterator::operator==(const ConstIterator& other) const
490 {
491 return _info == other._info;
492 }
493
494
495 inline void operator >>=(const SerializationInfo& si, SerializationInfo& ssi)
496 {
497 ssi = si;
498 }
499
500
501 inline void operator <<=(SerializationInfo& si, const SerializationInfo& ssi)
502 {
503 si = ssi;
504 }
505
506
507 inline void operator >>=(const SerializationInfo& si, bool& n)
508 {
509 si.getValue(n);
510 }
511
512
513 inline void operator <<=(SerializationInfo& si, bool n)
514 {
515 si.setValue(n);
516 si.setTypeName("bool");
517 }
518
519
520 inline void operator >>=(const SerializationInfo& si, signed char& n)
521 {
522 si.getValue(n);
523 }
524
525
526 inline void operator <<=(SerializationInfo& si, signed char n)
527 {
528 si.setValue(n);
529 si.setTypeName("char");
530 }
531
532
533 inline void operator >>=(const SerializationInfo& si, unsigned char& n)
534 {
535 si.getValue(n);
536 }
537
538
539 inline void operator <<=(SerializationInfo& si, unsigned char n)
540 {
541 si.setValue(n);
542 si.setTypeName("char");
543 }
544
545
546 inline void operator >>=(const SerializationInfo& si, char& n)
547 {
548 si.getValue(n);
549 }
550
551
552 inline void operator <<=(SerializationInfo& si, char n)
553 {
554 si.setValue(n);
555 si.setTypeName("char");
556 }
557
558
559 inline void operator >>=(const SerializationInfo& si, short& n)
560 {
561 si.getValue(n);
562 }
563
564
565 inline void operator <<=(SerializationInfo& si, short n)
566 {
567 si.setValue(n);
568 si.setTypeName("int");
569 }
570
571
572 inline void operator >>=(const SerializationInfo& si, unsigned short& n)
573 {
574 si.getValue(n);
575 }
576
577
578 inline void operator <<=(SerializationInfo& si, unsigned short n)
579 {
580 si.setValue(n);
581 si.setTypeName("int");
582 }
583
584
585 inline void operator >>=(const SerializationInfo& si, int& n)
586 {
587 si.getValue(n);
588 }
589
590
591 inline void operator <<=(SerializationInfo& si, int n)
592 {
593 si.setValue(n);
594 si.setTypeName("int");
595 }
596
597
598 inline void operator >>=(const SerializationInfo& si, unsigned int& n)
599 {
600 si.getValue(n);
601 }
602
603
604 inline void operator <<=(SerializationInfo& si, unsigned int n)
605 {
606 si.setValue(n);
607 si.setTypeName("int");
608 }
609
610
611 inline void operator >>=(const SerializationInfo& si, long& n)
612 {
613 si.getValue(n);
614 }
615
616
617 inline void operator <<=(SerializationInfo& si, long n)
618 {
619 si.setValue(n);
620 si.setTypeName("int");
621 }
622
623
624 inline void operator >>=(const SerializationInfo& si, unsigned long& n)
625 {
626 si.getValue(n);
627 }
628
629
630 inline void operator <<=(SerializationInfo& si, unsigned long n)
631 {
632 si.setValue(n);
633 si.setTypeName("int");
634 }
635
636
637 #ifdef HAVE_LONG_LONG
638
639 inline void operator >>=(const SerializationInfo& si, long long& n)
640 {
641 si.getValue(n);
642 }
643
644
645 inline void operator <<=(SerializationInfo& si, long long n)
646 {
647 si.setValue(n);
648 si.setTypeName("int");
649 }
650
651 #endif
652
653
654 #ifdef HAVE_UNSIGNED_LONG_LONG
655
656 inline void operator >>=(const SerializationInfo& si, unsigned long long& n)
657 {
658 si.getValue(n);
659 }
660
661
662 inline void operator <<=(SerializationInfo& si, unsigned long long n)
663 {
664 si.setValue(n);
665 si.setTypeName("int");
666 }
667
668 #endif
669
670
671 inline void operator >>=(const SerializationInfo& si, float& n)
672 {
673 si.getValue(n);
674 }
675
676
677 inline void operator <<=(SerializationInfo& si, float n)
678 {
679 si.setValue(n);
680 si.setTypeName("double");
681 }
682
683
684 inline void operator >>=(const SerializationInfo& si, double& n)
685 {
686 si.getValue(n);
687 }
688
689
690 inline void operator <<=(SerializationInfo& si, double n)
691 {
692 si.setValue(n);
693 si.setTypeName("double");
694 }
695
696
697 inline void operator >>=(const SerializationInfo& si, std::string& n)
698 {
699 si.getValue(n);
700 }
701
702
703 inline void operator <<=(SerializationInfo& si, const std::string& n)
704 {
705 si.setValue(n);
706 si.setTypeName("string");
707 }
708
709
710 inline void operator <<=(SerializationInfo& si, const char* n)
711 {
712 si.setValue(n);
713 si.setTypeName("string");
714 }
715
716
717 inline void operator >>=(const SerializationInfo& si, cxxtools::String& n)
718 {
719 si.getValue(n);
720 }
721
722
723 inline void operator <<=(SerializationInfo& si, const cxxtools::String& n)
724 {
725 si.setValue(n);
726 si.setTypeName("string");
727 }
728
729
730 template <typename T, typename A>
731 inline void operator >>=(const SerializationInfo& si, std::vector<T, A>& vec)
732 {
733 vec.clear();
734 vec.reserve(si.memberCount());
735 for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
736 {
737 vec.resize( vec.size() + 1 );
738 *it >>= vec.back();
739 }
740 }
741
742
743 template <typename T, typename A>
744 inline void operator <<=(SerializationInfo& si, const std::vector<T, A>& vec)
745 {
746 typename std::vector<T, A>::const_iterator it;
747
748 si.reserve(vec.size());
749 for(it = vec.begin(); it != vec.end(); ++it)
750 {
751 SerializationInfo& newSi = si.addMember(std::string());
752 newSi <<= *it;
753 }
754
755 si.setTypeName("array");
756 si.setCategory(SerializationInfo::Array);
757 }
758
759
760 inline void operator >>=(const SerializationInfo& si, std::vector<int>& vec)
761 {
762 vec.clear();
763 for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
764 {
765 vec.resize( vec.size() + 1 );
766 *it >>= vec.back();
767 }
768 }
769
770 inline void operator <<=(SerializationInfo& si, const std::vector<int>& vec)
771 {
772 std::vector<int>::const_iterator it;
773
774 for(it = vec.begin(); it != vec.end(); ++it)
775 {
776 SerializationInfo& newSi = si.addMember(std::string());
777 newSi <<= *it;
778 }
779
780 si.setTypeName("array");
781 si.setCategory(SerializationInfo::Array);
782 }
783
784
785 template <typename T, typename A>
786 inline void operator >>=(const SerializationInfo& si, std::list<T, A>& list)
787 {
788 list.clear();
789 for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
790 {
791 list.resize( list.size() + 1 );
792 *it >>= list.back();
793 }
794 }
795
796
797 template <typename T, typename A>
798 inline void operator <<=(SerializationInfo& si, const std::list<T, A>& list)
799 {
800 typename std::list<T, A>::const_iterator it;
801
802 for(it = list.begin(); it != list.end(); ++it)
803 {
804 SerializationInfo& newSi = si.addMember(std::string());
805 newSi <<= *it;
806 }
807
808 si.setTypeName("list");
809 si.setCategory(SerializationInfo::Array);
810 }
811
812
813 template <typename T, typename A>
814 inline void operator >>=(const SerializationInfo& si, std::deque<T, A>& deque)
815 {
816 deque.clear();
817 for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
818 {
819 deque.resize( deque.size() + 1 );
820 *it >>= deque.back();
821 }
822 }
823
824
825 template <typename T, typename A>
826 inline void operator <<=(SerializationInfo& si, const std::deque<T, A>& deque)
827 {
828 typename std::deque<T, A>::const_iterator it;
829
830 for(it = deque.begin(); it != deque.end(); ++it)
831 {
832 SerializationInfo& newSi = si.addMember(std::string());
833 newSi <<= *it;
834 }
835
836 si.setTypeName("deque");
837 si.setCategory(SerializationInfo::Array);
838 }
839
840
841 template <typename T, typename C, typename A>
842 inline void operator >>=(const SerializationInfo& si, std::set<T, C, A>& set)
843 {
844 set.clear();
845 for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
846 {
847 T t;
848 *it >>= t;
849 set.insert(t);
850 }
851 }
852
853
854 template <typename T, typename C, typename A>
855 inline void operator <<=(SerializationInfo& si, const std::set<T, C, A>& set)
856 {
857 typename std::set<T, C, A>::const_iterator it;
858
859 for(it = set.begin(); it != set.end(); ++it)
860 {
861 SerializationInfo& newSi = si.addMember(std::string());
862 newSi <<= *it;
863 }
864
865 si.setTypeName("set");
866 si.setCategory(SerializationInfo::Array);
867 }
868
869
870 template <typename T, typename C, typename A>
871 inline void operator >>=(const SerializationInfo& si, std::multiset<T, C, A>& multiset)
872 {
873 multiset.clear();
874 for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
875 {
876 T t;
877 *it >>= t;
878 multiset.insert(t);
879 }
880 }
881
882
883 template <typename T, typename C, typename A>
884 inline void operator <<=(SerializationInfo& si, const std::multiset<T, C, A>& multiset)
885 {
886 typename std::multiset<T, C, A>::const_iterator it;
887
888 for(it = multiset.begin(); it != multiset.end(); ++it)
889 {
890 SerializationInfo& newSi = si.addMember(std::string());
891 newSi <<= *it;
892 }
893
894 si.setTypeName("multiset");
895 si.setCategory(SerializationInfo::Array);
896 }
897
898
899 template <typename A, typename B>
900 inline void operator >>=(const SerializationInfo& si, std::pair<A, B>& p)
901 {
902 si.getMember("first") >>= p.first;
903 si.getMember("second") >>= p.second;
904 }
905
906
907 template <typename A, typename B>
908 inline void operator <<=(SerializationInfo& si, const std::pair<A, B>& p)
909 {
910 si.setTypeName("pair");
911 si.addMember("first") <<= p.first;
912 si.addMember("second") <<= p.second;
913 }
914
915
916 template <typename K, typename V, typename P, typename A>
917 inline void operator >>=(const SerializationInfo& si, std::map<K, V, P, A>& map)
918 {
919 map.clear();
920 for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
921 {
922 typename std::pair<K, V> v;
923 *it >>= v;
924 map.insert(v);
925 }
926 }
927
928
929 template <typename K, typename V, typename P, typename A>
930 inline void operator <<=(SerializationInfo& si, const std::map<K, V, P, A>& map)
931 {
932 typename std::map<K, V, P, A>::const_iterator it;
933
934 for(it = map.begin(); it != map.end(); ++it)
935 {
936 SerializationInfo& newSi = si.addMember(std::string());
937 newSi <<= *it;
938 }
939
940 si.setTypeName("map");
941 si.setCategory(SerializationInfo::Array);
942 }
943
944
945 template <typename K, typename V, typename P, typename A>
946 inline void operator >>=(const SerializationInfo& si, std::multimap<K, V, P, A>& multimap)
947 {
948 multimap.clear();
949 for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
950 {
951 typename std::pair<K, V> v;
952 *it >>= v;
953 multimap.insert(v);
954 }
955 }
956
957
958 template <typename T, typename C, typename P, typename A>
959 inline void operator <<=(SerializationInfo& si, const std::multimap<T, C, P, A>& multimap)
960 {
961 typename std::multimap<T, C, P, A>::const_iterator it;
962
963 for(it = multimap.begin(); it != multimap.end(); ++it)
964 {
965 SerializationInfo& newSi = si.addMember(std::string());
966 newSi <<= *it;
967 }
968
969 si.setTypeName("multimap");
970 si.setCategory(SerializationInfo::Array);
971 }
972
973
974 inline std::ostream& operator<< (std::ostream& out, const SerializationInfo& si)
975 {
976 si.dump(out);
977 return out;
978 }
979
980 } // namespace cxxtools
981
982
983 #endif
984