00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #ifndef MORE_SYNCSTREAM_H
00049 #define MORE_SYNCSTREAM_H
00050
00051 #include <stdexcept>
00052 #include <string>
00053 #include <utility>
00054 #include <iostream>
00055 #include <fstream>
00056 #include <more/io/binary_io.h>
00057 #include <complex>
00058
00059 namespace more {
00060 namespace io {
00061
00062 using std::size_t;
00063
00064
00065
00066
00067
00068
00069
00070 struct syncstream
00071 {
00072 enum openmode
00073 {
00074 in = 1,
00075 out = 2,
00076 test = 3
00077 };
00078
00079 protected:
00080 syncstream(std::streambuf* buf);
00081 syncstream(std::streambuf* buf, std::ios_base::openmode mode_);
00082 void prolog(std::ios_base::openmode mode_);
00083
00084 public:
00085
00086
00087
00088
00089
00090 void set_digits(int dig) { m_dig = dig; }
00091
00092
00093 void set_digits10(int dig10);
00094
00095
00096 int digits() { return m_dig; }
00097
00098
00099 int digits10();
00100
00101
00102 bool is_input() { return m_mode & std::ios_base::in; }
00103
00104
00105 bool is_output() { return m_mode & std::ios_base::out; }
00106
00107
00108 bool good() { return m_ios.good(); }
00109
00110
00111 bool fail() { return m_ios.fail(); }
00112
00113
00114 bool bad() { return m_ios.bad(); }
00115
00116
00117 void setstate(std::ios_base::iostate st) { m_ios.setstate(st); }
00118
00119
00120 void clear() { m_ios.clear(); }
00121
00122
00123
00124
00125 void sync_raw_data(void* p, size_t n);
00126
00127
00128 template<typename T>
00129 syncstream& operator|(T& x) { x.sync(*this); return *this; }
00130
00131
00132
00133 syncstream& operator|(char& x) { sync(x); return *this; }
00134 syncstream& operator|(signed char& x) { sync(x); return *this; }
00135 syncstream& operator|(unsigned char& x) { sync(x); return *this; }
00136 syncstream& operator|(short& x) { sync(x); return *this; }
00137 syncstream& operator|(unsigned short& x) { sync(x); return *this; }
00138 syncstream& operator|(int& x) { sync(x); return *this; }
00139 syncstream& operator|(unsigned int& x) { sync(x); return *this; }
00140 syncstream& operator|(long& x) { sync(x); return *this; }
00141 syncstream& operator|(unsigned long& x) { sync(x); return *this; }
00142 #ifdef MORE_HAVE_LONG_LONG
00143 syncstream& operator|(long long& x) { sync(x); return *this; }
00144 syncstream& operator|(unsigned long long& x) {sync(x);return*this;}
00145 #endif
00146
00147 syncstream& operator|(bool& x) { sync(x); return *this; }
00148
00149 syncstream& operator|(float& x) { sync_fp(x); return *this; }
00150 syncstream& operator|(double& x) { sync_fp(x); return *this; }
00151 syncstream& operator|(long double& x) { sync_fp(x); return *this; }
00152 syncstream& operator|(std::complex<float>& x)
00153 { sync_cplx(x); return *this; }
00154 syncstream& operator|(std::complex<double>& x)
00155 { sync_cplx(x); return *this; }
00156 syncstream& operator|(std::complex<long double>& x)
00157 { sync_cplx(x); return *this; }
00158
00159 syncstream& operator|(std::string& x) { sync(x); return *this; }
00160 template<typename T, typename U>
00161 syncstream& operator|(std::pair<T, U>& x)
00162 {
00163 *this | x.first | x.second;
00164 return *this;
00165 }
00166
00167
00168 syncstream& operator|(void (*f)(syncstream&)) { f(*this); return *this; }
00169
00170
00171 int _version() const { return m_version; }
00172
00173 private:
00174 std::iostream m_ios;
00175 std::ios_base::openmode m_mode;
00176 int m_dig;
00177 int m_version;
00178
00179 template<typename T>
00180 void sync(T& x)
00181 {
00182 if (m_mode & std::ios_base::binary) {
00183 if (m_mode & std::ios_base::out)
00184 binary_write(m_ios, x);
00185 if (m_mode & std::ios_base::in)
00186 binary_read(m_ios, x);
00187 }
00188 else
00189 throw std::logic_error
00190 ("syncstream: ascii mode not implemented");
00191 }
00192
00193 template<typename T>
00194 void sync_fp(T& x)
00195 {
00196 if (m_mode & std::ios_base::binary) {
00197 if (m_mode & std::ios_base::out)
00198 binary_write(m_ios, x,
00199 std::min(std::numeric_limits<T>
00200 ::digits, m_dig));
00201 if (m_mode & std::ios_base::in)
00202 binary_read(m_ios, x);
00203 }
00204 else
00205 throw std::logic_error
00206 ("syncstream: ascii mode not implemented");
00207 }
00208
00209 template<typename T>
00210 void sync_cplx(std::complex<T>& x)
00211 {
00212 T re = x.real();
00213 T im = x.imag();
00214 *this | re | im;
00215 x = std::complex<T>(re, im);
00216 }
00217 };
00218
00219
00220
00221
00222
00223 struct setdigits {
00224 setdigits(int dig_) : m_dig(dig_) {}
00225
00226 friend syncstream&
00227 operator|(syncstream& sync, setdigits x)
00228 {
00229 sync.set_digits(x.m_dig);
00230 return sync;
00231 }
00232 private:
00233 int m_dig;
00234 };
00235
00236
00237
00238
00239
00240 struct setdigits10
00241 {
00242 setdigits10(int dig_) : m_dig(dig_) {}
00243
00244 friend syncstream&
00245 operator|(syncstream& sync, setdigits10 x)
00246 {
00247 sync.set_digits10(x.m_dig);
00248 return sync;
00249 }
00250 private:
00251 int m_dig;
00252 };
00253
00254
00255
00256
00257 struct fsyncstream : syncstream
00258 {
00259 fsyncstream()
00260 : syncstream(&sb) {}
00261
00262 fsyncstream(const char* name, std::ios_base::openmode mode)
00263 : syncstream(&sb)
00264 {
00265 this->open(name, mode);
00266 }
00267
00268 fsyncstream(const char* name, syncstream::openmode mode)
00269 : syncstream(&sb)
00270 {
00271 if (mode & in) {
00272 open(name, std::ios_base::binary | std::ios_base::in);
00273 if (!good() && (mode & out))
00274 open(name, std::ios_base::binary | std::ios_base::out);
00275 }
00276 }
00277
00278 std::filebuf* rdbuf() { return &sb; }
00279 std::filebuf const* rdbuf() const { return &sb; }
00280
00281 bool is_open() const { return rdbuf()->is_open(); }
00282
00283 void open(const char* name, std::ios_base::openmode mode) {
00284 rdbuf()->open(name, mode);
00285 prolog(mode);
00286 }
00287
00288 void close() {
00289 clear();
00290 if (!rdbuf()->close())
00291 setstate(std::ios_base::failbit);
00292 }
00293
00294 private:
00295 std::filebuf sb;
00296 };
00297
00298
00299
00300
00301 struct ifsyncstream : fsyncstream
00302 {
00303
00304 ifsyncstream() {}
00305
00306
00307 ifsyncstream(const char* name,
00308 std::ios_base::openmode mode
00309 = std::ios_base::in | std::ios_base::binary)
00310 : fsyncstream(name, mode) {}
00311
00312
00313
00314 void open(const char* name,
00315 std::ios_base::openmode mode
00316 = std::ios_base::in | std::ios_base::binary)
00317 {
00318 fsyncstream::open(name, mode);
00319 }
00320 };
00321
00322
00323
00324
00325 struct ofsyncstream : fsyncstream
00326 {
00327
00328 ofsyncstream() {}
00329
00330
00331 ofsyncstream(const char* name,
00332 std::ios_base::openmode mode
00333 = std::ios_base::out | std::ios_base::binary)
00334 : fsyncstream(name, mode) {}
00335
00336
00337
00338 void
00339 open(const char* name,
00340 std::ios_base::openmode mode
00341 = std::ios_base::out | std::ios_base::binary)
00342 {
00343 fsyncstream::open(name, mode);
00344 }
00345 };
00346
00347
00348 template<typename T>
00349 void sync_skip(syncstream& sio, int i = 1)
00350 {
00351 T x;
00352 while (i) {
00353 sio | x;
00354 --i;
00355 }
00356 }
00357
00358
00359 template<typename Iterator>
00360 void sync_range(syncstream& sio, Iterator first, Iterator last)
00361 {
00362 while (first != last) sio | *first, ++first;
00363 }
00364
00365
00366
00367 template<typename Seq>
00368 void sync_sequence(syncstream& sio, Seq& c)
00369 {
00370 typename Seq::size_type n;
00371 if (sio.is_input()) {
00372 sio | n;
00373 if (!sio.good()) return;
00374 c.resize(n);
00375 }
00376 else {
00377 n = c.size();
00378 sio | n;
00379 if (!sio.good()) return;
00380 }
00381 sync_range(sio, c.begin(), c.end());
00382 }
00383
00384
00385 template<typename Assoc>
00386 void sync_associative_container(syncstream& sio, Assoc& x)
00387 {
00388 typename Assoc::size_type n;
00389 typename Assoc::value_type v;
00390 if (sio.is_input()) {
00391 sio | n;
00392 while (n--) {
00393 sio | v;
00394 x.insert(x.end(), v);
00395 }
00396 }
00397 else {
00398 n = x.size();
00399 sio | n;
00400 for (typename Assoc::iterator it = x.begin();
00401 it != x.end(); ++it) {
00402 v = *it;
00403 sio | v;
00404 }
00405 }
00406 }
00407
00408
00409 template<typename Assoc>
00410 void sync_pair_associative_container(syncstream& sio, Assoc& x)
00411 {
00412 typename Assoc::size_type n;
00413 typename Assoc::key_type k;
00414 typename Assoc::data_type d;
00415 if (sio.is_input()) {
00416 sio | n;
00417 while (n--) {
00418 sio | k | d;
00419 x.insert(typename Assoc::value_type(k, d));
00420 }
00421 }
00422 else {
00423 n = x.size();
00424 sio | n;
00425 for (typename Assoc::iterator it = x.begin(); it != x.end();
00426 ++it) {
00427 k = it->first;
00428 d = it->second;
00429 sio | k | d;
00430 }
00431 }
00432 }
00433
00434 }
00435 #if defined(MORE_BACKWARD) && MORE_BACKWARD < 20010615
00436 using namespace io;
00437 #endif
00438 }
00439
00440 #endif