]> git.donarmstrong.com Git - rsem.git/blob - boost/format/alt_sstream_impl.hpp
RSEM Source Codes
[rsem.git] / boost / format / alt_sstream_impl.hpp
1 // ----------------------------------------------------------------------------
2 //  alt_sstream_impl.hpp : alternative stringstream, templates implementation 
3 // ----------------------------------------------------------------------------
4
5 //  Copyright Samuel Krempp 2003. Use, modification, and distribution are
6 //  subject to the Boost Software License, Version 1.0. (See accompanying
7 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8
9 //  See http://www.boost.org/libs/format for library home page
10
11 // ----------------------------------------------------------------------------
12
13 #ifndef BOOST_SK_ALT_SSTREAM_IMPL_HPP
14 #define BOOST_SK_ALT_SSTREAM_IMPL_HPP
15
16 namespace boost {
17     namespace io {
18 // --- Implementation  ------------------------------------------------------//
19
20         template<class Ch, class Tr, class Alloc>
21         void basic_altstringbuf<Ch, Tr, Alloc>:: 
22         clear_buffer () {
23             const Ch * p = pptr();
24             const Ch * b = pbase();
25             if(p != NULL && p != b) {
26                 seekpos(0, ::std::ios_base::out); 
27             }
28             p = gptr();
29             b = eback();
30             if(p != NULL && p != b) {
31                 seekpos(0, ::std::ios_base::in); 
32             }
33         }
34
35         template<class Ch, class Tr, class Alloc>
36         void basic_altstringbuf<Ch, Tr, Alloc>:: 
37         str (const string_type& s) {
38             size_type sz=s.size();
39             if(sz != 0 && mode_ & (::std::ios_base::in | ::std::ios_base::out) ) {
40 #ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
41                 void *vd_ptr = alloc_.allocate(sz, is_allocated_? eback() : 0);
42                 Ch *new_ptr = static_cast<Ch *>(vd_ptr);
43 #else
44                 Ch *new_ptr = alloc_.allocate(sz, is_allocated_? eback() : 0);
45 #endif
46                 // if this didnt throw, we're safe, update the buffer
47                 dealloc();
48                 sz = s.copy(new_ptr, sz);
49                 putend_ = new_ptr + sz;
50                 if(mode_ & ::std::ios_base::in)
51                     streambuf_t::setg(new_ptr, new_ptr, new_ptr + sz);
52                 if(mode_ & ::std::ios_base::out) {
53                     streambuf_t::setp(new_ptr, new_ptr + sz);
54                     if(mode_ & (::std::ios_base::app | ::std::ios_base::ate))
55                         streambuf_t::pbump(static_cast<int>(sz));
56                     if(gptr() == NULL)
57                         streambuf_t::setg(new_ptr, NULL, new_ptr);
58                 }
59                 is_allocated_ = true;
60             }
61             else 
62                 dealloc();
63         }
64         template<class Ch, class Tr, class Alloc>
65         Ch*   basic_altstringbuf<Ch, Tr, Alloc>:: 
66         begin () const {
67             if(mode_ & ::std::ios_base::out && pptr() != NULL)
68                 return pbase();
69             else if(mode_ & ::std::ios_base::in && gptr() != NULL)
70                 return eback();
71             return NULL;
72         }
73
74         template<class Ch, class Tr, class Alloc>
75         typename std::basic_string<Ch,Tr,Alloc>::size_type
76         basic_altstringbuf<Ch, Tr, Alloc>:: 
77         size () const { 
78             if(mode_ & ::std::ios_base::out && pptr())
79                 return static_cast<size_type>(pend() - pbase());
80             else if(mode_ & ::std::ios_base::in && gptr())
81                 return static_cast<size_type>(egptr() - eback());
82             else 
83                 return 0;
84         }
85
86         template<class Ch, class Tr, class Alloc>
87         typename std::basic_string<Ch,Tr,Alloc>::size_type
88         basic_altstringbuf<Ch, Tr, Alloc>:: 
89         cur_size () const { 
90             if(mode_ & ::std::ios_base::out && pptr())
91                 return static_cast<streamsize>( pptr() - pbase());
92             else if(mode_ & ::std::ios_base::in && gptr())
93                 return static_cast<streamsize>( gptr() - eback());
94             else 
95                 return 0;
96         }
97
98         template<class Ch, class Tr, class Alloc>
99         typename basic_altstringbuf<Ch, Tr, Alloc>::pos_type  
100         basic_altstringbuf<Ch, Tr, Alloc>:: 
101         seekoff (off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) {
102             if(pptr() != NULL && putend_ < pptr())
103                 putend_ = pptr();
104             if(which & ::std::ios_base::in && gptr() != NULL) {
105                 // get area
106                 if(way == ::std::ios_base::end)
107                     off += static_cast<off_type>(putend_ - gptr());
108                 else if(way == ::std::ios_base::beg)
109                     off += static_cast<off_type>(eback() - gptr());
110                 else if(way != ::std::ios_base::cur || (which & ::std::ios_base::out) )
111                     // (altering in&out is only supported if way is beg or end, not cur)
112                     return pos_type(off_type(-1));
113                 if(eback() <= off+gptr() && off+gptr() <= putend_ ) {
114                     // set gptr
115                     streambuf_t::gbump(static_cast<int>(off));
116                     if(which & ::std::ios_base::out && pptr() != NULL)
117                         // update pptr to match gptr
118                         streambuf_t::pbump(static_cast<int>(gptr()-pptr()));
119                 }
120                 else
121                     off = off_type(-1);
122             }
123             else if(which & ::std::ios_base::out && pptr() != NULL) {
124                 // put area
125                 if(way == ::std::ios_base::end)
126                     off += static_cast<off_type>(putend_ - pptr());
127                 else if(way == ::std::ios_base::beg)
128                     off += static_cast<off_type>(pbase() - pptr());
129                 else if(way != ::std::ios_base::beg)
130                     return pos_type(off_type(-1));                    
131                 if(pbase() <= off+pptr() && off+pptr() <= putend_)
132                     // set pptr
133                     streambuf_t::pbump(static_cast<int>(off)); 
134                 else
135                     off = off_type(-1);
136             }
137             else // neither in nor out
138                 off = off_type(-1);
139             return (pos_type(off));
140         }
141         //- end seekoff(..)
142
143         
144         template<class Ch, class Tr, class Alloc>
145         typename basic_altstringbuf<Ch, Tr, Alloc>::pos_type 
146         basic_altstringbuf<Ch, Tr, Alloc>:: 
147         seekpos (pos_type pos, ::std::ios_base::openmode which) {
148             off_type off = off_type(pos); // operation guaranteed by 27.4.3.2 table 88
149             if(pptr() != NULL && putend_ < pptr())
150                 putend_ = pptr();
151             if(off != off_type(-1)) {
152                 if(which & ::std::ios_base::in && gptr() != NULL) {
153                     // get area
154                     if(0 <= off && off <= putend_ - eback()) {
155                         streambuf_t::gbump(static_cast<int>(eback() - gptr() + off));
156                         if(which & ::std::ios_base::out && pptr() != NULL) {
157                             // update pptr to match gptr
158                             streambuf_t::pbump(static_cast<int>(gptr()-pptr()));
159                         }
160                     }
161                     else
162                         off = off_type(-1);
163                 }
164                 else if(which & ::std::ios_base::out && pptr() != NULL) {
165                     // put area
166                     if(0 <= off && off <= putend_ - eback())
167                         streambuf_t::pbump(static_cast<int>(eback() - pptr() + off));
168                     else
169                         off = off_type(-1);
170                 }
171                 else // neither in nor out
172                     off = off_type(-1);
173                 return (pos_type(off));
174             }
175             else {
176                 BOOST_ASSERT(0); // ยง27.4.3.2 allows undefined-behaviour here
177                 return pos_type(off_type(-1));
178             }
179         }
180         // -end seekpos(..)
181
182
183         template<class Ch, class Tr, class Alloc>
184         typename basic_altstringbuf<Ch, Tr, Alloc>::int_type
185         basic_altstringbuf<Ch, Tr, Alloc>:: 
186         underflow () {
187             if(gptr() == NULL) // no get area -> nothing to get.
188                 return (compat_traits_type::eof()); 
189             else if(gptr() < egptr())  // ok, in buffer
190                 return (compat_traits_type::to_int_type(*gptr())); 
191             else if(mode_ & ::std::ios_base::in && pptr() != NULL
192                     && (gptr() < pptr() || gptr() < putend_) )
193                 {  // expand get area 
194                     if(putend_ < pptr()) 
195                         putend_ = pptr(); // remember pptr reached this far
196                     streambuf_t::setg(eback(), gptr(), putend_);
197                     return (compat_traits_type::to_int_type(*gptr()));
198                 }
199             else // couldnt get anything. EOF.
200                 return (compat_traits_type::eof());
201         }
202         // -end underflow(..)
203
204
205         template<class Ch, class Tr, class Alloc>
206         typename basic_altstringbuf<Ch, Tr, Alloc>::int_type 
207         basic_altstringbuf<Ch, Tr, Alloc>:: 
208         pbackfail (int_type meta) {
209             if(gptr() != NULL  &&  (eback() < gptr()) 
210                && (mode_ & (::std::ios_base::out)
211                    || compat_traits_type::eq_int_type(compat_traits_type::eof(), meta)
212                    || compat_traits_type::eq(compat_traits_type::to_char_type(meta), gptr()[-1]) ) ) { 
213                 streambuf_t::gbump(-1); // back one character
214                 if(!compat_traits_type::eq_int_type(compat_traits_type::eof(), meta))
215                     //  put-back meta into get area
216                     *gptr() = compat_traits_type::to_char_type(meta);
217                 return (compat_traits_type::not_eof(meta));
218             }
219             else
220                 return (compat_traits_type::eof());  // failed putback
221         }
222         // -end pbackfail(..)
223
224
225         template<class Ch, class Tr, class Alloc>
226         typename basic_altstringbuf<Ch, Tr, Alloc>::int_type 
227         basic_altstringbuf<Ch, Tr, Alloc>:: 
228         overflow (int_type meta) {
229 #ifdef BOOST_MSVC
230 #pragma warning(push)
231 #pragma warning(disable:4996)
232 #endif
233             if(compat_traits_type::eq_int_type(compat_traits_type::eof(), meta))
234                 return compat_traits_type::not_eof(meta); // nothing to do
235             else if(pptr() != NULL && pptr() < epptr()) {
236                 streambuf_t::sputc(compat_traits_type::to_char_type(meta));
237                 return meta;
238             }
239             else if(! (mode_ & ::std::ios_base::out)) 
240                 // no write position, and cant make one
241                 return compat_traits_type::eof(); 
242             else { // make a write position available
243                 std::size_t prev_size = pptr() == NULL ? 0 : epptr() - eback();
244                 std::size_t new_size = prev_size;
245                 // exponential growth : size *= 1.5
246                 std::size_t add_size = new_size / 2;
247                 if(add_size < alloc_min)
248                     add_size = alloc_min;
249                 Ch * newptr = NULL,  *oldptr = eback();
250
251                 // make sure adding add_size wont overflow size_t
252                 while (0 < add_size && ((std::numeric_limits<std::size_t>::max)()
253                                         - add_size < new_size) )
254                     add_size /= 2;
255                 if(0 < add_size) {
256                     new_size += add_size;
257 #ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
258                     void *vdptr = alloc_.allocate(new_size, is_allocated_? oldptr : 0);
259                     newptr = static_cast<Ch *>(vdptr);
260 #else
261                     newptr = alloc_.allocate(new_size, is_allocated_? oldptr : 0);
262 #endif
263                 }
264
265                 if(0 < prev_size)
266                     compat_traits_type::copy(newptr, oldptr, prev_size);
267                 if(is_allocated_)
268                     alloc_.deallocate(oldptr, prev_size);
269                 is_allocated_=true;
270
271                 if(prev_size == 0) { // first allocation
272                     putend_ = newptr;
273                     streambuf_t::setp(newptr, newptr + new_size);
274                     if(mode_ & ::std::ios_base::in)
275                         streambuf_t::setg(newptr, newptr, newptr + 1);
276                     else
277                         streambuf_t::setg(newptr, 0, newptr);
278                 }
279                 else { // update pointers
280                     putend_ = putend_ - oldptr + newptr;
281                     int pptr_count = static_cast<int>(pptr()-pbase());
282                     int gptr_count = static_cast<int>(gptr()-eback());
283                     streambuf_t::setp(pbase() - oldptr + newptr, newptr + new_size);
284                     streambuf_t::pbump(pptr_count);
285                     if(mode_ & ::std::ios_base::in)
286                         streambuf_t::setg(newptr, newptr + gptr_count, pptr() + 1);
287                     else
288                         streambuf_t::setg(newptr, 0, newptr);
289                 }
290                 streambuf_t::sputc(compat_traits_type::to_char_type(meta));
291                 return meta;
292             }
293 #ifdef BOOST_MSVC
294 #pragma warning(pop)
295 #endif
296         }
297         // -end overflow(..)
298
299         template<class Ch, class Tr, class Alloc>
300         void basic_altstringbuf<Ch, Tr, Alloc>:: dealloc() {
301             if(is_allocated_)
302                 alloc_.deallocate(eback(), (pptr() != NULL ? epptr() : egptr()) - eback());
303             is_allocated_ = false;
304             streambuf_t::setg(0, 0, 0);
305             streambuf_t::setp(0, 0);
306             putend_ = NULL;
307         }
308
309     }// N.S. io
310 } // N.S. boost
311
312 #endif // include guard
313