annotate DEPENDENCIES/generic/include/boost/format/alt_sstream_impl.hpp @ 133:4acb5d8d80b6 tip

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