00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __archive_hpp
00021 #define __archive_hpp
00022
00023 #include <mynahsa/spimpl.hpp>
00024
00025 #include <string>
00026 #include <vector>
00027 #include <list>
00028 #include <utility>
00029 #include <map>
00030 #include <set>
00031
00032 #include <mynahsa/exceptionbase.hpp>
00033
00034 #include <mynahsa/type_traits.hpp>
00035
00036 namespace MynahSA {
00037 class IoBase;
00038
00039
00043 class Archive {
00044 public:
00045
00050 class ArchiveConstructor {
00051 public:
00053 ArchiveConstructor() {
00054 }
00055
00057 ~ArchiveConstructor() {
00058 }
00059
00061 virtual SHARED_PTR<IoBase> operator()() const = 0;
00062 };
00063
00064
00066 Archive();
00067
00069 Archive(const Archive& ar);
00070
00072 Archive(const std::map<std::string, SHARED_PTR<Archive::ArchiveConstructor> >& cons);
00073
00075 virtual ~Archive();
00076
00077
00083 void registerConstructor(const std::string& name, const SHARED_PTR<ArchiveConstructor>& cons) {
00084 _constructors[name] = cons;
00085 }
00086
00088 const std::map<std::string, SHARED_PTR<ArchiveConstructor> >& getConstructors() const {
00089 return _constructors;
00090 }
00091
00092
00093
00095 virtual Archive& operator&(long long&) = 0;
00096
00098 virtual Archive& operator&(unsigned long long&) = 0;
00099
00101 virtual Archive& operator&(unsigned int&) = 0;
00102
00104 virtual Archive& operator&(int&) = 0;
00105
00107 virtual Archive& operator&(short&) = 0;
00108
00110 virtual Archive& operator&(unsigned short&) = 0;
00111
00113 virtual Archive& operator&(char&) = 0;
00114
00116 virtual Archive& operator&(unsigned char&) = 0;
00117
00119 virtual Archive& operator&(bool&) = 0;
00120
00122 virtual Archive& operator&(float&) = 0;
00123
00125 virtual Archive& operator&(double&) = 0;
00126
00128 virtual Archive& operator&(std::string&) = 0;
00129
00131 template<class T>
00132 Archive& operator&(std::vector<T>& v) {
00133
00134
00135 int size = v.size();
00136
00137
00138
00139 (*this) & size;
00140
00141 if (size > v.size()) {
00142 v.resize(size);
00143 }
00144
00145 for (unsigned int i=0; i<v.size(); i++) {
00146 (*this) & v[i];
00147 }
00148 return *this;
00149 }
00150
00152 template<class T>
00153 Archive& operator&(std::list<T>& l) {
00154
00155
00156
00157
00158
00159 int size = l.size();
00160 (*this) & size;
00161 if (size > l.size()) {
00162 l.resize(size);
00163 }
00164 for (typename std::list<T>::iterator lit = l.begin();
00165 lit != l.end();
00166 ++lit) {
00167 (*this) & (*lit);
00168 }
00169 return *this;
00170 }
00171
00173 template<class a_type, class b_type>
00174 Archive& operator&(std::pair<a_type, b_type>& p) {
00175 (*this) & p.first;
00176 (*this) & p.second;
00177 return *this;
00178 }
00179
00180
00182 template<class value_type>
00183 Archive& operator&(std::set<value_type>& s) {
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 if (getArchiveMode() == ARCHIVE_READ) {
00194
00195 s.clear();
00196
00197 int size = 0;
00198 (*this) & size;
00199
00200 for (unsigned int i=0; i < size; i++) {
00201
00202 value_type element;
00203 (*this) & element;
00204
00205 s.insert(element);
00206 }
00207 } else {
00208
00209 int size = s.size();
00210 (*this) & size;
00211
00212 for (typename std::set<value_type>::const_iterator sit = s.begin();
00213 sit != s.end();
00214 ++sit) {
00215 value_type element = (*sit);
00216 (*this) & element;
00217 }
00218 }
00219 return *this;
00220 }
00221
00222
00224 template<class index_type, class value_type>
00225 Archive& operator&(std::map<index_type, value_type>& m) {
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 if (getArchiveMode() == ARCHIVE_READ) {
00236
00237 m.clear();
00238
00239 int size = 0;
00240 (*this) & size;
00241
00242 for (unsigned int i=0; i < size; i++) {
00243
00244 std::pair<index_type, value_type> element;
00245 (*this) & element;
00246
00247 m.insert(element);
00248 }
00249 } else {
00250
00251 int size = m.size();
00252 (*this) & size;
00253
00254 for (typename std::map<index_type, value_type>::const_iterator mit = m.begin();
00255 mit != m.end();
00256 ++mit) {
00257
00258
00259
00260
00261 std::pair<index_type, value_type> element( (*mit).first, (*mit).second );
00262 (*this) & element;
00263 }
00264 }
00265 return *this;
00266 }
00267
00269 template<class index_type, class value_type>
00270 Archive& operator&(std::multimap<index_type, value_type>& m) {
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 if (getArchiveMode() == ARCHIVE_READ) {
00281
00282 m.clear();
00283
00284 int size = 0;
00285 (*this) & size;
00286
00287 for (unsigned int i=0; i < size; i++) {
00288
00289 std::pair<index_type, value_type> element;
00290 (*this) & element;
00291
00292 std::pair<const index_type, value_type> cElement(element.first, element.second);
00293 m.insert(cElement);
00294 }
00295 } else {
00296
00297 int size = m.size();
00298 (*this) & size;
00299
00300 for (typename std::multimap<index_type, value_type>::const_iterator mit = m.begin();
00301 mit != m.end();
00302 ++mit) {
00303
00304
00305
00306
00307 std::pair<index_type, value_type> element( (*mit).first, (*mit).second );
00308 (*this) & element;
00309 }
00310 }
00311 return *this;
00312 }
00313
00314
00315
00316
00321 template<class T>
00322 Archive& operator&(SHARED_PTR<T>& ptr) {
00323 return archiveSP(ptr, fundamental_t<T>());
00324 }
00325
00326
00343 template<class T>
00344 Archive& operator&(T& x) {
00345
00346 serializeArray(x, MynahSA::array_t<T>());
00347 return *this;
00348 }
00349
00350
00351
00352
00353
00381 void clearUPR();
00382
00386 template<class T>
00387 void touchPtr(const SHARED_PTR<T>& ptr) {
00388 SHARED_PTR<void> value(STATIC_PTR_CAST<void>(ptr));
00389 std::map<SHARED_PTR<void>, unsigned int>::iterator mit = _ptrToUPR.find(value);
00390 if (mit != _ptrToUPR.end()) {
00391 unsigned int upr = (*mit).second;
00392 _ptrToUPR.erase(mit);
00393 std::map<unsigned int, SHARED_PTR<void> >::iterator mit2 = _uprToPtr.find(upr);
00394 if (mit2 != _uprToPtr.end()) {
00395 _uprToPtr.erase(mit2);
00396 }
00397 }
00398 }
00399
00400 protected:
00401 enum ArchiveMode { ARCHIVE_READ, ARCHIVE_WRITE };
00404 virtual ArchiveMode getArchiveMode() const =0;
00405
00406
00407 private:
00408
00410 template<class T>
00411 void serializeArray(T& x, const false_t&) {
00412
00413 serializeTerm(x, MynahSA::enum_t<T>());
00414 }
00415
00417 template<class T>
00418 void serializeArray(T& x, const true_t&) {
00419 for (unsigned int i=0; i<sizeof(T); i++) {
00420 (*this) & x[i];
00421 }
00422 }
00423
00424
00426 template<class T>
00427 void serializeTerm(T& x, const true_t&) {
00428 (*this) & ((int&) x);
00429 }
00430
00432 template<class T>
00433 void serializeTerm(T& x, const false_t&) {
00434 x.serialize(*this);
00435 }
00436
00437
00439 template<class T>
00440 Archive& archiveSP(SHARED_PTR<T>& instance, const true_t&) {
00441
00442 if (getArchiveMode() == ARCHIVE_READ) {
00443
00444
00445
00446 bool useUPR;
00447 (*this) & useUPR;
00448 if (useUPR) {
00449
00450 unsigned int upr;
00451 (*this) & upr;
00452 std::map< unsigned int, SHARED_PTR<void> >::const_iterator mit = _uprToPtr.find(upr);
00453
00454 if (mit == _uprToPtr.end()) {
00455 throw ExceptionBase("Archive::operator&(SHARED_PTR<T>&) - recovery error: Unique Pointer Reference does not exist.");
00456 }
00457
00458
00459 instance = STATIC_PTR_CAST<T>( (*mit).second );
00460 } else {
00461
00462
00463
00464 instance = SHARED_PTR<T>(new T);
00465
00466
00467
00468
00469
00470
00471
00472
00473 SHARED_PTR<void> internalPointer = STATIC_PTR_CAST<void>(instance);
00474
00475 _ptrToUPR[internalPointer] = _nextUPR;
00476
00477 _uprToPtr[_nextUPR] = internalPointer;
00478
00479 ++_nextUPR;
00480
00481
00482 (*this) & (*instance);
00483 }
00484 } else {
00485
00486
00487
00488 SHARED_PTR<void> internalPointer = STATIC_PTR_CAST<void>(instance);
00489
00490
00491 std::map< SHARED_PTR<void>, unsigned int >::const_iterator mit = _ptrToUPR.find(internalPointer);
00492 if (mit != _ptrToUPR.end()) {
00493
00494 bool trueBool = true;
00495 (*this) & trueBool;
00496 unsigned int upr = (*mit).second;
00497 (*this) & upr;
00498 } else {
00499 bool falseBool = false;
00500 (*this) & falseBool;
00501
00502
00503
00504
00505
00506
00507
00508
00509 _ptrToUPR[internalPointer] = _nextUPR;
00510 _uprToPtr[_nextUPR] = internalPointer;
00511 ++_nextUPR;
00512
00513
00514 (*this) & (*instance);
00515 }
00516 }
00517 return *this;
00518 }
00519
00520
00521
00522
00524 template<class T>
00525 Archive& archiveSP(SHARED_PTR<T>& instance, const false_t&) {
00526 #ifdef DEBUG
00527
00528 STATIC_PTR_CAST<IoBase>(instance);
00529 #endif
00530
00531 if (getArchiveMode() == ARCHIVE_READ) {
00532
00533
00534
00535 bool useUPR = false;
00536 (*this) & useUPR;
00537 if (useUPR) {
00538
00539 unsigned int upr;
00540 (*this) & upr;
00541 std::map< unsigned int, SHARED_PTR<void> >::const_iterator mit = _uprToPtr.find(upr);
00542
00543 if (mit == _uprToPtr.end()) {
00544 throw ExceptionBase("Archive::operator&(SHARED_PTR<T>&) - recovery error: Unique Pointer Reference does not exist.");
00545 }
00546
00547
00548 instance = STATIC_PTR_CAST<T>( (*mit).second );
00549 } else {
00550
00551 std::string name;
00552 (*this) & name;
00553 SHARED_PTR<ArchiveConstructor> iac = _constructors[name];
00554
00555 if (!iac) {
00556 throw ExceptionBase(std::string("Class name: ")+name+" is not registered");
00557 }
00558
00559 instance = STATIC_PTR_CAST<T>( (*iac)() );
00560
00561
00562
00563
00564
00565
00566
00567
00568 SHARED_PTR<void> internalPointer = STATIC_PTR_CAST<void>(instance);
00569
00570 _ptrToUPR[internalPointer] = _nextUPR;
00571
00572 _uprToPtr[_nextUPR] = internalPointer;
00573
00574 ++_nextUPR;
00575
00576
00577 instance->serialize(*this);
00578
00579 }
00580 } else {
00581
00582
00583
00584 SHARED_PTR<void> internalPointer = STATIC_PTR_CAST<void>(instance);
00585
00586
00587 std::map< SHARED_PTR<void>, unsigned int >::const_iterator mit = _ptrToUPR.find(internalPointer);
00588 if (mit != _ptrToUPR.end()) {
00589
00590 bool trueBool = true;
00591 (*this) & trueBool;
00592 unsigned int upr = (*mit).second;
00593 (*this) & upr;
00594 } else {
00595 bool falseBool = false;
00596 (*this) & falseBool;
00597
00598
00599 std::string copyRef = instance->ioName();
00600 (*this) & copyRef;
00601
00602
00603
00604
00605
00606
00607
00608 _ptrToUPR[internalPointer] = _nextUPR;
00609 _uprToPtr[_nextUPR] = internalPointer;
00610 ++_nextUPR;
00611
00612
00613 instance->serialize( (*this) );
00614
00615 }
00616 }
00617 return *this;
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00631 std::map<std::string, SHARED_PTR<ArchiveConstructor> > _constructors;
00632
00634 std::map< SHARED_PTR<void>, unsigned int > _ptrToUPR;
00635
00637 std::map< unsigned int, SHARED_PTR<void> > _uprToPtr;
00638
00640 unsigned int _nextUPR;
00641
00642 };
00643 };
00644
00645
00646
00647 #endif