ThePEG  1.8.0
PersistentOStream.h
1 // -*- C++ -*-
2 //
3 // PersistentOStream.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 1999-2011 Leif Lonnblad
5 //
6 // ThePEG is licenced under version 2 of the GPL, see COPYING for details.
7 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
8 //
9 #ifndef ThePEG_PersistentOStream_H
10 #define ThePEG_PersistentOStream_H
11 // This is the declaration of the PersistentOStream class.
12 
13 #include "ThePEG/Config/ThePEG.h"
14 #include "ThePEG/Utilities/ClassDescription.h"
15 #include "ThePEG/Utilities/Exception.h"
16 #include "ThePEG/Utilities/Debug.h"
17 #include "PersistentOStream.fh"
18 #include "PersistentOStream.xh"
19 
20 namespace ThePEG {
21 
51 
52 public:
53 
55 
58 
61 
64 
65 public:
66 
72  PersistentOStream(ostream &, const vector<string> & libs = vector<string>());
73 
82  PersistentOStream(string, const vector<string> & libs = vector<string>());
83 
88 
94  template <typename T>
95  PersistentOStream & operator<<(const RCPtr<T> & p) {
96  return outputPointer(p);
97  }
98 
104  template <typename T>
105  PersistentOStream & operator<<(const ConstRCPtr<T> & p) {
106  return outputPointer(p);
107  }
108 
114  template <typename T>
115  PersistentOStream & operator<<(const TransientRCPtr<T> & p) {
116  return outputPointer(p);
117  }
118 
124  template <typename T>
125  PersistentOStream & operator<<(const TransientConstRCPtr<T> & p) {
126  return outputPointer(p);
127  }
128 
129 
136  for ( string::const_iterator i = s.begin(); i < s.end(); ++i ) escape(*i);
137  put(tSep);
138  return *this;
139  }
140 
145  escape(c);
146  put(tSep);
147  return *this;
148  }
149 
153  PersistentOStream & operator<<(signed char c) {
154  return (*this) << static_cast<char>(c);
155  }
156 
160  PersistentOStream & operator<<(unsigned char c) {
161  return (*this) << static_cast<char>(c);
162  }
163 
168  os() << i;
169  put(tSep);
170  return *this;
171  }
172 
176  PersistentOStream & operator<<(unsigned int i) {
177  os() << i;
178  put(tSep);
179  return *this;
180  }
181 
186  os() << i;
187  put(tSep);
188  return *this;
189  }
190 
194  PersistentOStream & operator<<(unsigned long i) {
195  os() << i;
196  put(tSep);
197  return *this;
198  }
199 
204  os() << i;
205  put(tSep);
206  return *this;
207  }
208 
212  PersistentOStream & operator<<(unsigned short i) {
213  os() << i;
214  put(tSep);
215  return *this;
216  }
217 
222  if ( isnan(d) || isinf(d) )
223  throw WriteError()
224  << "Tried to write a NaN or Inf double to a persistent stream."
226  os() << setprecision(18) << d;
227  put(tSep);
228  return *this;
229  }
230 
235  if ( isnan(f) || isinf(f) )
236  throw WriteError()
237  << "Tried to write a NaN or Inf float to a persistent stream."
239  os() << setprecision(9) << f;
240  put(tSep);
241  return *this;
242  }
243 
248  if (t) put(tYes);
249  else put(tNo);
250  // This is a workaround for a possible bug in gcc 4.0.0
251  // which inserts tYes and tNo as global symbols although
252  // they are private
253  // put(t? tYes: tNo);
254  put(tSep);
255  return *this;
256  }
257 
261  PersistentOStream & operator<<(const char * s) {
262  *this << string(s);
263  return *this;
264  }
265 
270  *this << z.real() << z.imag();
271  return *this;
272  }
274 
278  template <typename Container>
279  void putContainer(const Container & c) {
280  *this << c.size();
281  for ( typename Container::const_iterator it = c.begin();
282  it != c.end() && good() ; ++it )
283  *this << *it;
284  }
285 
290 
298  void putObjectPart(tcBPtr obj, const ClassDescriptionBase * cd);
299 
305 
311  lastSavedObject.push(writtenObjects.size() - 1);
312  return *this;
313  }
314 
319  lastSavedObject.pop();
320  return *this;
321  }
322 
326  bool good() const { return !badState && os(); }
327 
331  operator bool() const { return good(); }
332 
336  bool operator!() const { return !good(); }
337 
338 private:
339 
344  struct MissingClass: public Exception {};
348  struct WriteError: public Exception {};
354  static const int version = 0;
355 
359  static const int subVersion = 3;
360 
366  static const char tBegin = '{';
367 
371  static const char tEnd = '}';
372 
380  static const char tNext = '|';
381 
385  static const char tNull = '\\';
386 
390  static const char tSep = '\n';
391 
396  static const char tNoSep = 'n';
397 
401  static const char tYes = 'y';
402 
406  static const char tNo = 'n';
408 
412  bool isToken(char c) const {
413  return c == tBegin || c == tEnd || c == tNext || c == tSep || c == tNull;
414  }
415 
419  void setBadState() {
420  breakThePEG();
421  badState = true;
422  }
423 
427  void checkState() { if ( ! os() ) badState = true; }
428 
433 
438 
442  void beginObject() { put(tBegin); }
443 
447  void endObject() { put(tEnd); }
448 
452  void endBase() { put(tNext); }
453 
457  void put(char c) { os().put(c); }
458 
463  void escape(char c) {
464  if ( isToken(c) ) {
465  put(tNull);
466  put( c == tSep? tNoSep: c );
467  } else
468  put(c);
469  }
470 
474  ostream & os() { return *theOStream; }
475 
479  const ostream & os() const { return *theOStream; }
480 
484  void init(const vector<string> & libs);
485 
490 
494  stack<int> lastSavedObject;
495 
500 
504  ostream * theOStream;
505 
509  bool badState;
510 
515 
516 private:
517 
522 
527 
532 
533 };
534 
538 inline PersistentOStream &
540  return (*func)(os);
541 }
542 
543 
547 inline PersistentOStream & flush(PersistentOStream & os) { return os.flush(); }
548 
552 inline PersistentOStream & push(PersistentOStream & os) { return os.push(); }
553 
557 inline PersistentOStream & pop(PersistentOStream & os) { return os.pop(); }
558 
559 
566 template <typename T1, typename T2>
568  const pair<T1,T2> & p) {
569  return os << p.first << p.second;
570 }
571 
575 template <typename Key, typename T, typename Cmp, typename A>
577  const multimap<Key,T,Cmp,A> & m) {
578  os.putContainer(m);
579  return os;
580 }
581 
585 template <typename Key, typename T, typename Cmp, typename A>
587  const map<Key,T,Cmp,A> & m) {
588  os.putContainer(m);
589  return os;
590 }
591 
595 template <typename Key, typename Cmp, typename A>
597  const set<Key,Cmp,A> & s) {
598  os.putContainer(s);
599  return os;
600 }
601 
602 
606 template <typename Key, typename Cmp, typename A>
608  const multiset<Key,Cmp,A> & s) {
609  os.putContainer(s);
610  return os;
611 }
612 
613 
617 template <typename T, typename A>
619  const list<T,A> & l) {
620  os.putContainer(l);
621  return os;
622 }
623 
624 
628 template <typename T, typename A>
630  const vector<T,A> & v) {
631  os.putContainer(v);
632  return os;
633 }
634 
638 template <typename T, typename A>
640  const deque<T,A> & d) {
641  os.putContainer(d);
642  return os;
643 }
645 
646 }
647 
648 #endif /* ThePEG_PersistentOStream_H */