00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ThePEG_PersistentOStream_H
00010 #define ThePEG_PersistentOStream_H
00011
00012
00013 #include "ThePEG/Config/ThePEG.h"
00014 #include "ThePEG/Utilities/ClassDescription.h"
00015 #include "ThePEG/Utilities/Exception.h"
00016 #include "PersistentOStream.fh"
00017 #include "PersistentOStream.xh"
00018
00019 namespace ThePEG {
00020
00049 class PersistentOStream {
00050
00051 public:
00052
00053 ThePEG_DECLARE_POINTERS(PersistentBase,BPtr);
00054
00056 ThePEG_DECLARE_MAP(cBPtr, int, ObjectMap);
00057
00059 ThePEG_DECLARE_MAP(const ClassDescriptionBase *, int, ClassMap);
00060
00062 typedef ClassDescriptionBase::DescriptionVector DescriptionVector;
00063
00064 public:
00065
00071 PersistentOStream(ostream &, const vector<string> & libs = vector<string>());
00072
00081 PersistentOStream(string, const vector<string> & libs = vector<string>());
00082
00086 ~PersistentOStream();
00087
00093 template <typename T>
00094 PersistentOStream & operator<<(const RCPtr<T> & p) {
00095 return outputPointer(p);
00096 }
00097
00103 template <typename T>
00104 PersistentOStream & operator<<(const ConstRCPtr<T> & p) {
00105 return outputPointer(p);
00106 }
00107
00113 template <typename T>
00114 PersistentOStream & operator<<(const TransientRCPtr<T> & p) {
00115 return outputPointer(p);
00116 }
00117
00123 template <typename T>
00124 PersistentOStream & operator<<(const TransientConstRCPtr<T> & p) {
00125 return outputPointer(p);
00126 }
00127
00128
00134 PersistentOStream & operator<<(string s) {
00135 for ( string::const_iterator i = s.begin(); i < s.end(); ++i ) escape(*i);
00136 put(tSep);
00137 return *this;
00138 }
00139
00143 PersistentOStream & operator<<(char c) {
00144 escape(c);
00145 put(tSep);
00146 return *this;
00147 }
00148
00152 PersistentOStream & operator<<(signed char c) {
00153 return (*this) << static_cast<char>(c);
00154 }
00155
00159 PersistentOStream & operator<<(unsigned char c) {
00160 return (*this) << static_cast<char>(c);
00161 }
00162
00166 PersistentOStream & operator<<(int i) {
00167 os() << i;
00168 put(tSep);
00169 return *this;
00170 }
00171
00175 PersistentOStream & operator<<(unsigned int i) {
00176 os() << i;
00177 put(tSep);
00178 return *this;
00179 }
00180
00184 PersistentOStream & operator<<(long i) {
00185 os() << i;
00186 put(tSep);
00187 return *this;
00188 }
00189
00193 PersistentOStream & operator<<(unsigned long i) {
00194 os() << i;
00195 put(tSep);
00196 return *this;
00197 }
00198
00202 PersistentOStream & operator<<(short i) {
00203 os() << i;
00204 put(tSep);
00205 return *this;
00206 }
00207
00211 PersistentOStream & operator<<(unsigned short i) {
00212 os() << i;
00213 put(tSep);
00214 return *this;
00215 }
00216
00220 PersistentOStream & operator<<(double d) {
00221 os() << setprecision(18) << d;
00222 put(tSep);
00223 return *this;
00224 }
00225
00229 PersistentOStream & operator<<(float f) {
00230 os() << setprecision(9) << f;
00231 put(tSep);
00232 return *this;
00233 }
00234
00238 PersistentOStream & operator<<(bool t) {
00239 if (t) put(tYes);
00240 else put(tNo);
00241
00242
00243
00244
00245 put(tSep);
00246 return *this;
00247 }
00248
00252 PersistentOStream & operator<<(const char * s) {
00253 *this << string(s);
00254 return *this;
00255 }
00256
00260 PersistentOStream & operator<<(Complex z) {
00261 *this << z.real() << z.imag();
00262 return *this;
00263 }
00265
00269 template <typename Container>
00270 void putContainer(const Container & c) {
00271 *this << c.size();
00272 for ( typename Container::const_iterator it = c.begin();
00273 it != c.end() && good() ; ++it )
00274 *this << *it;
00275 }
00276
00280 PersistentOStream & outputPointer(tcBPtr);
00281
00289 void putObjectPart(tcBPtr obj, const ClassDescriptionBase * cd);
00290
00295 PersistentOStream & flush();
00296
00301 PersistentOStream & push() {
00302 lastSavedObject.push(writtenObjects.size() - 1);
00303 return *this;
00304 }
00305
00309 PersistentOStream & pop() {
00310 lastSavedObject.pop();
00311 return *this;
00312 }
00313
00317 bool good() const { return !badState && os(); }
00318
00322 operator bool() const { return good(); }
00323
00327 bool operator!() const { return !good(); }
00328
00329 private:
00330
00335 struct MissingClass: public Exception {};
00341 static const int version = 0;
00342
00346 static const int subVersion = 3;
00347
00353 static const char tBegin = '{';
00354
00358 static const char tEnd = '}';
00359
00367 static const char tNext = '|';
00368
00372 static const char tNull = '\\';
00373
00377 static const char tSep = '\n';
00378
00383 static const char tNoSep = 'n';
00384
00388 static const char tYes = 'y';
00389
00393 static const char tNo = 'n';
00395
00399 bool isToken(char c) const {
00400 return c == tBegin || c == tEnd || c == tNext || c == tSep || c == tNull;
00401 }
00402
00406 void setBadState() {
00407 breakThePEG();
00408 badState = true;
00409 }
00410
00414 void checkState() { if ( ! os() ) badState = true; }
00415
00419 const ClassDescriptionBase * writeClassId(tcBPtr);
00420
00424 void writeClassDescription(const ClassDescriptionBase *);
00425
00429 void beginObject() { put(tBegin); }
00430
00434 void endObject() { put(tEnd); }
00435
00439 void endBase() { put(tNext); }
00440
00444 void put(char c) { os().put(c); }
00445
00450 void escape(char c) {
00451 if ( isToken(c) ) {
00452 put(tNull);
00453 put( c == tSep? tNoSep: c );
00454 } else
00455 put(c);
00456 }
00457
00461 ostream & os() { return *theOStream; }
00462
00466 const ostream & os() const { return *theOStream; }
00467
00471 void init(const vector<string> & libs);
00472
00476 ObjectMap writtenObjects;
00477
00481 stack<int> lastSavedObject;
00482
00486 ClassMap writtenClasses;
00487
00491 ostream * theOStream;
00492
00496 bool badState;
00497
00501 bool allocStream;
00502
00503 private:
00504
00508 PersistentOStream();
00509
00513 PersistentOStream(const PersistentOStream &);
00514
00518 PersistentOStream & operator=(const PersistentOStream &);
00519
00520 };
00521
00525 inline PersistentOStream &
00526 operator<<(PersistentOStream & os, PersistentOManip func) {
00527 return (*func)(os);
00528 }
00529
00530
00534 inline PersistentOStream & flush(PersistentOStream & os) { return os.flush(); }
00535
00539 inline PersistentOStream & push(PersistentOStream & os) { return os.push(); }
00540
00544 inline PersistentOStream & pop(PersistentOStream & os) { return os.pop(); }
00545
00546
00553 template <typename T1, typename T2>
00554 inline PersistentOStream & operator<<(PersistentOStream & os,
00555 const pair<T1,T2> & p) {
00556 return os << p.first << p.second;
00557 }
00558
00562 template <typename Key, typename T, typename Cmp, typename A>
00563 inline PersistentOStream & operator<<(PersistentOStream & os,
00564 const multimap<Key,T,Cmp,A> & m) {
00565 os.putContainer(m);
00566 return os;
00567 }
00568
00572 template <typename Key, typename T, typename Cmp, typename A>
00573 inline PersistentOStream & operator<<(PersistentOStream & os,
00574 const map<Key,T,Cmp,A> & m) {
00575 os.putContainer(m);
00576 return os;
00577 }
00578
00582 template <typename Key, typename Cmp, typename A>
00583 inline PersistentOStream & operator<<(PersistentOStream & os,
00584 const set<Key,Cmp,A> & s) {
00585 os.putContainer(s);
00586 return os;
00587 }
00588
00589
00593 template <typename Key, typename Cmp, typename A>
00594 inline PersistentOStream & operator<<(PersistentOStream & os,
00595 const multiset<Key,Cmp,A> & s) {
00596 os.putContainer(s);
00597 return os;
00598 }
00599
00600
00604 template <typename T, typename A>
00605 inline PersistentOStream & operator<<(PersistentOStream & os,
00606 const list<T,A> & l) {
00607 os.putContainer(l);
00608 return os;
00609 }
00610
00611
00615 template <typename T, typename A>
00616 inline PersistentOStream & operator<<(PersistentOStream & os,
00617 const vector<T,A> & v) {
00618 os.putContainer(v);
00619 return os;
00620 }
00621
00625 template <typename T, typename A>
00626 inline PersistentOStream & operator<<(PersistentOStream & os,
00627 const deque<T,A> & d) {
00628 os.putContainer(d);
00629 return os;
00630 }
00632
00633 }
00634
00635 #endif