serializationinfo.h
Go to the documentation of this file.
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/string.h>
33 #include <vector>
34 #include <set>
35 #include <map>
36 #include <list>
37 #include <deque>
38 #include <limits>
39 #include <typeinfo>
40 #include <cxxtools/config.h>
41 
42 #if __cplusplus >= 201103L
43 
44 #include <forward_list>
45 #include <unordered_set>
46 #include <unordered_map>
47 #include <utility>
48 
49 #endif
50 
51 namespace cxxtools
52 {
53 
109 {
110  typedef std::deque<SerializationInfo> Nodes;
111  friend void operator <<=(SerializationInfo& si, const SerializationInfo& ssi);
112 
113  public:
114  enum Category {
115  Void = 0, Value = 1, Object = 2, Array = 6
116  };
117 
119  typedef Nodes::iterator Iterator;
121  typedef Nodes::const_iterator ConstIterator;
122 
124  typedef Nodes::iterator iterator;
126  typedef Nodes::const_iterator const_iterator;
127 
128 #ifdef HAVE_LONG_LONG
129  typedef long long int_type;
130 #else
131  typedef long int_type;
132 #endif
133 #ifdef HAVE_UNSIGNED_LONG_LONG
134  typedef unsigned long long unsigned_type;
135 #else
136  typedef unsigned long unsigned_type;
137 #endif
138 
139  public:
141 
143 
145 
147 
148 #if __cplusplus >= 201103L
149 
150  SerializationInfo(SerializationInfo&& si) noexcept;
151 
152  SerializationInfo& operator=(SerializationInfo&& si);
153 
154 #endif
155 
157  {
158  return _category;
159  }
160 
162  {
163  _category = cat;
164  }
165 
166  const std::string& typeName() const
167  {
168  return _type;
169  }
170 
171  void setTypeName(const std::string& type)
172  {
173  _type = type;
174  }
175 
176  const std::string& name() const
177  {
178  return _name;
179  }
180 
181  void setName(const std::string& name)
182  {
183  _name = name;
184  }
185 
188  void setValue(const String& value) { _setString(value); }
189  void setValue(const std::string& value) { _setString8(value); }
190  void setValue(const char* value) { _setString8(value); }
191  void setValue(Char value) { _setString(String(1, value)); }
192  void setValue(wchar_t value) { _setString(String(1, value)); }
193  void setValue(bool value) { _setBool(value) ; }
194  void setValue(char value) { _setChar(value) ; }
195  void setValue(unsigned char value) { _setUInt(value) ; }
196  void setValue(short value) { _setInt(value) ; }
197  void setValue(unsigned short value) { _setUInt(value) ; }
198  void setValue(int value) { _setInt(value) ; }
199  void setValue(unsigned int value) { _setUInt(value) ; }
200  void setValue(long value) { _setInt(value) ; }
201  void setValue(unsigned long value) { _setUInt(value) ; }
202 #ifdef HAVE_LONG_LONG
203  void setValue(long long value) { _setInt(value) ; }
204 #endif
205 #ifdef HAVE_UNSIGNED_LONG_LONG
206  void setValue(unsigned long long value) { _setUInt(value) ; }
207 #endif
208 
209  void setValue(float value) { _setFloat(value); }
210  void setValue(double value) { _setFloat(value); }
211  void setValue(long double value) { _setFloat(value); }
212  void setNull();
213 
216  void getValue(String& value) const;
217  void getValue(std::string& value) const;
218  void getValue(Char& value) const { value = _getWChar(); }
219  void getValue(wchar_t& value) const { value = _getWChar(); }
220  void getValue(bool& value) const { value = _getBool(); }
221  void getValue(char& value) const { value = _getChar(); }
222  void getValue(signed char& value) const
223  { value = static_cast<signed char>(_getInt("signed char", std::numeric_limits<signed char>::min(), std::numeric_limits<signed char>::max())); }
224  void getValue(unsigned char& value) const
225  { value = static_cast<signed char>(_getUInt("unsigned char", std::numeric_limits<unsigned char>::max())); }
226  void getValue(short& value) const
227  { value = static_cast<short>(_getInt("short", std::numeric_limits<short>::min(), std::numeric_limits<short>::max())); }
228  void getValue(unsigned short& value) const
229  { value = static_cast<unsigned short>(_getUInt("unsigned short", std::numeric_limits<unsigned short>::max())); }
230  void getValue(int& value) const
231  { value = static_cast<int>(_getInt("int", std::numeric_limits<int>::min(), std::numeric_limits<int>::max())); }
232  void getValue(unsigned int& value) const
233  { value = static_cast<unsigned int>(_getUInt("unsigned int", std::numeric_limits<unsigned int>::max())); }
234  void getValue(long& value) const
235  { value = static_cast<long>(_getInt("long", std::numeric_limits<long>::min(), std::numeric_limits<long>::max())); }
236  void getValue(unsigned long& value) const
237  { value = static_cast<unsigned long>(_getUInt("unsigned long", std::numeric_limits<unsigned long>::max())); }
238 #ifdef HAVE_LONG_LONG
239  void getValue(long long& value) const
240  { value = static_cast<long long>(_getInt("long long", std::numeric_limits<long long>::min(), std::numeric_limits<long long>::max())); }
241 #endif
242 #ifdef HAVE_UNSIGNED_LONG_LONG
243  void getValue(unsigned long long& value) const
244  { value = static_cast<unsigned long long>(_getUInt("unsigned long long", std::numeric_limits<unsigned long long>::max())); }
245 #endif
246  void getValue(float& value) const
247  { value = static_cast<float>(_getFloat("float", static_cast<long double>(std::numeric_limits<float>::max())*1.0000000000001)); }
248  void getValue(double& value) const
249  { value = static_cast<double>(_getFloat("double", static_cast<long double>(std::numeric_limits<double>::max())*1.0000000000001)); }
250  void getValue(long double& value) const
251  { value = static_cast<long double>(_getFloat("long double", std::numeric_limits<long double>::max())); }
252 
255  template <typename T>
256  SerializationInfo& addValue(const std::string& name, const T& value)
257  {
258  SerializationInfo& info = this->addMember(name);
259  info.setValue(value);
260  return info;
261  }
262 
265  SerializationInfo& addMember(const std::string& name = std::string());
266 
269  SerializationInfo& getAddMember(const std::string& name)
270  {
271  SerializationInfo* si = findMember(name);
272  if (si == 0)
273  return addMember(name);
274  return *si;
275  }
276 
281  const SerializationInfo& getMember(const std::string& name) const;
282 
287  const SerializationInfo& getMember(unsigned idx) const;
288 
294  template <typename T>
295  bool getMember(const std::string& name, T& value) const
296  {
297  const SerializationInfo* si = findMember(name);
298  if (si == 0)
299  return false;
300  *si >>= value;
301  return true;
302  }
303 
309  const SerializationInfo* findMember(const std::string& name) const;
310 
316  SerializationInfo* findMember(const std::string& name);
317 
318  size_t memberCount() const
319  {
320  return nodes().size();
321  }
322 
324  {
325  return nodes().begin();
326  }
327 
329  {
330  return nodes().end();
331  }
332 
334  {
335  return nodes().begin();
336  }
337 
339  {
340  return nodes().end();
341  }
342 
343  void clear();
344 
345  void swap(SerializationInfo& si);
346 
347  bool isNull() const { return _t == t_none && _category == Void; }
348  bool isString() const { return _t == t_string; }
349  bool isString8() const { return _t == t_string8; }
350  bool isChar() const { return _t == t_char; }
351  bool isBool() const { return _t == t_bool; }
352  bool isInt() const { return _t == t_int; }
353  bool isUInt() const { return _t == t_uint; }
354  bool isFloat() const { return _t == t_float; }
355 
356  void dump(std::ostream& out, const std::string& prefix = std::string()) const;
357 
358  private:
359  Category _category;
360  std::string _name;
361  std::string _type;
362 
363  void _releaseValue();
364  void _setString(const String& value);
365  void _setString8(const std::string& value);
366  void _setString8(const char* value);
367  void _setChar(char value);
368  void _setBool(bool value);
369  void _setInt(int_type value);
370  void _setUInt(unsigned_type value);
371  void _setFloat(long double value);
372 
373  bool _getBool() const;
374  wchar_t _getWChar() const;
375  char _getChar() const;
376  int_type _getInt(const char* type, int_type min, int_type max) const;
377  unsigned_type _getUInt(const char* type, unsigned_type max) const;
378  long double _getFloat(const char* type, long double max) const;
379  Nodes& nodes();
380  const Nodes& nodes() const;
381  // assignment without name
382  void assignData(const SerializationInfo& si);
383 
384  union U
385  {
386  char _s[sizeof(String) >= sizeof(std::string) ? sizeof(String) : sizeof(std::string)];
387  char _c;
388  bool _b;
389  int_type _i;
390  unsigned_type _u;
391  long double _f;
392  } _u;
393 
394  String* _StringPtr() { return reinterpret_cast<String*>(&_u); }
395  String& _String() { return *_StringPtr(); }
396  const String* _StringPtr() const { return reinterpret_cast<const String*>(&_u); }
397  const String& _String() const { return *_StringPtr(); }
398  std::string* _String8Ptr() { return reinterpret_cast<std::string*>(&_u); }
399  std::string& _String8() { return *_String8Ptr(); }
400  const std::string* _String8Ptr() const { return reinterpret_cast<const std::string*>(&_u); }
401  const std::string& _String8() const { return *_String8Ptr(); }
402 
403  enum T
404  {
405  t_none,
406  t_string,
407  t_string8,
408  t_char,
409  t_bool,
410  t_int,
411  t_uint,
412  t_float
413  } _t;
414 
415  Nodes* _nodes; // objects/arrays
416 };
417 
418 
420 : _category(Void),
421  _t(t_none),
422  _nodes(0)
423 { }
424 
425 
427 {
428  ssi = si;
429 }
430 
431 
432 void operator <<=(SerializationInfo& si, const SerializationInfo& ssi);
433 
434 
435 inline void operator >>=(const SerializationInfo& si, bool& n)
436 {
437  si.getValue(n);
438 }
439 
440 
441 inline void operator <<=(SerializationInfo& si, bool n)
442 {
443  si.setValue(n);
444  si.setTypeName("bool");
445 }
446 
447 
448 inline void operator >>=(const SerializationInfo& si, signed char& n)
449 {
450  si.getValue(n);
451 }
452 
453 
454 inline void operator <<=(SerializationInfo& si, signed char n)
455 {
456  si.setValue(n);
457  si.setTypeName("char");
458 }
459 
460 
461 inline void operator >>=(const SerializationInfo& si, unsigned char& n)
462 {
463  si.getValue(n);
464 }
465 
466 
467 inline void operator <<=(SerializationInfo& si, unsigned char n)
468 {
469  si.setValue(n);
470  si.setTypeName("char");
471 }
472 
473 
474 inline void operator >>=(const SerializationInfo& si, char& n)
475 {
476  si.getValue(n);
477 }
478 
479 
480 inline void operator <<=(SerializationInfo& si, char n)
481 {
482  si.setValue(n);
483  si.setTypeName("char");
484 }
485 
486 
487 inline void operator >>=(const SerializationInfo& si, short& n)
488 {
489  si.getValue(n);
490 }
491 
492 
493 inline void operator <<=(SerializationInfo& si, short n)
494 {
495  si.setValue(n);
496  si.setTypeName("int");
497 }
498 
499 
500 inline void operator >>=(const SerializationInfo& si, unsigned short& n)
501 {
502  si.getValue(n);
503 }
504 
505 
506 inline void operator <<=(SerializationInfo& si, unsigned short n)
507 {
508  si.setValue(n);
509  si.setTypeName("int");
510 }
511 
512 
513 inline void operator >>=(const SerializationInfo& si, int& n)
514 {
515  si.getValue(n);
516 }
517 
518 
519 inline void operator <<=(SerializationInfo& si, int n)
520 {
521  si.setValue(n);
522  si.setTypeName("int");
523 }
524 
525 
526 inline void operator >>=(const SerializationInfo& si, unsigned int& n)
527 {
528  si.getValue(n);
529 }
530 
531 
532 inline void operator <<=(SerializationInfo& si, unsigned int n)
533 {
534  si.setValue(n);
535  si.setTypeName("int");
536 }
537 
538 
539 inline void operator >>=(const SerializationInfo& si, long& n)
540 {
541  si.getValue(n);
542 }
543 
544 
545 inline void operator <<=(SerializationInfo& si, long n)
546 {
547  si.setValue(n);
548  si.setTypeName("int");
549 }
550 
551 
552 inline void operator >>=(const SerializationInfo& si, unsigned long& n)
553 {
554  si.getValue(n);
555 }
556 
557 
558 inline void operator <<=(SerializationInfo& si, unsigned long n)
559 {
560  si.setValue(n);
561  si.setTypeName("int");
562 }
563 
564 
565 #ifdef HAVE_LONG_LONG
566 
567 inline void operator >>=(const SerializationInfo& si, long long& n)
568 {
569  si.getValue(n);
570 }
571 
572 
573 inline void operator <<=(SerializationInfo& si, long long n)
574 {
575  si.setValue(n);
576  si.setTypeName("int");
577 }
578 
579 #endif
580 
581 
582 #ifdef HAVE_UNSIGNED_LONG_LONG
583 
584 inline void operator >>=(const SerializationInfo& si, unsigned long long& n)
585 {
586  si.getValue(n);
587 }
588 
589 
590 inline void operator <<=(SerializationInfo& si, unsigned long long n)
591 {
592  si.setValue(n);
593  si.setTypeName("int");
594 }
595 
596 #endif
597 
598 
599 inline void operator >>=(const SerializationInfo& si, float& n)
600 {
601  si.getValue(n);
602 }
603 
604 
605 inline void operator <<=(SerializationInfo& si, float n)
606 {
607  si.setValue(n);
608  si.setTypeName("double");
609 }
610 
611 
612 inline void operator >>=(const SerializationInfo& si, double& n)
613 {
614  si.getValue(n);
615 }
616 
617 
618 inline void operator <<=(SerializationInfo& si, double n)
619 {
620  si.setValue(n);
621  si.setTypeName("double");
622 }
623 
624 
625 inline void operator >>=(const SerializationInfo& si, std::string& n)
626 {
627  si.getValue(n);
628 }
629 
630 
631 inline void operator <<=(SerializationInfo& si, const std::string& n)
632 {
633  si.setValue(n);
634  si.setTypeName("string");
635 }
636 
637 
638 inline void operator <<=(SerializationInfo& si, const char* n)
639 {
640  si.setValue(n);
641  si.setTypeName("string");
642 }
643 
644 
645 inline void operator >>=(const SerializationInfo& si, String& n)
646 {
647  si.getValue(n);
648 }
649 
650 
651 inline void operator <<=(SerializationInfo& si, const String& n)
652 {
653  si.setValue(n);
654  si.setTypeName("string");
655 }
656 
657 
658 inline void operator >>=(const SerializationInfo& si, Char& n)
659 {
660  si.getValue(n);
661 }
662 
663 
664 inline void operator <<=(SerializationInfo& si, const Char& n)
665 {
666  si.setValue(n);
667  si.setTypeName("char");
668 }
669 
670 
671 template <typename T, typename A>
672 inline void operator >>=(const SerializationInfo& si, std::vector<T, A>& vec)
673 {
674  vec.clear();
675  vec.reserve(si.memberCount());
676  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
677  {
678  vec.resize( vec.size() + 1 );
679  *it >>= vec.back();
680  }
681 }
682 
683 
684 template <typename T, typename A>
685 inline void operator <<=(SerializationInfo& si, const std::vector<T, A>& vec)
686 {
687  typename std::vector<T, A>::const_iterator it;
688 
689  for(it = vec.begin(); it != vec.end(); ++it)
690  {
691  SerializationInfo& newSi = si.addMember();
692  newSi <<= *it;
693  }
694 
695  si.setTypeName("array");
696  si.setCategory(SerializationInfo::Array);
697 }
698 
699 
700 template <typename T, typename A>
701 inline void operator >>=(const SerializationInfo& si, std::list<T, A>& list)
702 {
703  list.clear();
704  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
705  {
706  list.resize( list.size() + 1 );
707  *it >>= list.back();
708  }
709 }
710 
711 
712 template <typename T, typename A>
713 inline void operator <<=(SerializationInfo& si, const std::list<T, A>& list)
714 {
715  typename std::list<T, A>::const_iterator it;
716 
717  for(it = list.begin(); it != list.end(); ++it)
718  {
719  SerializationInfo& newSi = si.addMember();
720  newSi <<= *it;
721  }
722 
723  si.setTypeName("list");
724  si.setCategory(SerializationInfo::Array);
725 }
726 
727 
728 template <typename T, typename A>
729 inline void operator >>=(const SerializationInfo& si, std::deque<T, A>& deque)
730 {
731  deque.clear();
732  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
733  {
734  deque.resize( deque.size() + 1 );
735  *it >>= deque.back();
736  }
737 }
738 
739 
740 template <typename T, typename A>
741 inline void operator <<=(SerializationInfo& si, const std::deque<T, A>& deque)
742 {
743  typename std::deque<T, A>::const_iterator it;
744 
745  for(it = deque.begin(); it != deque.end(); ++it)
746  {
747  SerializationInfo& newSi = si.addMember();
748  newSi <<= *it;
749  }
750 
751  si.setTypeName("deque");
752  si.setCategory(SerializationInfo::Array);
753 }
754 
755 
756 template <typename T, typename C, typename A>
757 inline void operator >>=(const SerializationInfo& si, std::set<T, C, A>& set)
758 {
759  set.clear();
760  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
761  {
762  T t;
763  *it >>= t;
764  set.insert(t);
765  }
766 }
767 
768 
769 template <typename T, typename C, typename A>
770 inline void operator <<=(SerializationInfo& si, const std::set<T, C, A>& set)
771 {
772  typename std::set<T, C, A>::const_iterator it;
773 
774  for(it = set.begin(); it != set.end(); ++it)
775  {
776  SerializationInfo& newSi = si.addMember();
777  newSi <<= *it;
778  }
779 
780  si.setTypeName("set");
781  si.setCategory(SerializationInfo::Array);
782 }
783 
784 
785 template <typename T, typename C, typename A>
786 inline void operator >>=(const SerializationInfo& si, std::multiset<T, C, A>& multiset)
787 {
788  multiset.clear();
789  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
790  {
791  T t;
792  *it >>= t;
793  multiset.insert(t);
794  }
795 }
796 
797 
798 template <typename T, typename C, typename A>
799 inline void operator <<=(SerializationInfo& si, const std::multiset<T, C, A>& multiset)
800 {
801  typename std::multiset<T, C, A>::const_iterator it;
802 
803  for(it = multiset.begin(); it != multiset.end(); ++it)
804  {
805  SerializationInfo& newSi = si.addMember();
806  newSi <<= *it;
807  }
808 
809  si.setTypeName("multiset");
810  si.setCategory(SerializationInfo::Array);
811 }
812 
813 
814 template <typename A, typename B>
815 inline void operator >>=(const SerializationInfo& si, std::pair<A, B>& p)
816 {
817  si.getMember("first") >>= p.first;
818  si.getMember("second") >>= p.second;
819 }
820 
821 
822 template <typename A, typename B>
823 inline void operator <<=(SerializationInfo& si, const std::pair<A, B>& p)
824 {
825  si.setTypeName("pair");
826  si.addMember("first") <<= p.first;
827  si.addMember("second") <<= p.second;
828 }
829 
830 
831 template <typename K, typename V, typename P, typename A>
832 inline void operator >>=(const SerializationInfo& si, std::map<K, V, P, A>& map)
833 {
834  map.clear();
835  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
836  {
837  typename std::pair<K, V> v;
838  *it >>= v;
839  typename std::map<K, V, P, A>::value_type vv(v.first, v.second);
840  map.insert(vv);
841  }
842 }
843 
844 
845 template <typename K, typename V, typename P, typename A>
846 inline void operator <<=(SerializationInfo& si, const std::map<K, V, P, A>& map)
847 {
848  typename std::map<K, V, P, A>::const_iterator it;
849 
850  for(it = map.begin(); it != map.end(); ++it)
851  {
852  SerializationInfo& newSi = si.addMember();
853  newSi <<= *it;
854  }
855 
856  si.setTypeName("map");
857  si.setCategory(SerializationInfo::Array);
858 }
859 
860 
861 template <typename K, typename V, typename P, typename A>
862 inline void operator >>=(const SerializationInfo& si, std::multimap<K, V, P, A>& multimap)
863 {
864  multimap.clear();
865  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
866  {
867  typename std::pair<K, V> v;
868  *it >>= v;
869  typename std::multimap<K, V, P, A>::value_type vv(v.first, v.second);
870  multimap.insert(vv);
871  }
872 }
873 
874 
875 template <typename T, typename C, typename P, typename A>
876 inline void operator <<=(SerializationInfo& si, const std::multimap<T, C, P, A>& multimap)
877 {
878  typename std::multimap<T, C, P, A>::const_iterator it;
879 
880  for(it = multimap.begin(); it != multimap.end(); ++it)
881  {
882  SerializationInfo& newSi = si.addMember();
883  newSi <<= *it;
884  }
885 
886  si.setTypeName("multimap");
887  si.setCategory(SerializationInfo::Array);
888 }
889 
890 #if __cplusplus >= 201103L
891 
892 template <typename T, typename A>
893 inline void operator >>=(const SerializationInfo& si, std::forward_list<T, A>& list)
894 {
895  list.clear();
896  for (size_t n = si.memberCount(); n > 0; --n)
897  {
898  list.push_front(T());
899  si.getMember(n-1) >>= list.front();
900  }
901 }
902 
903 
904 template <typename T, typename A>
905 inline void operator <<=(SerializationInfo& si, const std::forward_list<T, A>& list)
906 {
907  typename std::forward_list<T, A>::const_iterator it;
908 
909  for(it = list.begin(); it != list.end(); ++it)
910  {
911  SerializationInfo& newSi = si.addMember();
912  newSi <<= *it;
913  }
914 
915  si.setTypeName("list");
916  si.setCategory(SerializationInfo::Array);
917 }
918 
919 
920 template <typename T, typename H, typename P, typename A>
921 inline void operator >>=(const SerializationInfo& si, std::unordered_set<T, H, P, A>& unordered_set)
922 {
923  unordered_set.clear();
924  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
925  {
926  T t;
927  *it >>= t;
928  unordered_set.insert(t);
929  }
930 }
931 
932 
933 template <typename T, typename H, typename P, typename A>
934 inline void operator <<=(SerializationInfo& si, const std::unordered_set<T, H, P, A>& unordered_set)
935 {
936  typename std::unordered_set<T, H, P, A>::const_iterator it;
937 
938  for(it = unordered_set.begin(); it != unordered_set.end(); ++it)
939  {
940  SerializationInfo& newSi = si.addMember();
941  newSi <<= *it;
942  }
943 
944  si.setTypeName("set");
945  si.setCategory(SerializationInfo::Array);
946 }
947 
948 
949 template <typename T, typename H, typename P, typename A>
950 inline void operator >>=(const SerializationInfo& si, std::unordered_multiset<T, H, P, A>& unordered_multiset)
951 {
952  unordered_multiset.clear();
953  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
954  {
955  T t;
956  *it >>= t;
957  unordered_multiset.insert(t);
958  }
959 }
960 
961 
962 template <typename T, typename H, typename P, typename A>
963 inline void operator <<=(SerializationInfo& si, const std::unordered_multiset<T, H, P, A>& unordered_multiset)
964 {
965  typename std::unordered_multiset<T, H, P, A>::const_iterator it;
966 
967  for(it = unordered_multiset.begin(); it != unordered_multiset.end(); ++it)
968  {
969  SerializationInfo& newSi = si.addMember();
970  newSi <<= *it;
971  }
972 
973  si.setTypeName("set");
974  si.setCategory(SerializationInfo::Array);
975 }
976 
977 
978 template <typename K, typename V, typename H, typename P, typename A>
979 inline void operator >>=(const SerializationInfo& si, std::unordered_map<K, V, H, P, A>& unordered_map)
980 {
981  unordered_map.clear();
982  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
983  {
984  typename std::pair<K, V> v;
985  *it >>= v;
986  typename std::unordered_map<K, V, H, P, A>::value_type vv(v.first, v.second);
987  unordered_map.insert(vv);
988  }
989 }
990 
991 
992 template <typename K, typename V, typename H, typename P, typename A>
993 inline void operator <<=(SerializationInfo& si, const std::unordered_map<K, V, H, P, A>& unordered_map)
994 {
995  typename std::unordered_map<K, V, H, P, A>::const_iterator it;
996 
997  for(it = unordered_map.begin(); it != unordered_map.end(); ++it)
998  {
999  SerializationInfo& newSi = si.addMember();
1000  newSi <<= *it;
1001  }
1002 
1003  si.setTypeName("map");
1004  si.setCategory(SerializationInfo::Array);
1005 }
1006 
1007 
1008 template <typename K, typename V, typename H, typename P, typename A>
1009 inline void operator >>=(const SerializationInfo& si, std::unordered_multimap<K, V, H, P, A>& unordered_multimap)
1010 {
1011  unordered_multimap.clear();
1012  for(SerializationInfo::ConstIterator it = si.begin(); it != si.end(); ++it)
1013  {
1014  typename std::pair<K, V> v;
1015  *it >>= v;
1016  typename std::unordered_multimap<K, V, H, P, A>::value_type vv(v.first, v.second);
1017  unordered_multimap.insert(vv);
1018  }
1019 }
1020 
1021 
1022 template <typename K, typename V, typename H, typename P, typename A>
1023 inline void operator <<=(SerializationInfo& si, const std::unordered_multimap<K, V, H, P, A>& unordered_multimap)
1024 {
1025  typename std::unordered_multimap<K, V, H, P, A>::const_iterator it;
1026 
1027  for(it = unordered_multimap.begin(); it != unordered_multimap.end(); ++it)
1028  {
1029  SerializationInfo& newSi = si.addMember();
1030  newSi <<= *it;
1031  }
1032 
1033  si.setTypeName("map");
1034  si.setCategory(SerializationInfo::Array);
1035 }
1036 
1037 
1038 #endif // __cplusplus >= 201103L
1039 
1040 inline std::ostream& operator<< (std::ostream& out, const SerializationInfo& si)
1041 {
1042  si.dump(out);
1043  return out;
1044 }
1045 
1046 } // namespace cxxtools
1047 
1048 
1049 #endif