Browse code

Adding stream on windows

Steffen Neumann authored on 17/01/2022 13:33:38
Showing2 changed files

1 1
new file mode 100755
... ...
@@ -0,0 +1,491 @@
1
+//////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4
+// Software License, Version 1.0. (See accompanying file
5
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
+//
7
+// See http://www.boost.org/libs/interprocess for documentation.
8
+//
9
+//////////////////////////////////////////////////////////////////////////////
10
+//
11
+// This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012.
12
+// Changed internal SGI string to a buffer. Added efficient
13
+// internal buffer get/set/swap functions, so that we can obtain/establish the
14
+// internal buffer without any reallocation or copy. Kill those temporaries!
15
+///////////////////////////////////////////////////////////////////////////////
16
+/*
17
+ * Copyright (c) 1998
18
+ * Silicon Graphics Computer Systems, Inc.
19
+ *
20
+ * Permission to use, copy, modify, distribute and sell this software
21
+ * and its documentation for any purpose is hereby granted without fee,
22
+ * provided that the above copyright notice appear in all copies and
23
+ * that both that copyright notice and this permission notice appear
24
+ * in supporting documentation.  Silicon Graphics makes no
25
+ * representations about the suitability of this software for any
26
+ * purpose.  It is provided "as is" without express or implied warranty.
27
+ */
28
+
29
+//!\file
30
+//!This file defines basic_bufferbuf, basic_ibufferstream,
31
+//!basic_obufferstream, and basic_bufferstream classes. These classes
32
+//!represent streamsbufs and streams whose sources or destinations
33
+//!are fixed size character buffers.
34
+
35
+#ifndef BOOST_INTERPROCESS_BUFFERSTREAM_HPP
36
+#define BOOST_INTERPROCESS_BUFFERSTREAM_HPP
37
+
38
+#ifndef BOOST_CONFIG_HPP
39
+#  include <boost/config.hpp>
40
+#endif
41
+#
42
+#if defined(BOOST_HAS_PRAGMA_ONCE)
43
+#  pragma once
44
+#endif
45
+
46
+#include <boost/interprocess/detail/config_begin.hpp>
47
+#include <boost/interprocess/detail/workaround.hpp>
48
+
49
+#include <iosfwd>
50
+#include <ios>
51
+#include <istream>
52
+#include <ostream>
53
+#include <string>    // char traits
54
+#include <cstddef>   // ptrdiff_t
55
+#include <boost/assert.hpp>
56
+#include <boost/interprocess/interprocess_fwd.hpp>
57
+
58
+namespace boost {  namespace interprocess {
59
+
60
+//!A streambuf class that controls the transmission of elements to and from
61
+//!a basic_xbufferstream. The elements are transmitted from a to a fixed
62
+//!size buffer
63
+template <class CharT, class CharTraits>
64
+class basic_bufferbuf
65
+   : public std::basic_streambuf<CharT, CharTraits>
66
+{
67
+   public:
68
+   typedef CharT                                         char_type;
69
+   typedef typename CharTraits::int_type                 int_type;
70
+   typedef typename CharTraits::pos_type                 pos_type;
71
+   typedef typename CharTraits::off_type                 off_type;
72
+   typedef CharTraits                                    traits_type;
73
+   typedef std::basic_streambuf<char_type, traits_type>  basic_streambuf_t;
74
+
75
+   public:
76
+   //!Constructor.
77
+   //!Does not throw.
78
+   explicit basic_bufferbuf(std::ios_base::openmode mode
79
+                            = std::ios_base::in | std::ios_base::out)
80
+      :  basic_streambuf_t(), m_mode(mode), m_buffer(0), m_length(0)
81
+      {}
82
+
83
+   //!Constructor. Assigns formatting buffer.
84
+   //!Does not throw.
85
+   explicit basic_bufferbuf(CharT *buf, std::size_t length,
86
+                            std::ios_base::openmode mode
87
+                              = std::ios_base::in | std::ios_base::out)
88
+      :  basic_streambuf_t(), m_mode(mode), m_buffer(buf), m_length(length)
89
+      {  this->set_pointers();   }
90
+
91
+   virtual ~basic_bufferbuf(){}
92
+
93
+   public:
94
+   //!Returns the pointer and size of the internal buffer.
95
+   //!Does not throw.
96
+   std::pair<CharT *, std::size_t> buffer() const
97
+      { return std::pair<CharT *, std::size_t>(m_buffer, m_length); }
98
+
99
+   //!Sets the underlying buffer to a new value
100
+   //!Does not throw.
101
+   void buffer(CharT *buf, std::size_t length)
102
+      {  m_buffer = buf;   m_length = length;   this->set_pointers();   }
103
+
104
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
105
+   private:
106
+   void set_pointers()
107
+   {
108
+      // The initial read position is the beginning of the buffer.
109
+      if(m_mode & std::ios_base::in)
110
+         this->setg(m_buffer, m_buffer, m_buffer + m_length);
111
+
112
+      // The initial write position is the beginning of the buffer.
113
+      if(m_mode & std::ios_base::out)
114
+         this->setp(m_buffer, m_buffer + m_length);
115
+   }
116
+
117
+   protected:
118
+   virtual int_type underflow()
119
+   {
120
+      // Precondition: gptr() >= egptr(). Returns a character, if available.
121
+      return this->gptr() != this->egptr() ?
122
+         CharTraits::to_int_type(*this->gptr()) : CharTraits::eof();
123
+   }
124
+
125
+   virtual int_type pbackfail(int_type c = CharTraits::eof())
126
+   {
127
+      if(this->gptr() != this->eback()) {
128
+         if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
129
+            if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) {
130
+               this->gbump(-1);
131
+               return c;
132
+            }
133
+            else if(m_mode & std::ios_base::out) {
134
+               this->gbump(-1);
135
+               *this->gptr() = CharTraits::to_char_type(c);
136
+               return c;
137
+            }
138
+            else
139
+               return CharTraits::eof();
140
+         }
141
+         else {
142
+            this->gbump(-1);
143
+            return CharTraits::not_eof(c);
144
+         }
145
+      }
146
+      else
147
+         return CharTraits::eof();
148
+   }
149
+
150
+   virtual int_type overflow(int_type c = CharTraits::eof())
151
+   {
152
+      if(m_mode & std::ios_base::out) {
153
+         if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
154
+//            if(!(m_mode & std::ios_base::in)) {
155
+//               if(this->pptr() != this->epptr()) {
156
+//                  *this->pptr() = CharTraits::to_char_type(c);
157
+//                  this->pbump(1);
158
+//                  return c;
159
+//               }
160
+//               else
161
+//                  return CharTraits::eof();
162
+//            }
163
+//            else {
164
+               if(this->pptr() == this->epptr()) {
165
+                  //We can't append to a static buffer
166
+                  return CharTraits::eof();
167
+               }
168
+               else {
169
+                  *this->pptr() = CharTraits::to_char_type(c);
170
+                  this->pbump(1);
171
+                  return c;
172
+               }
173
+//            }
174
+         }
175
+         else  // c is EOF, so we don't have to do anything
176
+            return CharTraits::not_eof(c);
177
+      }
178
+      else     // Overflow always fails if it's read-only.
179
+         return CharTraits::eof();
180
+   }
181
+
182
+   virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
183
+                              std::ios_base::openmode mode
184
+                                 = std::ios_base::in | std::ios_base::out)
185
+   {
186
+      bool in  = false;
187
+      bool out = false;
188
+
189
+      const std::ios_base::openmode inout =
190
+         std::ios_base::in | std::ios_base::out;
191
+
192
+      if((mode & inout) == inout) {
193
+         if(dir == std::ios_base::beg || dir == std::ios_base::end)
194
+            in = out = true;
195
+      }
196
+      else if(mode & std::ios_base::in)
197
+         in = true;
198
+      else if(mode & std::ios_base::out)
199
+         out = true;
200
+
201
+      if(!in && !out)
202
+         return pos_type(off_type(-1));
203
+      else if((in  && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) ||
204
+               (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0))))
205
+         return pos_type(off_type(-1));
206
+
207
+      std::streamoff newoff;
208
+      switch(dir) {
209
+         case std::ios_base::beg:
210
+            newoff = 0;
211
+         break;
212
+         case std::ios_base::end:
213
+            newoff = static_cast<std::streamoff>(m_length);
214
+         break;
215
+         case std::ios_base::cur:
216
+            newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
217
+                        : static_cast<std::streamoff>(this->pptr() - this->pbase());
218
+         break;
219
+         default:
220
+            return pos_type(off_type(-1));
221
+      }
222
+
223
+      off += newoff;
224
+
225
+      if(in) {
226
+         std::ptrdiff_t n = this->egptr() - this->eback();
227
+
228
+         if(off < 0 || off > n)
229
+            return pos_type(off_type(-1));
230
+         else
231
+            this->setg(this->eback(), this->eback() + off, this->eback() + n);
232
+      }
233
+
234
+      if(out) {
235
+         std::ptrdiff_t n = this->epptr() - this->pbase();
236
+
237
+         if(off < 0 || off > n)
238
+            return pos_type(off_type(-1));
239
+         else {
240
+            this->setp(this->pbase(), this->pbase() + n);
241
+            this->pbump(static_cast<int>(off));
242
+         }
243
+      }
244
+
245
+      return pos_type(off);
246
+   }
247
+
248
+   virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
249
+                                 = std::ios_base::in | std::ios_base::out)
250
+   {  return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode);  }
251
+
252
+   private:
253
+   std::ios_base::openmode m_mode;
254
+   CharT *                 m_buffer;
255
+   std::size_t             m_length;
256
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
257
+};
258
+
259
+//!A basic_istream class that uses a fixed size character buffer
260
+//!as its formatting buffer.
261
+template <class CharT, class CharTraits>
262
+class basic_ibufferstream :
263
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
264
+   private basic_bufferbuf<CharT, CharTraits>,
265
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
266
+   public std::basic_istream<CharT, CharTraits>
267
+{
268
+   public:                         // Typedefs
269
+   typedef typename std::basic_ios
270
+      <CharT, CharTraits>::char_type          char_type;
271
+   typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
272
+   typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
273
+   typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
274
+   typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
275
+
276
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
277
+   private:
278
+   typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;
279
+   typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
280
+   typedef std::basic_istream<char_type, CharTraits>  basic_streambuf_t;
281
+   bufferbuf_t &       get_buf()      {  return *this;  }
282
+   const bufferbuf_t & get_buf() const{  return *this;  }
283
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
284
+
285
+   public:
286
+   //!Constructor.
287
+   //!Does not throw.
288
+   basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in)
289
+      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
290
+         //virtual base of basic_istream. The class will be initialized when
291
+         //basic_istream is constructed calling basic_ios_t::init().
292
+         //As bufferbuf_t's constructor does not throw there is no risk of
293
+         //calling the basic_ios_t's destructor without calling basic_ios_t::init()
294
+        bufferbuf_t(mode | std::ios_base::in)
295
+      , basic_streambuf_t(this)
296
+      {}
297
+
298
+   //!Constructor. Assigns formatting buffer.
299
+   //!Does not throw.
300
+   basic_ibufferstream(const CharT *buf, std::size_t length,
301
+                       std::ios_base::openmode mode = std::ios_base::in)
302
+      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
303
+         //virtual base of basic_istream. The class will be initialized when
304
+         //basic_istream is constructed calling basic_ios_t::init().
305
+         //As bufferbuf_t's constructor does not throw there is no risk of
306
+         //calling the basic_ios_t's destructor without calling basic_ios_t::init()
307
+        bufferbuf_t(const_cast<CharT*>(buf), length, mode | std::ios_base::in)
308
+      , basic_streambuf_t(this)
309
+      {}
310
+
311
+   ~basic_ibufferstream(){}
312
+
313
+   public:
314
+   //!Returns the address of the stored
315
+   //!stream buffer.
316
+   basic_bufferbuf<CharT, CharTraits>* rdbuf() const
317
+      { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
318
+
319
+   //!Returns the pointer and size of the internal buffer.
320
+   //!Does not throw.
321
+   std::pair<const CharT *, std::size_t> buffer() const
322
+      { return get_buf().buffer(); }
323
+
324
+   //!Sets the underlying buffer to a new value. Resets
325
+   //!stream position. Does not throw.
326
+   void buffer(const CharT *buf, std::size_t length)
327
+      {  get_buf().buffer(const_cast<CharT*>(buf), length);  }
328
+};
329
+
330
+//!A basic_ostream class that uses a fixed size character buffer
331
+//!as its formatting buffer.
332
+template <class CharT, class CharTraits>
333
+class basic_obufferstream :
334
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
335
+   private basic_bufferbuf<CharT, CharTraits>,
336
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
337
+   public std::basic_ostream<CharT, CharTraits>
338
+{
339
+   public:
340
+   typedef typename std::basic_ios
341
+      <CharT, CharTraits>::char_type          char_type;
342
+   typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
343
+   typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
344
+   typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
345
+   typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
346
+
347
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
348
+   private:
349
+   typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;
350
+   typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
351
+   typedef std::basic_ostream<char_type, CharTraits>  basic_ostream_t;
352
+   bufferbuf_t &       get_buf()      {  return *this;  }
353
+   const bufferbuf_t & get_buf() const{  return *this;  }
354
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
355
+
356
+   public:
357
+   //!Constructor.
358
+   //!Does not throw.
359
+   basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out)
360
+      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
361
+         //virtual base of basic_istream. The class will be initialized when
362
+         //basic_istream is constructed calling basic_ios_t::init().
363
+         //As bufferbuf_t's constructor does not throw there is no risk of
364
+         //calling the basic_ios_t's destructor without calling basic_ios_t::init()
365
+         bufferbuf_t(mode | std::ios_base::out)
366
+      ,  basic_ostream_t(this)
367
+      {}
368
+
369
+   //!Constructor. Assigns formatting buffer.
370
+   //!Does not throw.
371
+   basic_obufferstream(CharT *buf, std::size_t length,
372
+                       std::ios_base::openmode mode = std::ios_base::out)
373
+      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
374
+         //virtual base of basic_istream. The class will be initialized when
375
+         //basic_istream is constructed calling basic_ios_t::init().
376
+         //As bufferbuf_t's constructor does not throw there is no risk of
377
+         //calling the basic_ios_t's destructor without calling basic_ios_t::init()
378
+         bufferbuf_t(buf, length, mode | std::ios_base::out)
379
+      ,  basic_ostream_t(this)
380
+      {}
381
+
382
+   ~basic_obufferstream(){}
383
+
384
+   public:
385
+   //!Returns the address of the stored
386
+   //!stream buffer.
387
+   basic_bufferbuf<CharT, CharTraits>* rdbuf() const
388
+      { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
389
+
390
+   //!Returns the pointer and size of the internal buffer.
391
+   //!Does not throw.
392
+   std::pair<CharT *, std::size_t> buffer() const
393
+      { return get_buf().buffer(); }
394
+
395
+   //!Sets the underlying buffer to a new value. Resets
396
+   //!stream position. Does not throw.
397
+   void buffer(CharT *buf, std::size_t length)
398
+      {  get_buf().buffer(buf, length);  }
399
+};
400
+
401
+
402
+//!A basic_iostream class that uses a fixed size character buffer
403
+//!as its formatting buffer.
404
+template <class CharT, class CharTraits>
405
+class basic_bufferstream :
406
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
407
+   private basic_bufferbuf<CharT, CharTraits>,
408
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
409
+   public std::basic_iostream<CharT, CharTraits>
410
+{
411
+   public:                         // Typedefs
412
+   typedef typename std::basic_ios
413
+      <CharT, CharTraits>::char_type          char_type;
414
+   typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
415
+   typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
416
+   typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
417
+   typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
418
+
419
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
420
+   private:
421
+   typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;
422
+   typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
423
+   typedef std::basic_iostream<char_type, CharTraits> basic_iostream_t;
424
+   bufferbuf_t &       get_buf()      {  return *this;  }
425
+   const bufferbuf_t & get_buf() const{  return *this;  }
426
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
427
+
428
+   public:
429
+   //!Constructor.
430
+   //!Does not throw.
431
+   basic_bufferstream(std::ios_base::openmode mode
432
+                      = std::ios_base::in | std::ios_base::out)
433
+      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
434
+         //virtual base of basic_istream. The class will be initialized when
435
+         //basic_istream is constructed calling basic_ios_t::init().
436
+         //As bufferbuf_t's constructor does not throw there is no risk of
437
+         //calling the basic_ios_t's destructor without calling basic_ios_t::init()
438
+         bufferbuf_t(mode)
439
+      ,  basic_iostream_t(this)
440
+      {}
441
+
442
+   //!Constructor. Assigns formatting buffer.
443
+   //!Does not throw.
444
+   basic_bufferstream(CharT *buf, std::size_t length,
445
+                      std::ios_base::openmode mode
446
+                        = std::ios_base::in | std::ios_base::out)
447
+      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
448
+         //virtual base of basic_istream. The class will be initialized when
449
+         //basic_istream is constructed calling basic_ios_t::init().
450
+         //As bufferbuf_t's constructor does not throw there is no risk of
451
+         //calling the basic_ios_t's destructor without calling basic_ios_t::init()
452
+         bufferbuf_t(buf, length, mode)
453
+      ,  basic_iostream_t(this)
454
+      {}
455
+
456
+   ~basic_bufferstream(){}
457
+
458
+   public:
459
+   //!Returns the address of the stored
460
+   //!stream buffer.
461
+   basic_bufferbuf<CharT, CharTraits>* rdbuf() const
462
+      { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
463
+
464
+   //!Returns the pointer and size of the internal buffer.
465
+   //!Does not throw.
466
+   std::pair<CharT *, std::size_t> buffer() const
467
+      { return get_buf().buffer(); }
468
+
469
+   //!Sets the underlying buffer to a new value. Resets
470
+   //!stream position. Does not throw.
471
+   void buffer(CharT *buf, std::size_t length)
472
+      {  get_buf().buffer(buf, length);  }
473
+};
474
+
475
+//Some typedefs to simplify usage
476
+typedef basic_bufferbuf<char>        bufferbuf;
477
+typedef basic_bufferstream<char>     bufferstream;
478
+typedef basic_ibufferstream<char>    ibufferstream;
479
+typedef basic_obufferstream<char>    obufferstream;
480
+
481
+typedef basic_bufferbuf<wchar_t>     wbufferbuf;
482
+typedef basic_bufferstream<wchar_t>  wbufferstream;
483
+typedef basic_ibufferstream<wchar_t> wibufferstream;
484
+typedef basic_obufferstream<wchar_t> wobufferstream;
485
+
486
+
487
+}} //namespace boost {  namespace interprocess {
488
+
489
+#include <boost/interprocess/detail/config_end.hpp>
490
+
491
+#endif /* BOOST_INTERPROCESS_BUFFERSTREAM_HPP */
0 492
new file mode 100755
... ...
@@ -0,0 +1,622 @@
1
+//////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4
+// Software License, Version 1.0. (See accompanying file
5
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
+//
7
+// See http://www.boost.org/libs/interprocess for documentation.
8
+//
9
+//////////////////////////////////////////////////////////////////////////////
10
+//
11
+// This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012.
12
+// Changed internal SGI string to a generic, templatized vector. Added efficient
13
+// internal buffer get/set/swap functions, so that we can obtain/establish the
14
+// internal buffer without any reallocation or copy. Kill those temporaries!
15
+///////////////////////////////////////////////////////////////////////////////
16
+/*
17
+ * Copyright (c) 1998
18
+ * Silicon Graphics Computer Systems, Inc.
19
+ *
20
+ * Permission to use, copy, modify, distribute and sell this software
21
+ * and its documentation for any purpose is hereby granted without fee,
22
+ * provided that the above copyright notice appear in all copies and
23
+ * that both that copyright notice and this permission notice appear
24
+ * in supporting documentation.  Silicon Graphics makes no
25
+ * representations about the suitability of this software for any
26
+ * purpose.  It is provided "as is" without express or implied warranty.
27
+ */
28
+
29
+//!\file
30
+//!This file defines basic_vectorbuf, basic_ivectorstream,
31
+//!basic_ovectorstream, and basic_vectorstreamclasses.  These classes
32
+//!represent streamsbufs and streams whose sources or destinations are
33
+//!STL-like vectors that can be swapped with external vectors to avoid
34
+//!unnecessary allocations/copies.
35
+
36
+#ifndef BOOST_INTERPROCESS_VECTORSTREAM_HPP
37
+#define BOOST_INTERPROCESS_VECTORSTREAM_HPP
38
+
39
+#ifndef BOOST_CONFIG_HPP
40
+#  include <boost/config.hpp>
41
+#endif
42
+#
43
+#if defined(BOOST_HAS_PRAGMA_ONCE)
44
+#  pragma once
45
+#endif
46
+
47
+#include <boost/interprocess/detail/config_begin.hpp>
48
+#include <boost/interprocess/detail/workaround.hpp>
49
+
50
+#include <iosfwd>
51
+#include <ios>
52
+#include <istream>
53
+#include <ostream>
54
+#include <string>    // char traits
55
+#include <cstddef>   // ptrdiff_t
56
+#include <boost/interprocess/interprocess_fwd.hpp>
57
+#include <boost/assert.hpp>
58
+
59
+namespace boost {  namespace interprocess {
60
+
61
+//!A streambuf class that controls the transmission of elements to and from
62
+//!a basic_ivectorstream, basic_ovectorstream or basic_vectorstream.
63
+//!It holds a character vector specified by CharVector template parameter
64
+//!as its formatting buffer. The vector must have contiguous storage, like
65
+//!std::vector, boost::interprocess::vector or boost::interprocess::basic_string
66
+template <class CharVector, class CharTraits>
67
+class basic_vectorbuf
68
+   : public std::basic_streambuf<typename CharVector::value_type, CharTraits>
69
+{
70
+   public:
71
+   typedef CharVector                        vector_type;
72
+   typedef typename CharVector::value_type   char_type;
73
+   typedef typename CharTraits::int_type     int_type;
74
+   typedef typename CharTraits::pos_type     pos_type;
75
+   typedef typename CharTraits::off_type     off_type;
76
+   typedef CharTraits                        traits_type;
77
+
78
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
79
+   private:
80
+   typedef std::basic_streambuf<char_type, traits_type> base_t;
81
+
82
+   basic_vectorbuf(const basic_vectorbuf&);
83
+   basic_vectorbuf & operator =(const basic_vectorbuf&);
84
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
85
+
86
+   public:
87
+   //!Constructor. Throws if vector_type default
88
+   //!constructor throws.
89
+   explicit basic_vectorbuf(std::ios_base::openmode mode
90
+                              = std::ios_base::in | std::ios_base::out)
91
+      :  base_t(), m_mode(mode)
92
+   {  this->initialize_pointers();   }
93
+
94
+   //!Constructor. Throws if
95
+   //!vector_type(const VectorParameter &param) throws.
96
+   template<class VectorParameter>
97
+   explicit basic_vectorbuf(const VectorParameter &param,
98
+                            std::ios_base::openmode mode
99
+                                 = std::ios_base::in | std::ios_base::out)
100
+      :  base_t(), m_mode(mode), m_vect(param)
101
+   {  this->initialize_pointers();   }
102
+
103
+   public:
104
+
105
+   //!Swaps the underlying vector with the passed vector.
106
+   //!This function resets the read/write position in the stream.
107
+   //!Does not throw.
108
+   void swap_vector(vector_type &vect)
109
+   {
110
+      if (this->m_mode & std::ios_base::out){
111
+         //Update high water if necessary
112
+         //And resize vector to remove extra size
113
+         if (mp_high_water < base_t::pptr()){
114
+            //Restore the vector's size if necessary
115
+            mp_high_water = base_t::pptr();
116
+         }
117
+         //This does not reallocate
118
+         m_vect.resize(mp_high_water - (m_vect.size() ? &m_vect[0] : 0));
119
+      }
120
+      //Now swap vector
121
+      m_vect.swap(vect);
122
+      this->initialize_pointers();
123
+   }
124
+
125
+   //!Returns a const reference to the internal vector.
126
+   //!Does not throw.
127
+   const vector_type &vector() const
128
+   {
129
+      if (this->m_mode & std::ios_base::out){
130
+         if (mp_high_water < base_t::pptr()){
131
+            //Restore the vector's size if necessary
132
+            mp_high_water = base_t::pptr();
133
+         }
134
+         //This shouldn't reallocate
135
+         typedef typename vector_type::size_type size_type;
136
+         char_type *old_ptr = base_t::pbase();
137
+         size_type high_pos = size_type(mp_high_water-old_ptr);
138
+         if(m_vect.size() > high_pos){
139
+            m_vect.resize(high_pos);
140
+            //But we must update end write pointer because vector size is now shorter
141
+            int old_pos = base_t::pptr() - base_t::pbase();
142
+            const_cast<basic_vectorbuf*>(this)->base_t::setp(old_ptr, old_ptr + high_pos);
143
+            const_cast<basic_vectorbuf*>(this)->base_t::pbump(old_pos);
144
+         }
145
+      }
146
+      return m_vect;
147
+   }
148
+
149
+   //!Preallocates memory from the internal vector.
150
+   //!Resets the stream to the first position.
151
+   //!Throws if the internals vector's memory allocation throws.
152
+   void reserve(typename vector_type::size_type size)
153
+   {
154
+      if (this->m_mode & std::ios_base::out && size > m_vect.size()){
155
+         typename vector_type::difference_type write_pos = base_t::pptr() - base_t::pbase();
156
+         typename vector_type::difference_type read_pos  = base_t::gptr() - base_t::eback();
157
+         //Now update pointer data
158
+         m_vect.reserve(size);
159
+         this->initialize_pointers();
160
+         base_t::pbump((int)write_pos);
161
+         if(this->m_mode & std::ios_base::in){
162
+            base_t::gbump((int)read_pos);
163
+         }
164
+      }
165
+   }
166
+
167
+   //!Calls clear() method of the internal vector.
168
+   //!Resets the stream to the first position.
169
+   void clear()
170
+   {  m_vect.clear();   this->initialize_pointers();   }
171
+
172
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
173
+   private:
174
+   //Maximizes high watermark to the initial vector size,
175
+   //initializes read and write iostream buffers to the capacity
176
+   //and resets stream positions
177
+   void initialize_pointers()
178
+   {
179
+      // The initial read position is the beginning of the vector.
180
+      if(!(m_mode & std::ios_base::out)){
181
+         if(m_vect.empty()){
182
+            this->setg(0, 0, 0);
183
+         }
184
+         else{
185
+            this->setg(&m_vect[0], &m_vect[0], &m_vect[0] + m_vect.size());
186
+         }
187
+      }
188
+
189
+      // The initial write position is the beginning of the vector.
190
+      if(m_mode & std::ios_base::out){
191
+         //First get real size
192
+         int real_size = (int)m_vect.size();
193
+         //Then maximize size for high watermarking
194
+         m_vect.resize(m_vect.capacity());
195
+         BOOST_ASSERT(m_vect.size() == m_vect.capacity());
196
+         //Set high watermarking with the expanded size
197
+         mp_high_water = m_vect.size() ? (&m_vect[0] + real_size) : 0;
198
+         //Now set formatting pointers
199
+         if(m_vect.empty()){
200
+            this->setp(0, 0);
201
+            if(m_mode & std::ios_base::in)
202
+               this->setg(0, 0, 0);
203
+         }
204
+         else{
205
+            char_type *p = &m_vect[0];
206
+            this->setp(p, p + m_vect.size());
207
+            if(m_mode & std::ios_base::in)
208
+               this->setg(p, p, p + real_size);
209
+         }
210
+         if (m_mode & (std::ios_base::app | std::ios_base::ate)){
211
+            base_t::pbump((int)real_size);
212
+         }
213
+      }
214
+   }
215
+
216
+   protected:
217
+   virtual int_type underflow()
218
+   {
219
+      if (base_t::gptr() == 0)
220
+         return CharTraits::eof();
221
+      if(m_mode & std::ios_base::out){
222
+         if (mp_high_water < base_t::pptr())
223
+            mp_high_water = base_t::pptr();
224
+         if (base_t::egptr() < mp_high_water)
225
+            base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water);
226
+      }
227
+      if (base_t::gptr() < base_t::egptr())
228
+         return CharTraits::to_int_type(*base_t::gptr());
229
+      return CharTraits::eof();
230
+   }
231
+
232
+   virtual int_type pbackfail(int_type c = CharTraits::eof())
233
+   {
234
+      if(this->gptr() != this->eback()) {
235
+         if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
236
+            if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) {
237
+               this->gbump(-1);
238
+               return c;
239
+            }
240
+            else if(m_mode & std::ios_base::out) {
241
+               this->gbump(-1);
242
+               *this->gptr() = c;
243
+               return c;
244
+            }
245
+            else
246
+               return CharTraits::eof();
247
+         }
248
+         else {
249
+            this->gbump(-1);
250
+            return CharTraits::not_eof(c);
251
+         }
252
+      }
253
+      else
254
+         return CharTraits::eof();
255
+   }
256
+
257
+   virtual int_type overflow(int_type c = CharTraits::eof())
258
+   {
259
+      if(m_mode & std::ios_base::out) {
260
+         if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
261
+               typedef typename vector_type::difference_type dif_t;
262
+               //The new output position is the previous one plus one
263
+               //because 'overflow' requires putting 'c' on the buffer
264
+               dif_t new_outpos = base_t::pptr() - base_t::pbase() + 1;
265
+               //Adjust high water if necessary
266
+               dif_t hipos = mp_high_water - base_t::pbase();
267
+               if (hipos < new_outpos)
268
+                  hipos = new_outpos;
269
+               //Insert the new data
270
+               m_vect.push_back(CharTraits::to_char_type(c));
271
+               m_vect.resize(m_vect.capacity());
272
+               BOOST_ASSERT(m_vect.size() == m_vect.capacity());
273
+               char_type* p = const_cast<char_type*>(&m_vect[0]);
274
+               //A reallocation might have happened, update pointers
275
+               base_t::setp(p, p + (dif_t)m_vect.size());
276
+               mp_high_water = p + hipos;
277
+               if (m_mode & std::ios_base::in)
278
+                  base_t::setg(p, p + (base_t::gptr() - base_t::eback()), mp_high_water);
279
+               //Update write position to the old position + 1
280
+               base_t::pbump((int)new_outpos);
281
+               return c;
282
+         }
283
+         else  // c is EOF, so we don't have to do anything
284
+            return CharTraits::not_eof(c);
285
+      }
286
+      else     // Overflow always fails if it's read-only.
287
+         return CharTraits::eof();
288
+   }
289
+
290
+   virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
291
+                              std::ios_base::openmode mode
292
+                                 = std::ios_base::in | std::ios_base::out)
293
+   {
294
+      //Get seek mode
295
+      bool in(0 != (mode & std::ios_base::in)), out(0 != (mode & std::ios_base::out));
296
+      //Test for logic errors
297
+      if(!in & !out)
298
+         return pos_type(off_type(-1));
299
+      else if((in && out) && (dir == std::ios_base::cur))
300
+         return pos_type(off_type(-1));
301
+      else if((in  && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) ||
302
+               (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0))))
303
+         return pos_type(off_type(-1));
304
+
305
+      off_type newoff;
306
+      //Just calculate the end of the stream. If the stream is read-only
307
+      //the limit is the size of the vector. Otherwise, the high water mark
308
+      //will mark the real size.
309
+      off_type limit;
310
+      if(m_mode & std::ios_base::out){
311
+         //Update high water marking because pptr() is going to change and it might
312
+         //have been updated since last overflow()
313
+         if(mp_high_water < base_t::pptr())
314
+            mp_high_water = base_t::pptr();
315
+         //Update read limits in case high water mark was changed
316
+         if(m_mode & std::ios_base::in){
317
+            if (base_t::egptr() < mp_high_water)
318
+               base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water);
319
+         }
320
+         limit = static_cast<off_type>(mp_high_water - base_t::pbase());
321
+      }
322
+      else{
323
+         limit = static_cast<off_type>(m_vect.size());
324
+      }
325
+
326
+      switch(dir) {
327
+         case std::ios_base::beg:
328
+            newoff = 0;
329
+         break;
330
+         case std::ios_base::end:
331
+            newoff = limit;
332
+         break;
333
+         case std::ios_base::cur:
334
+            newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
335
+                        : static_cast<std::streamoff>(this->pptr() - this->pbase());
336
+         break;
337
+         default:
338
+            return pos_type(off_type(-1));
339
+      }
340
+
341
+      newoff += off;
342
+
343
+      if (newoff < 0 || newoff > limit)
344
+         return pos_type(-1);
345
+      if (m_mode & std::ios_base::app && mode & std::ios_base::out && newoff != limit)
346
+         return pos_type(-1);
347
+      //This can reassign pointers
348
+      //if(m_vect.size() != m_vect.capacity())
349
+         //this->initialize_pointers();
350
+      if (in)
351
+         base_t::setg(base_t::eback(), base_t::eback() + newoff, base_t::egptr());
352
+      if (out){
353
+         base_t::setp(base_t::pbase(), base_t::epptr());
354
+         base_t::pbump(newoff);
355
+      }
356
+      return pos_type(newoff);
357
+   }
358
+
359
+   virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
360
+                                 = std::ios_base::in | std::ios_base::out)
361
+   {  return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode);  }
362
+
363
+   private:
364
+   std::ios_base::openmode m_mode;
365
+   mutable vector_type     m_vect;
366
+   mutable char_type*      mp_high_water;
367
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
368
+};
369
+
370
+//!A basic_istream class that holds a character vector specified by CharVector
371
+//!template parameter as its formatting buffer. The vector must have
372
+//!contiguous storage, like std::vector, boost::interprocess::vector or
373
+//!boost::interprocess::basic_string
374
+template <class CharVector, class CharTraits>
375
+class basic_ivectorstream
376
+   : public std::basic_istream<typename CharVector::value_type, CharTraits>
377
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
378
+   , private basic_vectorbuf<CharVector, CharTraits>
379
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
380
+{
381
+   public:
382
+   typedef CharVector                                                   vector_type;
383
+   typedef typename std::basic_ios
384
+      <typename CharVector::value_type, CharTraits>::char_type          char_type;
385
+   typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
386
+   typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
387
+   typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
388
+   typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
389
+
390
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
391
+   private:
392
+   typedef basic_vectorbuf<CharVector, CharTraits>    vectorbuf_t;
393
+   typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
394
+   typedef std::basic_istream<char_type, CharTraits>  base_t;
395
+
396
+   vectorbuf_t &       get_buf()      {  return *this;  }
397
+   const vectorbuf_t & get_buf() const{  return *this;  }
398
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
399
+
400
+   public:
401
+
402
+   //!Constructor. Throws if vector_type default
403
+   //!constructor throws.
404
+   basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in)
405
+      : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
406
+                  //(via basic_ios::init() call in base_t's constructor) without the risk of a
407
+                  //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
408
+      , vectorbuf_t(mode | std::ios_base::in)
409
+   {  this->base_t::rdbuf(&get_buf()); }
410
+
411
+   //!Constructor. Throws if vector_type(const VectorParameter &param)
412
+   //!throws.
413
+   template<class VectorParameter>
414
+   basic_ivectorstream(const VectorParameter &param,
415
+                       std::ios_base::openmode mode = std::ios_base::in)
416
+      : vectorbuf_t(param, mode | std::ios_base::in)
417
+         //basic_ios_t() is constructed uninitialized as virtual base
418
+         //and initialized inside base_t calling basic_ios::init()
419
+      , base_t(&get_buf())
420
+   {}
421
+
422
+   public:
423
+   //!Returns the address of the stored
424
+   //!stream buffer.
425
+   basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
426
+   { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
427
+
428
+   //!Swaps the underlying vector with the passed vector.
429
+   //!This function resets the read position in the stream.
430
+   //!Does not throw.
431
+   void swap_vector(vector_type &vect)
432
+   {  get_buf().swap_vector(vect);   }
433
+
434
+   //!Returns a const reference to the internal vector.
435
+   //!Does not throw.
436
+   const vector_type &vector() const
437
+   {  return get_buf().vector();   }
438
+
439
+   //!Calls reserve() method of the internal vector.
440
+   //!Resets the stream to the first position.
441
+   //!Throws if the internals vector's reserve throws.
442
+   void reserve(typename vector_type::size_type size)
443
+   {  get_buf().reserve(size);   }
444
+
445
+   //!Calls clear() method of the internal vector.
446
+   //!Resets the stream to the first position.
447
+   void clear()
448
+   {  get_buf().clear();   }
449
+};
450
+
451
+//!A basic_ostream class that holds a character vector specified by CharVector
452
+//!template parameter as its formatting buffer. The vector must have
453
+//!contiguous storage, like std::vector, boost::interprocess::vector or
454
+//!boost::interprocess::basic_string
455
+template <class CharVector, class CharTraits>
456
+class basic_ovectorstream
457
+   : public std::basic_ostream<typename CharVector::value_type, CharTraits>
458
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
459
+   , private basic_vectorbuf<CharVector, CharTraits>
460
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
461
+{
462
+   public:
463
+   typedef CharVector                                                   vector_type;
464
+   typedef typename std::basic_ios
465
+      <typename CharVector::value_type, CharTraits>::char_type          char_type;
466
+   typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
467
+   typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
468
+   typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
469
+   typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
470
+
471
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
472
+   private:
473
+   typedef basic_vectorbuf<CharVector, CharTraits>    vectorbuf_t;
474
+   typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
475
+   typedef std::basic_ostream<char_type, CharTraits>  base_t;
476
+
477
+   vectorbuf_t &       get_buf()      {  return *this;  }
478
+   const vectorbuf_t & get_buf()const {  return *this;  }
479
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
480
+
481
+   public:
482
+   //!Constructor. Throws if vector_type default
483
+   //!constructor throws.
484
+   basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out)
485
+      : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
486
+                  //(via basic_ios::init() call in base_t's constructor) without the risk of a
487
+                  //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
488
+      , vectorbuf_t(mode | std::ios_base::out)
489
+   {  this->base_t::rdbuf(&get_buf()); }
490
+
491
+   //!Constructor. Throws if vector_type(const VectorParameter &param)
492
+   //!throws.
493
+   template<class VectorParameter>
494
+   basic_ovectorstream(const VectorParameter &param,
495
+                        std::ios_base::openmode mode = std::ios_base::out)
496
+      : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
497
+                  //(via basic_ios::init() call in base_t's constructor) without the risk of a
498
+                  //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
499
+      , vectorbuf_t(param, mode | std::ios_base::out)
500
+   {  this->base_t::rdbuf(&get_buf()); }
501
+
502
+   public:
503
+   //!Returns the address of the stored
504
+   //!stream buffer.
505
+   basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
506
+   { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
507
+
508
+   //!Swaps the underlying vector with the passed vector.
509
+   //!This function resets the write position in the stream.
510
+   //!Does not throw.
511
+   void swap_vector(vector_type &vect)
512
+   {  get_buf().swap_vector(vect);   }
513
+
514
+   //!Returns a const reference to the internal vector.
515
+   //!Does not throw.
516
+   const vector_type &vector() const
517
+   {  return get_buf().vector();   }
518
+
519
+   //!Calls reserve() method of the internal vector.
520
+   //!Resets the stream to the first position.
521
+   //!Throws if the internals vector's reserve throws.
522
+   void reserve(typename vector_type::size_type size)
523
+   {  get_buf().reserve(size);   }
524
+};
525
+
526
+//!A basic_iostream class that holds a character vector specified by CharVector
527
+//!template parameter as its formatting buffer. The vector must have
528
+//!contiguous storage, like std::vector, boost::interprocess::vector or
529
+//!boost::interprocess::basic_string
530
+template <class CharVector, class CharTraits>
531
+class basic_vectorstream
532
+   : public std::basic_iostream<typename CharVector::value_type, CharTraits>
533
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
534
+   , private basic_vectorbuf<CharVector, CharTraits>
535
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
536
+{
537
+   public:
538
+   typedef CharVector                                                   vector_type;
539
+   typedef typename std::basic_ios
540
+      <typename CharVector::value_type, CharTraits>::char_type          char_type;
541
+   typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
542
+   typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
543
+   typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
544
+   typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
545
+
546
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
547
+   private:
548
+   typedef basic_vectorbuf<CharVector, CharTraits>    vectorbuf_t;
549
+   typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
550
+   typedef std::basic_iostream<char_type, CharTraits> base_t;
551
+
552
+   vectorbuf_t &       get_buf()      {  return *this;  }
553
+   const vectorbuf_t & get_buf() const{  return *this;  }
554
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
555
+
556
+   public:
557
+   //!Constructor. Throws if vector_type default
558
+   //!constructor throws.
559
+   basic_vectorstream(std::ios_base::openmode mode
560
+                      = std::ios_base::in | std::ios_base::out)
561
+      : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
562
+                  //(via basic_ios::init() call in base_t's constructor) without the risk of a
563
+                  //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
564
+      , vectorbuf_t(mode)
565
+   {  this->base_t::rdbuf(&get_buf()); }
566
+
567
+   //!Constructor. Throws if vector_type(const VectorParameter &param)
568
+   //!throws.
569
+   template<class VectorParameter>
570
+   basic_vectorstream(const VectorParameter &param, std::ios_base::openmode mode
571
+                      = std::ios_base::in | std::ios_base::out)
572
+      : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
573
+                  //(via basic_ios::init() call in base_t's constructor) without the risk of a
574
+                  //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
575
+      , vectorbuf_t(param, mode)
576
+   {  this->base_t::rdbuf(&get_buf()); }
577
+
578
+   public:
579
+   //Returns the address of the stored stream buffer.
580
+   basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
581
+   { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
582
+
583
+   //!Swaps the underlying vector with the passed vector.
584
+   //!This function resets the read/write position in the stream.
585
+   //!Does not throw.
586
+   void swap_vector(vector_type &vect)
587
+   {  get_buf().swap_vector(vect);   }
588
+
589
+   //!Returns a const reference to the internal vector.
590
+   //!Does not throw.
591
+   const vector_type &vector() const
592
+   {  return get_buf().vector();   }
593
+
594
+   //!Calls reserve() method of the internal vector.
595
+   //!Resets the stream to the first position.
596
+   //!Throws if the internals vector's reserve throws.
597
+   void reserve(typename vector_type::size_type size)
598
+   {  get_buf().reserve(size);   }
599
+
600
+   //!Calls clear() method of the internal vector.
601
+   //!Resets the stream to the first position.
602
+   void clear()
603
+   {  get_buf().clear();   }
604
+};
605
+
606
+//Some typedefs to simplify usage
607
+//!
608
+//!typedef basic_vectorbuf<std::vector<char> >        vectorbuf;
609
+//!typedef basic_vectorstream<std::vector<char> >     vectorstream;
610
+//!typedef basic_ivectorstream<std::vector<char> >    ivectorstream;
611
+//!typedef basic_ovectorstream<std::vector<char> >    ovectorstream;
612
+//!
613
+//!typedef basic_vectorbuf<std::vector<wchar_t> >     wvectorbuf;
614
+//!typedef basic_vectorstream<std::vector<wchar_t> >  wvectorstream;
615
+//!typedef basic_ivectorstream<std::vector<wchar_t> > wivectorstream;
616
+//!typedef basic_ovectorstream<std::vector<wchar_t> > wovectorstream;
617
+
618
+}} //namespace boost {  namespace interprocess {
619
+
620
+#include <boost/interprocess/detail/config_end.hpp>
621
+
622
+#endif /* BOOST_INTERPROCESS_VECTORSTREAM_HPP */