silly hack to get around the compiler bug for old SUN CC compiler.
[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
33 // Non-const version is required for puping std::pair
34 template <class A,class B>
35 inline void operator|(PUP::er &p,typename std::pair<A,B> &v)
36 {
37   p.syncComment(PUP::sync_index);
38   p|v.first;
39   p.syncComment(PUP::sync_item);
40   p|v.second;
41 }
42 // Const version is required for puping std::map
43 template <class A,class B> 
44 inline void operator|(PUP::er &p,typename std::pair<const A,B> &v)
45 {
46   p.syncComment(PUP::sync_index);
47   p|*(A *)&v.first; /* cast away constness on A */
48   p.syncComment(PUP::sync_item);
49   p|v.second;
50 }
51 template <class T>
52 inline void operator|(PUP::er &p,std::complex<T> &v)
53 {
54   T re=v.real(), im=v.imag();
55   p|re; p|im;
56   v=std::complex<T>(re,im);
57 }
58 template <class charType> 
59 inline void operator|(PUP::er &p,typename std::basic_string<charType> &v)
60 {
61   int nChar=v.length();
62   p|nChar;
63   if (p.isUnpacking()) { //Unpack to temporary buffer
64     charType *buf=new charType[nChar];
65     p(buf,nChar);
66     v=std::basic_string<charType>(buf,nChar);
67     delete[] buf;
68   }
69   else /*packing*/ { //Do packing in-place from data
70     //Have to cast away constness here
71     p((charType *)v.data(),nChar);
72   }
73 }
74 inline void operator|(PUP::er &p,std::string &v)
75 {
76   p.syncComment(PUP::sync_begin_object,"std::string");
77   int nChar=v.length();
78   p|nChar;
79   if (p.isUnpacking()) { //Unpack to temporary buffer
80     char *buf=new char[nChar];
81     p(buf,nChar);
82     v=std::basic_string<char>(buf,nChar);
83     delete[] buf;
84   }
85   else /*packing*/ { //Do packing in-place from data
86     //Have to cast away constness here
87     p((char *)v.data(),nChar);
88   }
89   p.syncComment(PUP::sync_end_object);
90 }
91
92 /**************** Containers *****************/
93
94 //Impl. util: pup the length of a container
95 template <class container>
96 inline int PUP_stl_container_size(PUP::er &p,container &c) {
97   int nElem=c.size();
98   p|nElem;
99   return nElem; 
100 }
101
102 //Impl. util: pup each current item of a container (no allocation)
103 template <class container, class dtype>
104 inline void PUP_stl_container_items(PUP::er &p,container &c) {
105   for (typename container::iterator it=c.begin();
106        it!=c.end();
107        ++it) {
108     p.syncComment(PUP::sync_item);
109     // Cast away the constness (needed for std::set)
110     p|*(dtype *)&(*it);
111   }
112 }
113
114 template <class container,class dtype>
115 inline void PUP_stl_container(PUP::er &p,container &c) {
116   p.syncComment(PUP::sync_begin_array);
117   int nElem=PUP_stl_container_size(p,c);
118   if (p.isUnpacking()) 
119   { //Unpacking: Extract each element and push_back:
120     c.resize(0);
121     for (int i=0;i<nElem;i++) {
122       p.syncComment(PUP::sync_item);
123       dtype n;
124       p|n;
125       c.push_back(n);
126     } 
127   }
128   else PUP_stl_container_items<container, dtype>(p,c);
129   p.syncComment(PUP::sync_end_array);
130 }
131 //Map objects don't have a "push_back", while vector and list
132 //  don't have an "insert", so PUP_stl_map isn't PUP_stl_container
133 template <class container,class dtype>
134 inline void PUP_stl_map(PUP::er &p,container &c) {
135   p.syncComment(PUP::sync_begin_list);
136   int nElem=PUP_stl_container_size(p,c);
137   if (p.isUnpacking()) 
138   { //Unpacking: Extract each element and insert:
139     for (int i=0;i<nElem;i++) {
140       dtype n;
141       p|n;
142       c.insert(n);
143     } 
144   }
145   else PUP_stl_container_items<container, dtype>(p,c);
146   p.syncComment(PUP::sync_end_list);
147 }
148
149 template <class T> 
150 inline void operator|(PUP::er &p,typename std::vector<T> &v)
151   { PUP_stl_container<std::vector<T>,T>(p,v); }
152 template <class T> 
153 inline void operator|(PUP::er &p,typename std::list<T> &v)
154   { PUP_stl_container<std::list<T>,T>(p,v); }
155
156 template <class V,class T,class Cmp> 
157 inline void operator|(PUP::er &p,typename std::map<V,T,Cmp> &m)
158   //{ PUP_stl_map<std::map<V,T,Cmp>,std::pair<const V,T> >(p,m); }    // 'const' confuses old version of a SUN CC compiler
159   { PUP_stl_map<std::map<V,T,Cmp>,std::pair<V,T> >(p,m); }
160 template <class V,class T,class Cmp> 
161 inline void operator|(PUP::er &p,typename std::multimap<V,T,Cmp> &m)
162   { PUP_stl_map<std::multimap<V,T,Cmp>,std::pair<const V,T> >(p,m); }
163 template <class T>
164 inline void operator|(PUP::er &p,typename std::set<T> &m)
165   { PUP_stl_map<std::set<T>,T >(p,m); }
166
167 #endif