Merge branch 'charm' of charmgit:charm into charm
[charm.git] / src / util / pup_stl.h
1 /*
2 Pup routines for STL classes.
3
4 After including this header, you can parameter-marshall
5 an variable consisting of STL vectors, lists, maps,
6 strings, or pairs.
7
8 This includes variables of type "std::list<int>", or even
9 "std::map<double, std::vector<std::string> >".
10
11 NOT included are the rarer types like valarray or slice, 
12 vector<bool>, set or multiset, or deque.
13
14 Orion Sky Lawlor, olawlor@acm.org, 7/22/2002
15 */
16 #ifndef _UIUC_CHARM_PUP_STL_H
17 #define _UIUC_CHARM_PUP_STL_H
18
19 /*It's kind of annoying that we have to drag all these headers in
20   just so the std:: parameter declarations will compile.
21  */
22 #include <set>
23 #include <vector>
24 #include <list>
25 #include <map>
26 #include <string>
27 #include <complex>
28 #include <utility> /*for std::pair*/
29 #include "pup.h"
30
31 /*************** Simple classes ***************/
32 // Non-const version is required for puping std::pair
33 template <class A,class B>
34 inline void operator|(PUP::er &p,typename std::pair<A,B> &v)
35 {
36   p.syncComment(PUP::sync_index);
37   p|v.first;
38   p.syncComment(PUP::sync_item);
39   p|v.second;
40 }
41 // Const version is required for puping std::map
42 template <class A,class B> 
43 inline void operator|(PUP::er &p,typename std::pair<const A,B> &v)
44 {
45   p.syncComment(PUP::sync_index);
46   p|*(A *)&v.first; /* cast away constness on A */
47   p.syncComment(PUP::sync_item);
48   p|v.second;
49 }
50 template <class T>
51 inline void operator|(PUP::er &p,std::complex<T> &v)
52 {
53   T re=v.real(), im=v.imag();
54   p|re; p|im;
55   v=std::complex<T>(re,im);
56 }
57 template <class charType> 
58 inline void operator|(PUP::er &p,typename std::basic_string<charType> &v)
59 {
60   int nChar=v.length();
61   p|nChar;
62   if (p.isUnpacking()) { //Unpack to temporary buffer
63     charType *buf=new charType[nChar];
64     p(buf,nChar);
65     v=std::basic_string<charType>(buf,nChar);
66     delete[] buf;
67   }
68   else /*packing*/ { //Do packing in-place from data
69     //Have to cast away constness here
70     p((charType *)v.data(),nChar);
71   }
72 }
73 inline void operator|(PUP::er &p,std::string &v)
74 {
75   p.syncComment(PUP::sync_begin_object,"std::string");
76   int nChar=v.length();
77   p|nChar;
78   if (p.isUnpacking()) { //Unpack to temporary buffer
79     char *buf=new char[nChar];
80     p(buf,nChar);
81     v=std::basic_string<char>(buf,nChar);
82     delete[] buf;
83   }
84   else /*packing*/ { //Do packing in-place from data
85     //Have to cast away constness here
86     p((char *)v.data(),nChar);
87   }
88   p.syncComment(PUP::sync_end_object);
89 }
90
91 /**************** Containers *****************/
92
93 //Impl. util: pup the length of a container
94 template <class container>
95 inline int PUP_stl_container_size(PUP::er &p,container &c) {
96   int nElem=c.size();
97   p|nElem;
98   return nElem; 
99 }
100
101 //Impl. util: pup each current item of a container (no allocation)
102 template <class container, class dtype>
103 inline void PUP_stl_container_items(PUP::er &p,container &c) {
104   for (typename container::iterator it=c.begin();
105        it!=c.end();
106        ++it) {
107     p.syncComment(PUP::sync_item);
108     // Cast away the constness (needed for std::set)
109     p|*(dtype *)&(*it);
110   }
111 }
112
113 template <class container,class dtype>
114 inline void PUP_stl_container(PUP::er &p,container &c) {
115   p.syncComment(PUP::sync_begin_array);
116   int nElem=PUP_stl_container_size(p,c);
117   if (p.isUnpacking()) 
118   { //Unpacking: Extract each element and push_back:
119     c.resize(0);
120     for (int i=0;i<nElem;i++) {
121       p.syncComment(PUP::sync_item);
122       dtype n;
123       p|n;
124       c.push_back(n);
125     } 
126   }
127   else PUP_stl_container_items<container, dtype>(p,c);
128   p.syncComment(PUP::sync_end_array);
129 }
130 //Map objects don't have a "push_back", while vector and list
131 //  don't have an "insert", so PUP_stl_map isn't PUP_stl_container
132 template <class container,class dtype>
133 inline void PUP_stl_map(PUP::er &p,container &c) {
134   p.syncComment(PUP::sync_begin_list);
135   int nElem=PUP_stl_container_size(p,c);
136   if (p.isUnpacking()) 
137   { //Unpacking: Extract each element and insert:
138     for (int i=0;i<nElem;i++) {
139       dtype n;
140       p|n;
141       c.insert(n);
142     } 
143   }
144   else PUP_stl_container_items<container, dtype>(p,c);
145   p.syncComment(PUP::sync_end_list);
146 }
147
148 template <class T> 
149 inline void operator|(PUP::er &p,typename std::vector<T> &v)
150   { PUP_stl_container<std::vector<T>,T>(p,v); }
151 template <class T> 
152 inline void operator|(PUP::er &p,typename std::list<T> &v)
153   { PUP_stl_container<std::list<T>,T>(p,v); }
154
155 template <class V,class T,class Cmp> 
156 inline void operator|(PUP::er &p,typename std::map<V,T,Cmp> &m)
157   { PUP_stl_map<std::map<V,T,Cmp>,std::pair<const V,T> >(p,m); }
158 template <class V,class T,class Cmp> 
159 inline void operator|(PUP::er &p,typename std::multimap<V,T,Cmp> &m)
160   { PUP_stl_map<std::multimap<V,T,Cmp>,std::pair<const V,T> >(p,m); }
161 template <class T>
162 inline void operator|(PUP::er &p,typename std::set<T> &m)
163   { PUP_stl_map<std::set<T>,T >(p,m); }
164
165 #endif