BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_stringbuf.h
Go to the documentation of this file.
1/// @file bslstl_stringbuf.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_stringbuf.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_STRINGBUF
9#define INCLUDED_BSLSTL_STRINGBUF
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_stringbuf bslstl_stringbuf
15/// @brief Provide a C++03-compatible `stringbuf` class.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_stringbuf
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_stringbuf-purpose"> Purpose</a>
25/// * <a href="#bslstl_stringbuf-classes"> Classes </a>
26/// * <a href="#bslstl_stringbuf-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_stringbuf-description"> Description </a>
28/// * <a href="#bslstl_stringbuf-memory-allocation"> Memory Allocation </a>
29/// * <a href="#bslstl_stringbuf-bslma-style-allocators"> bslma-Style Allocators </a>
30/// * <a href="#bslstl_stringbuf-usage"> Usage </a>
31/// * <a href="#bslstl_stringbuf-example-1-basic-operations"> Example 1: Basic Operations </a>
32///
33/// # Purpose {#bslstl_stringbuf-purpose}
34/// Provide a C++03-compatible `stringbuf` class.
35///
36/// # Classes {#bslstl_stringbuf-classes}
37///
38/// - bsl::stringbuf: C++03-compatible `stringbuf` class
39/// - bsl::StringBufContainer: wrapper for @ref basic_stringbuf
40///
41/// # Canonical Header {#bslstl_stringbuf-canonical-header}
42/// bsl_sstream.h
43///
44/// @see bslstl_stringstream, bslstl_ostringstream, bslstl_istringstream
45///
46/// # Description {#bslstl_stringbuf-description}
47/// This component is for internal use only. Please include
48/// `<bsl_sstream.h>` instead.
49///
50/// This component defines a class template, `bsl::basic_stringbuf`, that
51/// implements a standard string buffer, providing an unformatted character
52/// input sequence and an unformatted character output sequence that
53/// may be initialized or accessed using a string value (see 27.8.2 [stringbuf]
54/// of the C++11 standard). This component also defines two standard aliases,
55/// `bsl::stringbuf` and `bsl::wstringbuf`, that refer to specializations of the
56/// `bsl::basic_stringbuf` template for `char` and `wchar_t` types,
57/// respectively. As with any stream buffer class, `bsl::basic_stringbuf` is
58/// rarely used directly. Stream buffers provide low-level unformatted
59/// input/output. They are usually plugged into `std::basic_stream` classes to
60/// provide higher-level formatted input and output via `operator>>` and
61/// `operator<<`. `bsl::basic_stringbuf` is used in the
62/// `bsl::basic_stringstream` family of classes and users should prefer those
63/// classes over direct use of `bsl::basic_stringbuf`.
64///
65/// `bsl::basic_stringbuf` derives from `std::basic_streambuf` and implements
66/// the necessary protected virtual methods. In this way `bsl::basic_stringbuf`
67/// customizes the behavior of `std::basic_streambuf` to redirect the reading
68/// and writing of characters to an internally-maintained sequence of characters
69/// that can be initialized or accessed using a `bsl::basic_string`. Note that
70/// although the standard mandates functions that access and modify the
71/// buffered sequence using a @ref basic_string , it does not mandate that a
72/// @ref basic_stringbuf internally store this buffer in a @ref basic_string ; this
73/// implementation currently uses a @ref basic_string as its internal buffer, but
74/// that is subject to change without warning.
75///
76/// The `bsl::stringbuf` template has three parameters, `CHAR_TYPE`,
77/// `CHAR_TRAITS`, and `ALLOCATOR`. The `CHAR_TYPE` and `CHAR_TRAITS`
78/// parameters respectively define the character type for the stream buffer and
79/// a type providing a set of operations the stream buffer will use to
80/// manipulate characters of that type, which must meet the character traits
81/// requirements defined by the C++11 standard, 21.2 [char.traits]. The
82/// `ALLOCATOR` template parameter is described in the "Memory Allocation"
83/// section below.
84///
85/// ## Memory Allocation {#bslstl_stringbuf-memory-allocation}
86///
87///
88/// The type supplied as a stream buffer's `ALLOCATOR` template parameter
89/// determines how that stream buffer will allocate memory. The
90/// @ref basic_stringbuf template supports allocators meeting the requirements
91/// of the C++11 standard, 17.6.3.5 [allocator.requirements]; in addition, it
92/// supports scoped-allocators derived from the `bslma::Allocator` memory
93/// allocation protocol. Clients intending to use `bslma`-style allocators
94/// should use `bsl::allocator`, which provides a C++11 standard-compatible
95/// adapter for a `bslma::Allocator` object. Note that the standard aliases
96/// `bsl::stringbuf` and `bsl::wstringbuf` both use `bsl::allocator`.
97///
98/// ### bslma-Style Allocators {#bslstl_stringbuf-bslma-style-allocators}
99///
100///
101/// If the type supplied for the `ALLOCATOR` template parameter of a `stringbuf`
102/// instantiation is `bsl::allocator`, then objects of that stream buffer type
103/// will conform to the standard behavior of a `bslma`-allocator-enabled type.
104/// Such a stream buffer accepts an optional `bslma::Allocator` argument at
105/// construction. If the address of a `bslma::Allocator` object is explicitly
106/// supplied at construction, it will be used to supply memory for the stream
107/// buffer throughout its lifetime; otherwise, the stream buffer will use the
108/// default allocator installed at the time of the stream buffer's construction
109/// (see @ref bslma_default ).
110///
111/// ## Usage {#bslstl_stringbuf-usage}
112///
113///
114/// This section illustrates intended use of this component.
115///
116/// ### Example 1: Basic Operations {#bslstl_stringbuf-example-1-basic-operations}
117///
118///
119/// The following example demonstrates the use of `bsl::stringbuf` to read and
120/// write character data from and to a `bsl::string` object.
121///
122/// Suppose we want to implement a simplified converter from `unsigned int` to
123/// `bsl::string` and back. First, we define the prototypes of two conversion
124/// functions:
125/// @code
126/// bsl::string toString(unsigned int from);
127/// unsigned int fromString(const bsl::string& from);
128/// @endcode
129/// Then, we use `bsl::stringbuf` to implement the `toString` function. We
130/// write all digits into `bsl::stringbuf` individually using `sputc` methods
131/// and then return the resulting `bsl::string` object:
132/// @code
133/// #include <algorithm>
134///
135/// bsl::string toString(unsigned int from)
136/// {
137/// bsl::stringbuf out;
138///
139/// for (; from != 0; from /= 10) {
140/// out.sputc('0' + from % 10);
141/// }
142///
143/// bsl::string result(out.str());
144/// std::reverse(result.begin(), result.end());
145/// return result;
146/// }
147/// @endcode
148/// Now, we implement the `fromString` function that converts from
149/// `bsl::string` to `unsigned int` by using `bsl::stringbuf` to read individual
150/// digits from the string object:
151/// @code
152/// unsigned int fromString(const bsl::string& from)
153/// {
154/// unsigned int result = 0;
155///
156/// for (bsl::stringbuf in(from); in.in_avail(); ) {
157/// result = result * 10 + (in.sbumpc() - '0');
158/// }
159///
160/// return result;
161/// }
162/// @endcode
163/// Finally, we verify that the result of the round-trip conversion is identical
164/// to the original value:
165/// @code
166/// unsigned int orig = 92872498;
167/// unsigned int result = fromString(toString(orig));
168///
169/// assert(orig == result);
170/// @endcode
171/// @}
172/** @} */
173/** @} */
174
175/** @addtogroup bsl
176 * @{
177 */
178/** @addtogroup bslstl
179 * @{
180 */
181/** @addtogroup bslstl_stringbuf
182 * @{
183 */
184
185#include <bslscm_version.h>
186
187#include <bslstl_iosfwd.h>
188#include <bslstl_string.h>
189#include <bslstl_stringview.h>
191
192#include <bslalg_swaputil.h>
193
194#include <bslma_isstdallocator.h>
195#include <bslma_bslallocator.h>
197
198#include <bslmf_enableif.h>
199#include <bslmf_issame.h>
200#include <bslmf_movableref.h>
201
202#include <bsls_assert.h>
204#include <bsls_keyword.h>
205#include <bsls_libraryfeatures.h>
206#include <bsls_platform.h>
207
208#include <algorithm>
209#include <cstddef>
210#include <ios>
211#include <istream>
212#include <ostream>
213#include <streambuf>
214
215#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE
216# include <utility>
217#endif
218#include <limits.h> // for 'INT_MAX', 'INT_MIN'
219
220#ifndef BDE_OMIT_INTERNAL_DEPRECATED
221#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
222#include <bslalg_typetraits.h>
223#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
224#endif // BDE_OMIT_INTERNAL_DEPRECATED
225
226
227// 'BSLS_ASSERT' filename fix -- See @ref bsls_assertimputil
228#ifdef BSLS_ASSERTIMPUTIL_AVOID_STRING_CONSTANTS
229extern const char s_bslstl_stringbuf_h[];
230#undef BSLS_ASSERTIMPUTIL_FILE
231#define BSLS_ASSERTIMPUTIL_FILE BloombergLP::s_bslstl_stringbuf_h
232#endif
233}
234
235namespace bsl {
236
237using std::ios_base;
238
239 // =====================
240 // class basic_stringbuf
241 // =====================
242
243/// This class implements a standard stream buffer providing an unformatted
244/// character input sequence and an unformatted character output sequence
245/// that may be initialized or accessed using a string value.
246template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
248 : public std::basic_streambuf<CHAR_TYPE, CHAR_TRAITS> {
249
250 private:
251 // PRIVATE TYPES
252 typedef std::basic_streambuf<CHAR_TYPE, CHAR_TRAITS> BaseType;
255
256 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
257
258 public:
259 // TYPES
260 typedef CHAR_TYPE char_type;
262 typedef ALLOCATOR allocator_type;
263 typedef typename traits_type::int_type int_type;
264 typedef typename traits_type::off_type off_type;
265 typedef typename traits_type::pos_type pos_type;
266
267 private:
268 // DATA
269 StringType d_str; // internal character sequence buffer
270
271 off_type d_endHint;
272 // offset to one past the last known good
273 // character in `d_str` (Note that to enable
274 // efficient buffering, `d_str` may be resized
275 // beyond the last written character, so
276 // `d_str.size()` may not accurately report
277 // the current length of the character
278 // sequence available for input. Extending
279 // the size of `d_str` and updating `epptr`
280 // (the end-of-output pointer) allows the
281 // parent stream type to write additional
282 // characters without `overflow`. However,
283 // care must be taken to refresh the cached
284 // `d_endHint` value as the parent stream will
285 // update the current output position `pptr`,
286 // without calling a method on this type.)
287
288 ios_base::openmode d_mode; // `stringbuf` open mode (`in`, `out`, or both)
289
290 private:
291 // NOT IMPLEMENTED
292 basic_stringbuf(const basic_stringbuf&); // = delete
293 basic_stringbuf& operator=(const basic_stringbuf&); // = delete
294
295 private:
296 // PRIVATE MANIPULATORS
297
298 /// Update the input pointers (`eback`, `gptr`, `egptr`) of this string
299 /// buffer, setting the beginning of the input sequence, `eback`, to the
300 /// address of the first character of the internal string
301 /// representation, `d_str`, the current position of the input sequence,
302 /// `gptr`, to the specified `currentInputPosition`, and the address
303 /// past the end of the accessible sequence, `egptr`, to the last
304 /// character in `d_ptr` (`&d_ptr[0] + d_endHint`). Return the offset
305 /// of the current position of the input sequence from the start of the sequence.
306 ///
307 /// \pre The behavior is undefined unless this buffer is in input
308 /// mode and `currentInputPosition` is within the range of accessible
309 /// characters in `d_ptr`.
310 pos_type updateInputPointers(char_type *currentInputPosition);
311
312 /// Update the output pointers (`pback`, `pptr`, `epptr`) of this string
313 /// buffer, setting the beginning of the output sequence, `pback`, to
314 /// the address of the first character of the internal string
315 /// representation, `d_str`, the current position of the output
316 /// sequence, `pptr`, to the specified `currentOutputPosition`, and the
317 /// address past the end of the accessible sequence, `epptr`, to one
318 /// past the last character in `d_ptr` (`&d_ptr[0] + d_ptr.size()`).
319 /// Return the offset of the current position of the output sequence from the start of the sequence.
320 ///
321 /// \pre The behavior is undefined unless
322 /// this buffer is in output mode, and `currentOutputPosition` is within
323 /// the range of accessible characters in `d_ptr`.
324 pos_type updateOutputPointers(char_type *currentOutputPosition);
325
326 /// Update the input and output positions of this string buffer object
327 /// according to the current state of the internal string representation
328 /// `d_ptr`. Optionally specify an `inputOffset` indicating the current
329 /// input position's offset from the beginning of the sequence.
330 /// Optionally specify an `outputOffset` indicating the current output
331 /// position's offset from the beginning of the sequence. If this
332 /// buffer is in output mode, set the beginning of the output sequence,
333 /// `pback`, to the address of the first character of `d_ptr`, the
334 /// current output position, `pptr`, to `pback + outputOffset`, and the
335 /// end of the output sequence, `epptr`, to one past the last character
336 /// in `d_str` (`&d_ptr[0] + d_ptr.size()`). If this buffer is in input
337 /// mode, set the beginning of the input sequence, `eback`, to the
338 /// address of the first character of `d_ptr`, the current input
339 /// position, `gptr`, to `eback + inputOffset`, and the end of the input
340 /// sequence, `egptr`, to the last written character in `d_str`
341 /// (`&d_ptr[0] + d_endHint`).
342 void updateStreamPositions(off_type inputOffset = 0,
343 off_type outputOffset = 0);
344
345 /// Attempt to expand the sequence of characters available for input
346 /// (i.e., update the end of input buffer position, `egptr`) to
347 /// incorporate additional characters that may have been written (as
348 /// output) to the stream. Return `true` if the input buffer was successfully extended, and `false` otherwise.
349 ///
350 /// \note Note that the input
351 /// area as described by `eback`, `gptr`, and `egptr` may become out of
352 /// sync with the characters actually available in the buffer as the
353 /// parent @ref basic_streambuf type may perform writes into the output
354 /// area (using `pbase`, `pptr`, and `epptr`) without calling any
355 /// methods of this object.
356 bool extendInputArea();
357
358 // PRIVATE ACCESSORS
359
360 /// Return the number of characters currently in the buffer. Note this
361 /// may not be `d_str.size()`, as this implementation resizes `d_str`
362 /// beyond the number of written characters to provide more efficient
363 /// buffering, and it also may not be `d_endHint`, as that value may
364 /// currently be stale (as writes may have been performed through the
365 /// parent @ref basic_streambuf type without calling a method on this
366 /// object).
367 pos_type streamSize() const;
368
369 /// Return `true` if pointers form a valid range
370 /// (`first <= middle <= last`) and `first == d_str.data()` and
371 /// `middle` and `last` are in the range
372 /// `[d_str.data() .. d_str.data() + d_str.size()]`, or all arguments are 0, and `false` otherwise.
373 ///
374 /// \note Note that this function is called in
375 /// defensive (i.e., "DEBUG" or "SAFE") build modes only.
376 bool arePointersValid(const char_type *first,
377 const char_type *middle,
378 const char_type *last) const;
379
380 protected:
381 // PROTECTED MANIPULATORS
382
383 /// Set the current input position or the current output position (or
384 /// both) to the specified `offset` from the specified `whence`
385 /// location. Optionally specify a `modeBitMask` indicating whether to
386 /// set the current input position, current output position, or both.
387 /// If `whence` is `ios_base::beg`, set the current position to the
388 /// indicated `offset` from the beginning of the stream; if `whence` is
389 /// `ios_base::end`, set the current position to the indicated `offset`
390 /// from the end of the stream; and if `whence` is `ios_base::cur`, set
391 /// the current input or output position to the indicated `offset` from
392 /// its current position. If `whence` is `ios_base::cur`, then
393 /// `modeBitMask` may be either `ios_base::in` or `ios_base::out`, but
394 /// not both. Return the offset of the new position on success, and
395 /// `pos_type(off_type(-1))` otherwise.
396 virtual pos_type seekoff(
397 off_type offset,
398 ios_base::seekdir whence,
399 ios_base::openmode modeBitMask = ios_base::in | ios_base::out);
400
401 /// Set the current input position or the current output position (or
402 /// both) to the specified `absoluteOffset` from the beginning of the
403 /// stream. Optionally specify a `modeBitMask` indicating whether to
404 /// set the current input position, current output position, or both.
405 /// Return the offset of the new position on success, and
406 /// `pos_type(off_type(-1))` otherwise.
407 virtual pos_type seekpos(
408 pos_type absoluteOffset,
409 ios_base::openmode modeBitMask = ios_base::in | ios_base::out);
410
411 /// Read up to the specified `numCharacters` from this `stringbuf`
412 /// object and store them in the specified `result` array. Return the number of characters loaded into `result`.
413 ///
414 /// \note Note that if fewer than
415 /// `numCharacters` characters are available in the buffer, all
416 /// available characters are loaded into `result`.
417 ///
418 /// \pre The behavior is undefined unless `result` refers to a contiguous sequence of at
419 /// least `numCharacters` characters.
420 virtual std::streamsize xsgetn(char_type *result,
421 std::streamsize numCharacters);
422
423 /// Return the character at the current input position, if a character
424 /// is available, and `traits_type::eof()` otherwise. Update the end
425 /// of the input area, `egptr`, if additional characters are available
426 /// (as may occur if additional characters have been written to the string buffer).
427 ///
428 /// \note Note that this operation is similar to `uflow`,
429 /// but does not advance the current input position.
430 virtual int_type underflow();
431
432 /// Return the character at the current input position and advance the
433 /// input position by 1. If no character is available at the current
434 /// input position, return `traits_type::eof()`. Update the end of the
435 /// input area, `egptr`, if additional characters are available (as may
436 /// occur if additional characters have been written to the string buffer).
437 ///
438 /// \note Note that this operation is similar to `underflow`, but
439 /// advances the current input position.
440 virtual int_type uflow();
441
442 /// Put back the specified `character` into the input sequence so that
443 /// the next character read from the input sequence will be
444 /// `character`. If `character` is either `traits_type::eof()` or is
445 /// the same as the previously read character from the input sequence,
446 /// then adjust the current input position, `gptr`, back one position.
447 /// If `character` is neither `traits_type::eof()` nor the character
448 /// previously read from the input sequence, but this string buffer was
449 /// opened for writing (`ios_base::out`), then adjust the input
450 /// sequence back one position and write `character` to that position.
451 /// Return the character that was put back on success and
452 /// `traits_type::eof()` if either the input position is currently at
453 /// the beginning of the sequence or if the previous character in the
454 /// input sequence is not `character` and this buffer was not opened
455 /// for writing.
456 virtual int_type pbackfail(int_type character = traits_type::eof());
457
458 /// Append the specified `numCharacters` from the specified
459 /// `inputString` to the output sequence starting at the current output
460 /// position (`pptr`). Update the current output position of this
461 /// string buffer to refer to the last appended character. Return the
462 /// number of characters that were appended.
463 ///
464 /// \pre The behavior is undefined unless `inputString` refers to a contiguous sequence of at least
465 /// `numCharacters` characters.
466 virtual std::streamsize xsputn(const char_type *inputString,
467 std::streamsize numCharacters);
468
469 /// Append the specified `character` to the output sequence of this
470 /// stream buffer at the current output position (`pptr`), and advance
471 /// the output position by one. This operation may update the end of
472 /// output area (`epptr`) to allow for additional writes (e.g., by the
473 /// base @ref basic_streambuf type) to the output sequence without calling
474 /// a method on this type. Return the written character on success, and
475 /// `traits_type::eof()` if `character` is `traits_type::eof()` or this
476 /// stream buffer was not opened for writing.
477 virtual int_type overflow(int_type character = traits_type::eof());
478
479 public:
480 // CREATORS
481
482 /// Create a @ref basic_stringbuf object. Optionally specify a
483 /// `modeBitMask` indicating whether this buffer may be read from,
484 /// written to, or both. If `modeBitMask` is not supplied, this buffer
485 /// is created with `ios_base::in | ios_base::out`. Optionally specify
486 /// an `initialString` indicating the initial sequence of characters
487 /// that this buffer will access or manipulate. If `initialString` is
488 /// not supplied, the initial sequence of characters will be empty.
489 /// Optionally specify the `allocator` used to supply memory. If
490 /// `allocator` is not supplied, a default-constructed object of the
491 /// (template parameter) `ALLOCATOR` type is used. If the `ALLOCATOR`
492 /// argument is of type `bsl::allocator` (the default), then
493 /// `allocator`, if supplied, shall be convertible to
494 /// `bslma::Allocator *`. If the `ALLOCATOR` argument is of type
495 /// `bsl::allocator` and `allocator` is not supplied, the currently
496 /// installed default allocator will be used to supply memory.
497 explicit
499 explicit
500 basic_stringbuf(ios_base::openmode modeBitMask,
502 explicit
503 basic_stringbuf(const StringType& initialString,
505 basic_stringbuf(const StringType& initialString,
506 ios_base::openmode modeBitMask,
508
509 /// Create a @ref basic_stringbuf object. Use the specified
510 /// `initialString` indicating the initial sequence of characters that
511 /// this buffer will access or manipulate. Optionally specify a
512 /// `modeBitMask` indicating whether this buffer may be read from,
513 /// written to, or both. If `modeBitMask` is not supplied, this buffer
514 /// is created with `ios_base::in | ios_base::out`. Optionally specify
515 /// the `allocator` used to supply memory. If `allocator` is not
516 /// supplied, the allocator in `initialString` is used. `initialString`
517 /// is left in a valid but unspecified state.
518 explicit
519 basic_stringbuf(BloombergLP::bslmf::MovableRef<StringType>
520 initialString);
521 basic_stringbuf(BloombergLP::bslmf::MovableRef<StringType>
522 initialString,
524 basic_stringbuf(BloombergLP::bslmf::MovableRef<StringType>
525 initialString,
526 ios_base::openmode modeBitMask);
527 basic_stringbuf(BloombergLP::bslmf::MovableRef<StringType>
528 initialString,
529 ios_base::openmode modeBitMask,
531
532 /// Create a @ref basic_stringbuf object. Use the specified
533 /// `initialString` indicating the initial sequence of characters that
534 /// this buffer will access or manipulate. Optionally specify the
535 /// `allocator` used to supply memory. If `allocator` is not supplied,
536 /// a default-constructed object of the (template parameter) `ALLOCATOR`
537 /// type is used. If the `ALLOCATOR` argument is of type
538 /// `bsl::allocator` (the default), then `allocator`, if supplied, shall
539 /// be convertible to `bslma::Allocator *`. If the `ALLOCATOR` argument
540 /// is of type `bsl::allocator` and `allocator` is not supplied, the
541 /// currently installed default allocator will be used to supply memory.
542 template <class SALLOC>
543 explicit
546 initialString,
548 typename bsl::enable_if<
549 !bsl::is_same<ALLOCATOR, SALLOC>::value, void *>::type = 0)
550
551 : BaseType()
552 , d_str(initialString.data(), initialString.size(), allocator)
553 , d_endHint(initialString.size())
554 , d_mode(ios_base::in | ios_base::out)
555 {
556 // Note: implemented inline due to Sun CC compilation error.
557 updateStreamPositions();
558 }
559
560 /// Create a @ref basic_stringbuf object. Use the specified
561 /// `initialString` indicating the initial sequence of characters that
562 /// this buffer will access or manipulate. Use the specified
563 /// `modeBitMask` to indicate whether this buffer may be read from,
564 /// written to, or both. Optionally specify the `allocator` used to
565 /// supply memory. If `allocator` is not supplied, a
566 /// default-constructed object of the (template parameter) `allocator_type`
567 /// is used. If the `ALLOCATOR` argument is of type `bsl::allocator` (the
568 /// default), then `allocator`, if supplied, shall be convertible to
569 /// `bslma::Allocator *`. If the `ALLOCATOR` argument is of type
570 /// `bsl::allocator` and `allocator` is not supplied, the currently
571 /// installed default allocator will be used to supply memory.
572 template <class SALLOC>
575 initialString,
576 ios_base::openmode modeBitMask,
578 typename bsl::enable_if<
579 !bsl::is_same<ALLOCATOR, SALLOC>::value, void *>::type = 0)
580 : BaseType()
581 , d_str(initialString.data(), initialString.size(), allocator)
582 , d_endHint(initialString.size())
583 , d_mode(modeBitMask)
584 {
585 // Note: implemented inline due to Sun CC compilation error.
586 updateStreamPositions(0, d_mode & ios_base::ate ? d_endHint : 0);
587 }
588
589 /// Create a @ref basic_stringbuf object. Use the specified `initialString`
590 /// (of a type convertible to `basic_string_view<CHAR_TYPE, CHAR_TRAITS>`
591 /// but not to `const CHAR_TYPE *`) indicating the initial sequence of
592 /// characters that this buffer will access or manipulate. Optionally
593 /// specify the `allocator` used to supply memory. If `allocator` is not
594 /// supplied, a default-constructed object of the (template parameter)
595 /// `ALLOCATOR` type is used. If the `ALLOCATOR` argument is of type
596 /// `bsl::allocator` (the default), then `allocator`, if supplied, shall be
597 /// convertible to `bslma::Allocator *`. If the `ALLOCATOR` argument is of
598 /// type `bsl::allocator` and `allocator` is not supplied, the currently
599 /// installed default allocator will be used to supply to supply memory.
600 /// This buffer is created with `ios_base::in | ios_base::out`.
601 template <class STRING_VIEW_LIKE_TYPE>
602 explicit
604 const STRING_VIEW_LIKE_TYPE& initialString,
607 : BaseType()
608 , d_str(ViewType(initialString).data(),
609 ViewType(initialString).size(),
610 allocator)
611 , d_endHint(ViewType(initialString).size())
612 , d_mode(ios_base::in | ios_base::out)
613 {
614 // Note: implemented inline due to Sun CC compilation error.
615 updateStreamPositions();
616 }
617
618 /// Create a @ref basic_stringbuf object. Use the specified `initialString`
619 /// (of a type convertible to `basic_string_view<CHAR_TYPE, CHAR_TRAITS>`
620 /// but not to `const CHAR_TYPE *`) indicating the initial sequence of
621 /// characters that this buffer will access or manipulate. Use the
622 /// specified `modeBitMask` to indicate whether this buffer may be read
623 /// from, written to, or both. Optionally specify the `allocator` used to
624 /// supply memory. If `allocator` is not supplied, a default-constructed
625 /// object of `allocator_type` is used. If the `ALLOCATOR` argument is of
626 /// type bsl::allocator` (the default), then `allocator`, if supplied,
627 /// shall be convertible to `bslma::Allocator *`. If the `ALLOCATOR`
628 /// argument is of type `bsl::allocator` and `allocator` is not
629 /// supplied, the currently installed default allocator will be used
630 /// to supply memory.
631 template <class STRING_VIEW_LIKE_TYPE>
632 basic_stringbuf(const STRING_VIEW_LIKE_TYPE &initialString,
633 ios_base::openmode modeBitMask,
636 : BaseType(),
637 d_str(ViewType(initialString).data(),
638 ViewType(initialString).size(),
639 allocator)
640 , d_endHint(ViewType(initialString).size())
641 , d_mode(modeBitMask)
642 {
643 // Note: implemented inline due to Sun CC compilation error.
644 updateStreamPositions(0, d_mode & ios_base::ate ? d_endHint : 0);
645 }
646
647#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE
648 /// Create a @ref basic_stringbuf object having the same value as the
649 /// specified `original` object by moving the contents of `original` to
650 /// the newly-created object. Optionally specify the `allocator` used
651 /// to supply memory. `original` is left in a valid but unspecified
652 /// state.
653 // NOLINTNEXTLINE(performance-noexcept-move-constructor)
657#endif
658
659 /// Destroy this object.
661
662 // MANIPULATORS
663
664#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE
665 /// Assign to this object the value of the specified `rhs`, and return a
666 /// reference providing modifiable access to this object. The contents
667 /// of `rhs` are move-assigned to this object. `rhs` is left in a valid
668 /// but unspecified state.
669 // NOLINTNEXTLINE(performance-noexcept-move-constructor)
670 basic_stringbuf& operator=(basic_stringbuf&& rhs);
671#endif
672
673 /// Reset the internally buffered sequence of characters to the
674 /// specified `value`. Update the beginning and end of both the input
675 /// and output sequences to be the beginning and end of the updated
676 /// buffer, update the current input position to be the beginning of the
677 /// updated buffer, and update the current output position to be the end
678 /// of the updated buffer. If `value` is passed by `MovableRef`, then
679 /// it is left in an unspecified but valid state.
680 void str(const StringType& value);
681 void str(BloombergLP::bslmf::MovableRef<StringType> value);
682 template <class SALLOC>
683 typename
686 {
687 // Note: implemented inline due to Sun CC compilation error.
688 d_str.assign(value.data(), value.size());
689 d_endHint = d_str.size();
690 updateStreamPositions(0, d_mode & ios_base::ate ? d_endHint : 0);
691 }
692
693 /// Reset the internally buffered sequence of characters to the
694 /// specified `value` (of a type convertible to
695 /// `basic_string_view<CHAR_TYPE, CHAR_TRAITS>` but not to
696 /// `const CHAR_TYPE *`).
697 template <class STRING_VIEW_LIKE_TYPE>
699 str(const STRING_VIEW_LIKE_TYPE& value)
700 {
701 // Note: implemented inline due to Sun CC compilation error.
702 ViewType sv = value;
703 d_str.assign(sv.data(), sv.size());
704 d_endHint = d_str.size();
705 updateStreamPositions(0, d_mode & ios_base::ate ? d_endHint : 0);
706 }
707
708#ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
709 /// Return the currently buffered sequence of characters. If this
710 /// object was created only in input mode, the resultant `StringType`
711 /// contains the character sequence in the range `[eback(), egptr())`.
712 /// If `modeBitMask & ios_base::out` specified at construction is
713 /// nonzero then the resultant `StringType` contains the character
714 /// sequence in the range `[pbase(), high_mark)`, where @ref high_mark
715 /// represents the position one past the highest initialized character
716 /// in the buffer. Otherwise this object has been created in neither
717 /// input nor output mode and a zero length `StringType` is returned.
718 /// This object is left in an empty state.
719 StringType str() &&;
720#endif
721
722#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
723 /// Efficiently exchange the value of this object with the value of the
724 /// specified `other` object. This method provides the no-throw
725 /// exception-safety guarantee if `*this` and `other` allocators compare equal.
726 ///
727 /// \pre The behavior is undefined unless either `*this` and `other`
728 /// allocators compare equal or @ref propagate_on_container_swap is `true`.
729 ///
730 /// \note Note that this function is only available for C++11 (and later)
731 /// language standards because it requires that `swap` be provided on
732 /// the (platform supplied) base class for this type.
733 // NOLINTNEXTLINE(performance-noexcept-swap)
734 void swap(basic_stringbuf& other);
735#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
736
737 // ACCESSORS
738
739 /// Return the allocator used by the underlying string to supply memory.
741
742 /// Return the currently buffered sequence of characters. If this
743 /// object was created only in input mode, the resultant `StringType`
744 /// contains the character sequence in the range `[eback(), egptr())`.
745 /// If `modeBitMask & ios_base::out` specified at construction is
746 /// nonzero then the resultant `StringType` contains the character
747 /// sequence in the range `[pbase(), high_mark)`, where @ref high_mark
748 /// represents the position one past the highest initialized character
749 /// in the buffer. Otherwise this object has been created in neither
750 /// input nor output mode and a zero length `StringType` is returned.
751#ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
752 StringType str() const &;
753#else
754 StringType str() const;
755#endif
756
757#ifndef BSLS_PLATFORM_CMP_SUN
758 // To be enabled once DRQS 168075157 is resolved
759
760 /// Return the currently buffered sequence of characters in a
761 /// @ref basic_string that uses the specified `allocator`. If this object
762 /// was created only in input mode, the resultant @ref basic_string
763 /// contains the character sequence in the range `[eback(), egptr())`.
764 /// If `modeBitMask & ios_base::out` specified at construction is
765 /// nonzero then the resultant @ref basic_string contains the character
766 /// sequence in the range `[pbase(), high_mark)`, where @ref high_mark
767 /// represents the position one past the highest initialized character
768 /// in the buffer. Otherwise this object has been created in neither
769 /// input nor output mode and a zero length @ref basic_string is returned.
770 template <class SALLOC>
771 typename bsl::enable_if<
772 bsl::IsStdAllocator<SALLOC>::value,
774 str(const SALLOC& allocator) const
775 {
776 // Note: implemented inline due to Sun CC compilation error.
778 }
779#endif
780
781 /// Return a @ref string_view containing the currently buffered sequence of
782 /// characters. If this object was created only in input mode, the
783 /// resultant `ViewType` contains the character sequence in the range
784 /// `[eback(), egptr())`. If `modeBitMask & ios_base::out` specified at
785 /// construction is nonzero then the resultant `StringType` contains the
786 /// character sequence in the range `[pbase(), high_mark)`, where
787 /// @ref high_mark represents the position one past the highest initialized
788 /// character in the buffer. Otherwise this object has been created in
789 /// neither input nor output mode and a zero length `ViewType` is
790 /// returned.
791 ViewType view() const BSLS_KEYWORD_NOEXCEPT;
792};
793
794// FREE FUNCTIONS
795#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY) \
796 && defined(BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE)
797/// Efficiently exchange the values of the specified `a` and `b` objects.
798/// This method provides the no-throw exception-safety guarantee if `a` and `b` allocators compare equal.
799///
800/// \note Note that this function is only available
801/// for C++11 (and later) language standards.
802template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
805#endif
806
807// STANDARD TYPEDEFS
811
812 // =========================
813 // struct StringBufContainer
814 // =========================
815
816/// This class enables the implementation of string-stream types by
817/// providing a trivial type containing a @ref basic_stringbuf that is suitable
818/// as a (`private`) base class for a string-stream. Inheriting from
819/// `StringBufContainer` allows the string-stream to ensure that the
820/// contained @ref basic_stringbuf is initialized before initializing other
821/// base classes or data members without potentially overriding `virtual` methods in the `basic_stringbuf` type.
822///
823/// \note Note that implementations of
824/// string-stream types must pass the address of a string-buffer to their
825/// `public` base class (e.g., @ref basic_stream ), so the string-stream must
826/// ensure (using `private` inheritance) that the string-buffer is
827/// initialized before constructing the `public` base class. If a
828/// string-stream implementation were to directly inherit from
829/// @ref basic_streambuf , then `virtual` methods defined in that string-stream
830/// (e.g., `underflow`) might incorrectly override those in the
831/// @ref basic_stringbuf implementation.
832///
833/// See @ref bslstl_stringbuf
834template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
836
837 private:
838 // PRIVATE TYPES
841
842 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
843
844 // DATA
845 StreamBufType d_bufObj; // contained 'basic_stringbuf'
846
847 private:
848 // NOT IMPLEMENTED
849 StringBufContainer(const StringBufContainer&); // = delete
850 StringBufContainer& operator=(const StringBufContainer&); // = delete
851
852 public:
853 // CREATORS
854 explicit
856 : d_bufObj(allocator)
857 {
858 }
859
860 StringBufContainer(ios_base::openmode modeBitMask,
861 const ALLOCATOR& allocator)
862 : d_bufObj(modeBitMask, allocator)
863 {
864 }
865
866 StringBufContainer(const StringType& initialString,
867 const ALLOCATOR& allocator)
868 : d_bufObj(initialString, allocator)
869 {
870 }
871
872 StringBufContainer(const StringType& initialString,
873 ios_base::openmode modeBitMask,
874 const ALLOCATOR& allocator)
875 : d_bufObj(initialString, modeBitMask, allocator)
876 {
877 }
878
880 BloombergLP::bslmf::MovableRef<StringType> initialString,
881 ios_base::openmode modeBitMask,
882 const ALLOCATOR& allocator)
883 : d_bufObj(MoveUtil::move(initialString), modeBitMask, allocator)
884 {
885 }
886
888 BloombergLP::bslmf::MovableRef<StringType> initialString,
889 ios_base::openmode modeBitMask)
890 : d_bufObj(MoveUtil::move(initialString), modeBitMask)
891 {
892 }
893
894 template <class STRING_ITER>
895 StringBufContainer(STRING_ITER first,
896 STRING_ITER last,
897 ios_base::openmode modeBitMask,
898 const ALLOCATOR& allocator)
899 : d_bufObj(modeBitMask, allocator)
900 {
901 StringType tempStr(first, last, allocator);
902 d_bufObj.str(MoveUtil::move(tempStr));
903 }
904
905 /// Create a `StringBufContainer` object. Use the specified
906 /// `initialString` (of a type convertible to
907 /// `basic_string_view<CHAR_TYPE, CHAR_TRAITS>` but not to
908 /// `const CHAR_TYPE *`) indicating the initial sequence of characters
909 /// that this buffer will access or manipulate. Use the specified
910 /// `modeBitMask` to indicate whether this buffer may be read from,
911 /// written to, or both. Use the specified `allocator` to supply
912 /// memory.
913 template <class STRING_VIEW_LIKE_TYPE>
915 const STRING_VIEW_LIKE_TYPE& initialString,
916 ios_base::openmode modeBitMask,
918 allocator)
919 : d_bufObj(initialString, modeBitMask, allocator)
920 {
921 }
922
923#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE
924 /// Create a `StringBufContainer` object having the same value as the
925 /// specified `original` object by moving the contents of `original` to
926 /// the newly-created object. `original` is left in a valid but
927 /// unspecified state.
928 // NOLINTNEXTLINE(performance-noexcept-move-constructor)
930 : d_bufObj(std::move(original.d_bufObj))
931 {
932 }
933
934 /// Create a `StringBufContainer` object using the specified `allocator` to
935 /// supply memory and having the same value as the specified `original`
936 /// object by moving the contents of `original` to the newly-created object.
937 /// `original` is left in a valid but unspecified state.
938 StringBufContainer(StringBufContainer&& original,
939 const ALLOCATOR& allocator)
940 : d_bufObj(std::move(original.d_bufObj), allocator)
941 {
942 }
943#endif
944
946
947 // MANIPULATORS
948
949#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE
950 /// Assign to this object the value of the specified `rhs`, and return a
951 /// reference providing modifiable access to this object. The contents
952 /// of `rhs` are move-assigned to this object. `rhs` is left in a valid
953 /// but unspecified state.
954 // NOLINTNEXTLINE(performance-noexcept-move-constructor)
955 StringBufContainer& operator=(StringBufContainer&& rhs)
956 {
957 d_bufObj = std::move(rhs.d_bufObj);
958
959 return *this;
960 }
961#endif
962
963#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
964 /// Efficiently exchange the value of this object with the value of the
965 /// specified `other` object.
966 // NOLINTNEXTLINE(performance-noexcept-swap)
967 void swap(StringBufContainer& other)
968 {
969 d_bufObj.swap(other.d_bufObj);
970 }
971#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
972
973 // ACCESSORS
974 StreamBufType *rdbuf() const
975 {
976 return const_cast<StreamBufType *>(&d_bufObj);
977 }
978};
979
980// ============================================================================
981// TEMPLATE FUNCTION DEFINITIONS
982// ============================================================================
983
984 // ---------------------
985 // class basic_stringbuf
986 // ---------------------
987
988// PRIVATE MANIPULATORS
989template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
991basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::
992 updateInputPointers(char_type *currentInputPosition)
993{
994 BSLS_ASSERT(d_mode & ios_base::in);
995 BSLS_ASSERT(&d_str[0] <= currentInputPosition);
996 BSLS_ASSERT(currentInputPosition <=
997 &d_str[0] + static_cast<std::ptrdiff_t>(streamSize()));
998
999 char_type *dataPtr = &d_str[0];
1000
1001 this->setg(dataPtr,
1002 currentInputPosition,
1003 dataPtr + static_cast<std::ptrdiff_t>(streamSize()));
1004 return pos_type(currentInputPosition - dataPtr);
1005}
1006
1007template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1009basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::
1010 updateOutputPointers(char_type *currentOutputPosition)
1011{
1012 BSLS_ASSERT(d_mode & ios_base::out);
1013 BSLS_ASSERT(&d_str[0] <= currentOutputPosition);
1014 BSLS_ASSERT(currentOutputPosition <= &d_str[0] + d_str.size());
1015
1016 char_type *dataPtr = &d_str[0];
1017 std::size_t dataSize = d_str.size();
1018
1019 pos_type outputPos = currentOutputPosition - dataPtr;
1020 this->setp(dataPtr, dataPtr + dataSize);
1021 pos_type bumpAmount = outputPos;
1022 while (bumpAmount > INT_MAX) {
1023 this->pbump(INT_MAX);
1024 bumpAmount -= INT_MAX;
1025 }
1026 if (bumpAmount) {
1027 this->pbump(int(bumpAmount));
1028 }
1029 return outputPos;
1030}
1031
1032template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1033void basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::
1034 updateStreamPositions(off_type inputOffset, off_type outputOffset)
1035{
1036 // Extend the internal buffer to the full capacity of the string to allow
1037 // us to use the full capacity for buffering output.
1038
1039 d_str.resize(d_str.capacity());
1040 char_type *dataPtr = &d_str[0];
1041
1042 if (d_mode & ios_base::out) {
1043 // Update the output position.
1044
1045 std::size_t dataSize = d_str.size();
1046 this->setp(dataPtr, dataPtr + dataSize);
1047 off_type bumpAmount = outputOffset;
1048 while (bumpAmount < INT_MIN) {
1049 this->pbump(INT_MIN);
1050 bumpAmount -= INT_MIN;
1051 }
1052 while (bumpAmount > INT_MAX) {
1053 this->pbump(INT_MAX);
1054 bumpAmount -= INT_MAX;
1055 }
1056 if (bumpAmount) {
1057 this->pbump(int(bumpAmount));
1058 }
1059 }
1060
1061 if (d_mode & ios_base::in) {
1062 // Update the input position.
1063
1064 this->setg(dataPtr,
1065 dataPtr + inputOffset,
1066 dataPtr + static_cast<std::ptrdiff_t>(streamSize()));
1067 }
1068}
1069
1070template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1071bool basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::extendInputArea()
1072{
1073 // Try to extend into written buffer.
1074
1075 if (d_mode & ios_base::out && this->pptr() > this->egptr()) {
1076 d_endHint = streamSize();
1077 updateInputPointers(this->gptr());
1078 return true; // RETURN
1079 }
1080
1081 return false;
1082}
1083
1084// PRIVATE ACCESSORS
1085template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1087 basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::streamSize() const
1088{
1089 pos_type size = std::max<off_type>(d_endHint,
1090 this->pptr() - this->pbase());
1091
1092 BSLS_ASSERT(size <= off_type(d_str.size()));
1093
1094 return size;
1095}
1096
1097template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1098bool basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::arePointersValid(
1099 const char_type *first,
1100 const char_type *middle,
1101 const char_type *last) const
1102{
1103 const bool isNull = first == 0;
1104 const char_type *bufferBegin = isNull ? 0 : d_str.data();
1105 const char_type *bufferEnd = isNull ? 0 : d_str.data() + d_str.size();
1106 return first == bufferBegin
1107 && last <= bufferEnd
1108 && first <= middle
1109 && middle <= last;
1110}
1111
1112// PROTECTED MANIPULATORS
1113template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1116 off_type offset,
1117 ios_base::seekdir whence,
1118 ios_base::openmode modeBitMask)
1119{
1120 // If `whence` is `ios_base::cur` (the current position), `modeBitMask`
1121 // may not be both input and output mode.
1122
1123 if (((modeBitMask & (ios_base::in | ios_base::out)) ==
1124 (ios_base::in | ios_base::out))
1125 && whence == ios_base::cur) {
1126 return pos_type(off_type(-1)); // RETURN
1127 }
1128
1129 pos_type newPos = pos_type(off_type(-1));
1130
1131 // Set the current input position.
1132
1133 if ((modeBitMask & ios_base::in) && (d_mode & ios_base::in)) {
1134 char_type *inputPtr = 0;
1135
1136 switch (whence) {
1137 case ios_base::beg: {
1138 inputPtr = this->eback() + offset;
1139 } break;
1140 case ios_base::cur: {
1141 inputPtr = this->gptr() + offset;
1142 } break;
1143 case ios_base::end: {
1144 inputPtr = this->eback()
1145 + static_cast<std::ptrdiff_t>(streamSize())
1146 + offset;
1147 } break;
1148 default: {
1149 BSLS_ASSERT_OPT_UNREACHABLE("Invalid seekdir argument");
1150 }
1151 }
1152
1153 if (inputPtr < this->eback()
1154 || inputPtr >
1155 this->eback() + static_cast<std::ptrdiff_t>(streamSize())) {
1156 // 'inputPtr' is outside the valid range of the string buffer.
1157
1158 return pos_type(off_type(-1)); // RETURN
1159 }
1160
1161 newPos = updateInputPointers(inputPtr);
1162 }
1163
1164 // Set the current output position.
1165
1166 if ((modeBitMask & ios_base::out) && (d_mode & ios_base::out)) {
1167 char_type *outputPtr = 0;
1168
1169 switch (whence) {
1170 case ios_base::beg: {
1171 outputPtr = this->pbase() + offset;
1172 } break;
1173 case ios_base::cur: {
1174 outputPtr = this->pptr() + offset;
1175 } break;
1176 case ios_base::end: {
1177 outputPtr = this->pbase()
1178 + static_cast<std::ptrdiff_t>(streamSize())
1179 + offset;
1180 } break;
1181 default: {
1182 BSLS_ASSERT_OPT_UNREACHABLE("Invalid seekdir argument");
1183 }
1184 }
1185
1186 if (outputPtr < this->pbase()
1187 || outputPtr >
1188 this->pbase() + static_cast<std::ptrdiff_t>(streamSize())) {
1189 // 'outputPtr' is outside the valid range of the string buffer.
1190
1191 return pos_type(off_type(-1)); // RETURN
1192 }
1193
1194 newPos = updateOutputPointers(outputPtr);
1195 }
1196
1197 return newPos;
1198}
1199
1200template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1201inline
1204 pos_type absoluteOffset,
1205 ios_base::openmode modeBitMask)
1206{
1207 return basic_stringbuf::seekoff(off_type(absoluteOffset),
1208 ios_base::beg,
1209 modeBitMask);
1210}
1211
1212template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1213std::streamsize
1215 char_type *result,
1216 std::streamsize numCharacters)
1217{
1218 if ((d_mode & ios_base::in) == 0) {
1219 return 0; // RETURN
1220 }
1221
1222 // Additional characters may become available for reading when the input
1223 // area is extended to account for any characters newly written to the
1224 // output sequence.
1225 extendInputArea();
1226
1227 if (this->gptr() != this->egptr()) {
1228 // There are characters available in this buffer.
1229
1230 std::streamsize available = this->egptr() - this->gptr();
1231 std::streamsize readChars = std::min(available,
1232 numCharacters);
1233
1234 traits_type::copy(result, this->gptr(), std::size_t(readChars));
1235 this->gbump(int(readChars));
1236
1237 return readChars; // RETURN
1238 }
1239
1240 return 0;
1241}
1242
1243template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1246{
1247 if ((d_mode & ios_base::in) == 0) {
1248 return traits_type::eof(); // RETURN
1249 }
1250
1251 if (this->gptr() != this->egptr()) {
1252 // There are characters available in this buffer.
1253
1254 return traits_type::to_int_type(*this->gptr()); // RETURN
1255 }
1256
1257 if (extendInputArea()) {
1258 // Additional characters may become available after the input area is
1259 // extended.
1260
1261 return this->basic_stringbuf::underflow(); // RETURN
1262 }
1263
1264 return traits_type::eof();
1265}
1266
1267template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1270{
1271 if ((d_mode & ios_base::in) == 0) {
1272 return traits_type::eof(); // RETURN
1273 }
1274
1275 if (this->gptr() != this->egptr()) {
1276 // There are characters available in this buffer.
1277
1278 int_type c = traits_type::to_int_type(*this->gptr());
1279 this->gbump(1);
1280 return c; // RETURN
1281 }
1282
1283 if (extendInputArea()) {
1284 // Additional characters may become available after the input area is
1285 // extended.
1286
1287 return this->basic_stringbuf::uflow(); // RETURN
1288 }
1289
1290 return traits_type::eof();
1291}
1292
1293template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1296 int_type character)
1297{
1298 if (this->gptr() == this->eback()) {
1299 // The current position is at the start of the buffer, so we cannot
1300 // push back a character.
1301
1302 return traits_type::eof(); // RETURN
1303 }
1304
1305 if (traits_type::eq_int_type(character, traits_type::eof())
1306 || traits_type::eq_int_type(
1307 character,
1308 traits_type::to_int_type(*(this->gptr() - 1)))) {
1309 // If 'character' is 'eof' or the previous input character,
1310 // simply move the current position back 1.
1311
1312 this->gbump(-1);
1313 return traits_type::to_int_type(*this->gptr()); // RETURN
1314 }
1315
1316 if (d_mode & ios_base::out) {
1317 // In output mode, if 'character' is not the previous input character,
1318 // overwrite the previous input character.
1319
1320 this->gbump(-1);
1321 *this->gptr() = traits_type::to_char_type(character);
1322 return character; // RETURN
1323 }
1324
1325 return traits_type::eof();
1326}
1327
1328template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1329std::streamsize
1331 const char_type *inputString,
1332 std::streamsize numCharacters)
1333{
1334 if ((d_mode & ios_base::out) == 0) {
1335 return 0; // RETURN
1336 }
1337 BSLS_ASSERT(this->pptr());
1338 BSLS_ASSERT(this->pbase());
1339
1340 // Compute the space required.
1341
1342 std::streamsize spaceLeft = d_str.data() + d_str.size() - this->pptr();
1343 std::ptrdiff_t toOverwrite =
1344 std::ptrdiff_t(std::min(spaceLeft, numCharacters));
1345
1346 // Append the portion of 'inputString' that can be written without
1347 // resizing 'd_ptr'.
1348
1349 traits_type::copy(this->pptr(), inputString, toOverwrite);
1350
1351 off_type inputOffset = this->gptr() - this->eback();
1352
1353 if (numCharacters == toOverwrite) {
1354 // If all of 'inputString' has been written, just update the stream
1355 // positions.
1356
1357 off_type newHigh = numCharacters + this->pptr() - this->pbase();
1358 d_endHint = std::max(d_endHint, newHigh);
1359
1360 updateStreamPositions(inputOffset, newHigh);
1361 }
1362 else {
1363 // If some characters remain to be written, append them to 'd_str'
1364 // (resizing 'd_str' in the process).
1365
1366 d_str.append(inputString + toOverwrite, inputString + numCharacters);
1367
1368 // Update the last written character cache, and the input stream
1369 // positions.
1370
1371 d_endHint = d_str.size();
1372 updateStreamPositions(inputOffset, d_endHint);
1373 }
1374
1375 return numCharacters;
1376}
1377
1378template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1381 int_type character)
1382{
1383 if ((d_mode & ios_base::out) == 0) {
1384 return traits_type::eof(); // RETURN
1385 }
1386
1387 if (traits_type::eq_int_type(character, traits_type::eof())) {
1388 // Nothing to write, so just return success.
1389
1390 return traits_type::not_eof(character); // RETURN
1391 }
1392
1393 char_type c = traits_type::to_char_type(character);
1394 if (this->pptr() != this->epptr()) {
1395 // Additional space is available in 'd_str', so no need to resize the
1396 // buffer.
1397
1398 *this->pptr() = c;
1399 this->pbump(1);
1400
1401 d_endHint = streamSize();
1402 }
1403 else {
1404 // Store the input offset so it can be used to restore the input and
1405 // output positions after the next resize.
1406
1407 off_type inputOffset = this->gptr() - this->eback();
1408
1409 // Append the character, and expand the buffer.
1410
1411 d_str.push_back(c);
1412
1413 // Update the input sequence, restoring the current input position
1414 // from 'inputOffset', and updating the output sequence to reflect the
1415 // newly resized buffer.
1416
1417 d_endHint = d_str.size();
1418 updateStreamPositions(inputOffset, d_endHint);
1419 }
1420
1421 return character;
1422}
1423
1424// CREATORS
1425template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1428: BaseType()
1429, d_str(allocator)
1430, d_endHint(0)
1431, d_mode(ios_base::in | ios_base::out)
1432{
1433 updateStreamPositions();
1434}
1435
1436template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1438 basic_stringbuf(ios_base::openmode modeBitMask,
1440: BaseType()
1441, d_str(allocator)
1442, d_endHint(0)
1443, d_mode(modeBitMask)
1444{
1445 updateStreamPositions();
1446}
1447
1448template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1450 basic_stringbuf(const StringType& initialString,
1452: BaseType()
1453, d_str(initialString, allocator)
1454, d_endHint(initialString.size())
1455, d_mode(ios_base::in | ios_base::out)
1456{
1457 updateStreamPositions();
1458}
1459
1460template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1461inline
1463 basic_stringbuf(const StringType& initialString,
1464 ios_base::openmode modeBitMask,
1466: BaseType()
1467, d_str(initialString, allocator)
1468, d_endHint(initialString.size())
1469, d_mode(modeBitMask)
1470{
1471 updateStreamPositions(0, d_mode & ios_base::ate ? d_endHint : 0);
1472}
1473
1474template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1475inline
1477 basic_stringbuf(BloombergLP::bslmf::MovableRef<StringType> initialString)
1478: BaseType()
1479, d_str(MoveUtil::move(initialString))
1480, d_endHint(d_str.size())
1481, d_mode(ios_base::in | ios_base::out)
1482{
1483 updateStreamPositions();
1484}
1485
1486template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1487inline
1489 basic_stringbuf(BloombergLP::bslmf::MovableRef<StringType> initialString,
1491: BaseType()
1492, d_str(MoveUtil::move(initialString), allocator)
1493, d_endHint(d_str.size())
1494, d_mode(ios_base::in | ios_base::out)
1495{
1496 updateStreamPositions();
1497}
1498
1499template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1500inline
1502 basic_stringbuf(BloombergLP::bslmf::MovableRef<StringType> initialString,
1503 ios_base::openmode modeBitMask)
1504: BaseType()
1505, d_str(MoveUtil::move(initialString))
1506, d_endHint(d_str.size())
1507, d_mode(modeBitMask)
1508{
1509 updateStreamPositions(0, d_mode & ios_base::ate ? d_endHint : 0);
1510}
1511
1512template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1513inline
1515 basic_stringbuf(BloombergLP::bslmf::MovableRef<StringType> initialString,
1516 ios_base::openmode modeBitMask,
1518: BaseType()
1519, d_str(MoveUtil::move(initialString), allocator)
1520, d_endHint(d_str.size())
1521, d_mode(modeBitMask)
1522{
1523 updateStreamPositions(0, d_mode & ios_base::ate ? d_endHint : 0);
1524}
1525
1526#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE
1527template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1528inline
1531: BaseType()
1532, d_str(std::move(original.d_str))
1533, d_endHint(std::move(original.d_endHint))
1534, d_mode(std::move(original.d_mode))
1535{
1536 // Capture the positions for later restoration
1537
1538 const off_type inputOffset = original.gptr() - original.eback();
1539 const off_type outputOffset = original.pptr() - original.pbase();
1540 updateStreamPositions(inputOffset, outputOffset);
1541
1542 this->pubimbue(original.getloc());
1543
1544 if (original.d_endHint > 0 &&
1545 static_cast<size_t>(original.d_endHint) > original.d_str.size()) {
1546
1547 // The move has moved away the string
1548
1549 original.d_endHint = 0;
1550 original.updateStreamPositions();
1551 }
1552}
1553
1554template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1555inline
1556basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::
1557 basic_stringbuf(basic_stringbuf&& original,
1558 const allocator_type& allocator)
1559: BaseType()
1560, d_str(std::move(original.d_str), allocator)
1561, d_endHint(std::move(original.d_endHint))
1562, d_mode(std::move(original.d_mode))
1563{
1564 // Capture the positions for later restoration
1565
1566 const off_type inputOffset = original.gptr() - original.eback();
1567 const off_type outputOffset = original.pptr() - original.pbase();
1568 updateStreamPositions(inputOffset, outputOffset);
1569
1570 this->pubimbue(original.getloc());
1571
1572 if (original.d_endHint > 0 &&
1573 static_cast<size_t>(original.d_endHint) > original.d_str.size()) {
1574
1575 // The move has moved away the string
1576
1577 original.d_endHint = 0;
1578 original.updateStreamPositions();
1579 }
1580}
1581#endif
1582
1583template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1586{
1587 if (d_mode & ios_base::in) {
1588 BSLS_ASSERT(arePointersValid(this->eback(),
1589 this->gptr(),
1590 this->egptr()));
1591 }
1592
1593 if (d_mode & ios_base::out) {
1594 BSLS_ASSERT(arePointersValid(this->pbase(),
1595 this->pptr(),
1596 this->epptr()));
1597 }
1598}
1599
1600// MANIPULATORS
1601#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE
1602template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1603inline
1607{
1608 // Capture the positions for later restoration
1609
1610 const off_type inputOffset = rhs.gptr() - rhs.eback();
1611 const off_type inputSize = rhs.egptr() - rhs.eback();
1612 const off_type outputOffset = rhs.pptr() - rhs.pbase();
1613 const off_type outputSize = rhs.epptr() - rhs.pbase();
1614
1615 this->pubimbue(rhs.getloc());
1616
1617 d_str = std::move(rhs.d_str);
1618 d_endHint = std::move(rhs.d_endHint);
1619 d_mode = std::move(rhs.d_mode);
1620
1621 // Fix the stream-position pointers
1622
1623 char_type *dataPtr = &d_str[0];
1624
1625 // Update positions/pointers in the moved-to object
1626
1627 this->setp(dataPtr, dataPtr + outputSize);
1628 this->pbump(static_cast<int>(outputOffset));
1629 this->setg(dataPtr,
1630 dataPtr + inputOffset,
1631 dataPtr + inputSize);
1632
1633 // Reset positions/pointers in the moved-from object
1634
1635 if (rhs.d_endHint > 0 &&
1636 static_cast<size_t>(rhs.d_endHint) > rhs.d_str.size()) {
1637
1638 // The move has moved away the string
1639
1640 rhs.d_endHint = 0;
1641 rhs.updateStreamPositions();
1642 }
1643
1644 return *this;
1645}
1646#endif
1647
1648template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1650 const StringType& value)
1651{
1652 d_str = value;
1653 d_endHint = d_str.size();
1654 updateStreamPositions(0, d_mode & ios_base::ate ? d_endHint : 0);
1655}
1656
1657template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1659 BloombergLP::bslmf::MovableRef<StringType> value)
1660{
1661 StringType& lvalue = value;
1662
1663 d_str = MoveUtil::move(lvalue);
1664 d_endHint = d_str.size();
1665 updateStreamPositions(0, d_mode & ios_base::ate ? d_endHint : 0);
1666}
1667
1668#ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1669template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1672{
1673 if (d_mode & ios_base::out) {
1674 d_str.resize(static_cast<typename StringType::size_type>(streamSize()));
1675 this->setp(d_str.data(), d_str.data());
1676 }
1677 else if (d_mode & ios_base::in) {
1678 if (streamSize() > 0) {
1679 if (this->eback() != d_str.data()) {
1680 d_str.erase(0, this->eback() - d_str.data());
1681 }
1682 d_str.resize(static_cast<typename StringType::size_type>(
1683 streamSize()));
1684 this->setg(d_str.data(), d_str.data(), d_str.data());
1685 }
1686 }
1687
1688 StringType ret = std::move(d_str);
1689 d_endHint = 0;
1690 updateStreamPositions();
1691 return ret;
1692}
1693#endif
1694
1695#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1696template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1697void basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::swap(
1698 basic_stringbuf& other)
1699{
1702 || d_str.get_allocator() == other.d_str.get_allocator());
1703 // Capture the positions for the later restoration. Formally,
1704 // 'std::basic_streambuf::swap' exchanges the internal pointers and the
1705 // locale object. But 'bsl::string' swapping can invalidate pointers, so
1706 // we need to control this process manually.
1707
1708 const off_type inputOffset = this->gptr() - this->eback();
1709 const off_type outputOffset = this->pptr() - this->pbase();
1710 const std::locale loc = this->getloc();
1711
1712 const off_type otherInputOffset = other.gptr() - other.eback();
1713 const off_type otherOutputOffset = other.pptr() - other.pbase();
1714 const std::locale otherLoc = other.getloc();
1715
1716 // Parent method invocation.
1717
1718 this->BaseType::swap(other);
1719
1720 // Swapping data members.
1721
1722 this->pubimbue(otherLoc);
1723 other.pubimbue(loc);
1724
1725 d_str.swap(other.d_str);
1726 BloombergLP::bslalg::SwapUtil::swap(&this->d_endHint, &other.d_endHint);
1727 BloombergLP::bslalg::SwapUtil::swap(&this->d_mode, &other.d_mode);
1728
1729 // Fix the stream-position pointers.
1730
1731 this->updateStreamPositions(otherInputOffset, otherOutputOffset);
1732 other.updateStreamPositions( inputOffset, outputOffset);
1733}
1734#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1735
1736// ACCESSORS
1737template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1738inline
1745
1746template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1747inline
1749#ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1751#else
1753#endif
1754{
1755 return StringType(view());
1756}
1757
1758template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1759inline
1760typename basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::ViewType
1763{
1764 if (d_mode & ios_base::out) {
1765 return ViewType(d_str.begin(),
1766 static_cast<std::ptrdiff_t>(streamSize())); // RETURN
1767 }
1768
1769 if (d_mode & ios_base::in) {
1770 return ViewType(this->eback(), this->egptr() - this->eback());// RETURN
1771 }
1772
1773 return ViewType();
1774}
1775
1776} // close namespace bsl
1777
1778// FREE FUNCTIONS
1779#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY) \
1780 && defined(BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE)
1781template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1782void bsl::swap(basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& a,
1783 basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& b)
1784{
1785 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
1786
1787 if (a.get_allocator() == b.get_allocator()
1789 a.swap(b);
1790 }
1791 else {
1792 basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> aCopy(
1793 MoveUtil::move(a),
1794 b.get_allocator());
1795 basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> bCopy(
1796 MoveUtil::move(b),
1797 a.get_allocator());
1798 swap(a, bCopy);
1799 swap(b, aCopy);
1800 }
1801}
1802#endif
1803
1804// ============================================================================
1805// TYPE TRAITS
1806// ============================================================================
1807
1808
1809namespace bslma {
1810
1811template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1813 bsl::basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> >
1815{};
1816
1817} // close namespace bslma
1818
1819
1820// Undo 'BSLS_ASSERT' filename fix -- See @ref bsls_assertimputil
1821#ifdef BSLS_ASSERTIMPUTIL_AVOID_STRING_CONSTANTS
1822#undef BSLS_ASSERTIMPUTIL_FILE
1823#define BSLS_ASSERTIMPUTIL_FILE BSLS_ASSERTIMPUTIL_DEFAULTFILE
1824#endif
1825
1826#endif
1827
1828// ----------------------------------------------------------------------------
1829// Copyright 2013 Bloomberg Finance L.P.
1830//
1831// Licensed under the Apache License, Version 2.0 (the "License");
1832// you may not use this file except in compliance with the License.
1833// You may obtain a copy of the License at
1834//
1835// http://www.apache.org/licenses/LICENSE-2.0
1836//
1837// Unless required by applicable law or agreed to in writing, software
1838// distributed under the License is distributed on an "AS IS" BASIS,
1839// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1840// See the License for the specific language governing permissions and
1841// limitations under the License.
1842// ----------------------------- END-OF-FILE ----------------------------------
1843
1844/** @} */
1845/** @} */
1846/** @} */
Definition bslstl_stringbuf.h:835
StreamBufType * rdbuf() const
Definition bslstl_stringbuf.h:974
StringBufContainer(const StringType &initialString, ios_base::openmode modeBitMask, const ALLOCATOR &allocator)
Definition bslstl_stringbuf.h:872
StringBufContainer(ios_base::openmode modeBitMask, const ALLOCATOR &allocator)
Definition bslstl_stringbuf.h:860
StringBufContainer(BloombergLP::bslmf::MovableRef< StringType > initialString, ios_base::openmode modeBitMask)
Definition bslstl_stringbuf.h:887
StringBufContainer(const ALLOCATOR &allocator)
Definition bslstl_stringbuf.h:855
StringBufContainer(STRING_ITER first, STRING_ITER last, ios_base::openmode modeBitMask, const ALLOCATOR &allocator)
Definition bslstl_stringbuf.h:895
StringBufContainer(const StringType &initialString, const ALLOCATOR &allocator)
Definition bslstl_stringbuf.h:866
StringBufContainer(BloombergLP::bslmf::MovableRef< StringType > initialString, ios_base::openmode modeBitMask, const ALLOCATOR &allocator)
Definition bslstl_stringbuf.h:879
StringBufContainer(const STRING_VIEW_LIKE_TYPE &initialString, ios_base::openmode modeBitMask, allocator)
Definition bslstl_stringbuf.h:914
Definition bslma_bslallocator.h:588
Definition bslstl_stringview.h:471
Definition bslstl_string.h:1252
basic_string & assign(const basic_string &replacement)
Definition bslstl_string.h:6347
size_type size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7292
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by this string to supply memory.
Definition bslstl_string.h:7423
void push_back(CHAR_TYPE character)
Append the specified character to this string.
Definition bslstl_string.h:6330
CHAR_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7177
void resize(size_type newLength, CHAR_TYPE character)
Definition bslstl_string.h:5977
void swap(basic_string &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits const_iterator begin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:2792
basic_string & erase(size_type position=0, size_type numChars=npos)
Definition bslstl_string.h:6740
size_type capacity() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7323
basic_string & append(const basic_string &suffix)
Definition bslstl_string.h:6188
Definition bslstl_stringbuf.h:248
ViewType view() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_stringbuf.h:1761
virtual pos_type seekoff(off_type offset, ios_base::seekdir whence, ios_base::openmode modeBitMask=ios_base::in|ios_base::out)
Definition bslstl_stringbuf.h:1115
virtual int_type pbackfail(int_type character=traits_type::eof())
Definition bslstl_stringbuf.h:1295
StringType str() const
Definition bslstl_stringbuf.h:1752
virtual pos_type seekpos(pos_type absoluteOffset, ios_base::openmode modeBitMask=ios_base::in|ios_base::out)
Definition bslstl_stringbuf.h:1203
traits_type::off_type off_type
Definition bslstl_stringbuf.h:264
basic_stringbuf(const bsl::basic_string< CHAR_TYPE, CHAR_TRAITS, SALLOC > &initialString, const allocator_type &allocator=allocator_type(), typename bsl::enable_if< !bsl::is_same< ALLOCATOR, SALLOC >::value, void * >::type=0)
Definition bslstl_stringbuf.h:544
virtual std::streamsize xsgetn(char_type *result, std::streamsize numCharacters)
Definition bslstl_stringbuf.h:1214
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by the underlying string to supply memory.
Definition bslstl_stringbuf.h:1740
CHAR_TYPE char_type
Definition bslstl_stringbuf.h:260
bsl::enable_if< bsl::IsStdAllocator< SALLOC >::value, basic_string< CHAR_TYPE, CHAR_TRAITS, SALLOC > >::type str(const SALLOC &allocator) const
Definition bslstl_stringbuf.h:774
CHAR_TRAITS traits_type
Definition bslstl_stringbuf.h:261
~basic_stringbuf()
Destroy this object.
Definition bslstl_stringbuf.h:1585
virtual int_type uflow()
Definition bslstl_stringbuf.h:1269
basic_stringbuf(const bsl::basic_string< CHAR_TYPE, CHAR_TRAITS, SALLOC > &initialString, ios_base::openmode modeBitMask, const allocator_type &allocator=allocator_type(), typename bsl::enable_if< !bsl::is_same< ALLOCATOR, SALLOC >::value, void * >::type=0)
Definition bslstl_stringbuf.h:573
basic_stringbuf(const STRING_VIEW_LIKE_TYPE &initialString, allocator=allocator_type())
Definition bslstl_stringbuf.h:603
virtual std::streamsize xsputn(const char_type *inputString, std::streamsize numCharacters)
Definition bslstl_stringbuf.h:1330
virtual int_type underflow()
Definition bslstl_stringbuf.h:1245
traits_type::int_type int_type
Definition bslstl_stringbuf.h:263
traits_type::pos_type pos_type
Definition bslstl_stringbuf.h:265
basic_stringbuf(const STRING_VIEW_LIKE_TYPE &initialString, ios_base::openmode modeBitMask, BSLSTL_STRINGVIEWLIKEPARAM_ONLY_ENABLE_IF_T(const allocator_type &) allocator=allocator_type())
Definition bslstl_stringbuf.h:632
virtual int_type overflow(int_type character=traits_type::eof())
Definition bslstl_stringbuf.h:1380
bsl::enable_if<!bsl::is_same< ALLOCATOR, SALLOC >::value, void >::type str(const basic_string< CHAR_TYPE, CHAR_TRAITS, SALLOC > &value)
Definition bslstl_stringbuf.h:685
ALLOCATOR allocator_type
Definition bslstl_stringbuf.h:262
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_OPT_UNREACHABLE(X)
Definition bsls_assert.h:2065
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLSTL_STRINGVIEWLIKEPARAM_ONLY_ENABLE_IF_T(...)
Definition bslstl_stringviewlikeparam.h:159
void swap(OptionValue &a, OptionValue &b)
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
bool isNull(const TYPE &object)
Definition bdlat_valuetypefunctions.h:939
basic_stringbuf< wchar_t, char_traits< wchar_t >, allocator< wchar_t > > wstringbuf
Definition bslstl_iosfwd.h:102
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
basic_stringbuf< char, char_traits< char >, allocator< char > > stringbuf
Definition bslstl_iosfwd.h:93
CHAR_TRAITS
Definition bslstl_string.h:3917
BSLS_KEYWORD_CONSTEXPR CONTAINER::value_type * data(CONTAINER &container)
Definition bslstl_iterator.h:1325
Definition baljsn_encoder_testtypes.h:76
Definition bdldfp_decimal.h:5549
Definition bslma_allocatortraits.h:1089
Definition bslmf_enableif.h:530
Definition bslmf_issame.h:146
Definition bslma_usesbslmaallocator.h:344