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