// bslstl_stringstream.h -*-C++-*- #ifndef INCLUDED_BSLSTL_STRINGSTREAM #define INCLUDED_BSLSTL_STRINGSTREAM #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a C++03-compatible 'stringstream' class. // //@CLASSES: // bsl::stringstream: C++03-compatible 'stringstream' class // //@CANONICAL_HEADER: bsl_sstream.h // //@SEE_ALSO: // //@DESCRIPTION: This component is for internal use only. Please include // '<bsl_sstream.h>' instead. // // This component defines a class template, 'bsl::basic_stringstream', // implementing a standard stream that provides a constructor and manipulator // ('str') that allow clients to directly set the internal sequence of // characters that is accessed (or modified) by the stream, as well as an // accessor ('str') for obtaining a string having the same sequence of // characters to which the stream currently refers (see 27.8.5 [stringstream] // of the C++11 standard). This component also defines two standard aliases, // 'bsl::stringstream' and 'bsl::wstringstream', that refer to specializations // of the 'bsl::basic_stringstream' template for 'char' and 'wchar_t' types, // respectively. The 'bsl::basic_stringstream' template has three parameters, // 'CHAR_TYPE', 'CHAR_TRAITS', and 'ALLOCATOR'. The 'CHAR_TYPE' and // 'CHAR_TRAITS' parameters respectively define the character type for the // string-stream and a type providing a set of operations the string-stream // will use to manipulate characters of that type, which must meet the // character traits requirements defined by the C++11 standard, 21.2 // [char.traits]. The 'ALLOCATOR' template parameter is described in the // "Memory Allocation" section below. // ///Memory Allocation ///----------------- // The type supplied as a string-stream's 'ALLOCATOR' template parameter // determines how that string-stream will allocate memory. The // 'basic_stringstream' template supports allocators meeting the requirements // of the C++11 standard, 17.6.3.5 [allocator.requirements]; in addition, it // supports scoped-allocators derived from the 'bslma::Allocator' memory // allocation protocol. Clients intending to use 'bslma'-style allocators // should use 'bsl::allocator', which provides a C++11 standard-compatible // adapter for a 'bslma::Allocator' object. Note that the standard aliases // 'bsl::stringstream' and 'bsl::wstringstream' both use 'bsl::allocator'. // ///'bslma'-Style Allocators /// - - - - - - - - - - - - // If the type supplied for the 'ALLOCATOR' template parameter of an // 'stringstream' instantiation is 'bsl::allocator', then objects of that // string-stream type will conform to the standard behavior of a // 'bslma'-allocator-enabled type. Such a string-stream accepts an optional // 'bslma::Allocator' argument at construction. If the address of a // 'bslma::Allocator' object is explicitly supplied at construction, it will be // used to supply memory for the string-stream throughout its lifetime; // otherwise, the string-stream will use the default allocator installed at the // time of the string-stream's construction (see 'bslma_default'). // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Basic Input and Output Operations /// - - - - - - - - - - - - - - - - - - - - - - // The following example demonstrates the use of 'bsl::stringstream' to read // and write data of various types to a 'bsl::string' object. // // Suppose we want to implement a simplified converter between a pair of // generic types, 'TYPE1' and 'TYPE2'. We use 'bsl::stringstream' to implement // the 'lexicalCast' function. We write the data of type 'TYPE1' into the // stream with 'operator<<' and then read it back as the data of 'TYPE2' with // 'operator>>': //.. // template <class TYPE2, class TYPE1> // TYPE2 lexicalCast(const TYPE1& what) // { // bsl::stringstream converter; // converter << what; // // TYPE2 val; // converter >> val; // return val; // } //.. // Finally, we verify that the 'lexicalCast' function works on some simple test // cases: //.. // assert(lexicalCast<int>("1234") == 1234); // // assert(lexicalCast<short>("-5") == -5); // // assert(lexicalCast<bsl::string>("abc") == "abc"); // // assert(lexicalCast<bsl::string>(1234) == "1234"); // // assert(lexicalCast<short>(-5) == -5); //.. #include <bslscm_version.h> #include <bslma_isstdallocator.h> #include <bslma_usesbslmaallocator.h> #include <bslmf_enableif.h> #include <bslmf_issame.h> #include <bslmf_movableref.h> #include <bsls_compilerfeatures.h> #include <bsls_keyword.h> #include <bsls_libraryfeatures.h> #include <bsls_platform.h> #include <bslstl_string.h> #include <bslstl_stringbuf.h> #include <bslstl_stringview.h> #include <ios> #include <iostream> #ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE # include <utility> #endif namespace bsl { // ======================== // class basic_stringstream // ======================== template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> class basic_stringstream : private StringBufContainer<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> , public std::basic_iostream<CHAR_TYPE, CHAR_TRAITS> { // This class implements a standard stream providing operations using // 'bsl::basic_string' for modifying or accessing the sequence of // characters read from, or written to, the stream. private: // PRIVATE TYPES typedef basic_stringbuf<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> StreamBufType; typedef StringBufContainer<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> BaseType; typedef bsl::basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> StringType; typedef bsl::basic_string_view<CHAR_TYPE, CHAR_TRAITS> ViewType; typedef std::basic_iostream<CHAR_TYPE, CHAR_TRAITS> BaseStream; typedef std::ios_base ios_base; typedef BloombergLP::bslmf::MovableRefUtil MoveUtil; private: // NOT IMPLEMENTED basic_stringstream(const basic_stringstream&); // = delete basic_stringstream& operator=(const basic_stringstream&); // = delete public: // TYPES typedef CHAR_TYPE char_type; typedef CHAR_TRAITS traits_type; typedef ALLOCATOR allocator_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::off_type off_type; typedef typename traits_type::pos_type pos_type; // CREATORS explicit basic_stringstream(const allocator_type& allocator = allocator_type()); explicit basic_stringstream(ios_base::openmode modeBitMask, const allocator_type& allocator = allocator_type()); explicit basic_stringstream(const StringType& initialString, const allocator_type& allocator = allocator_type()); basic_stringstream(const StringType& initialString, ios_base::openmode modeBitMask, const allocator_type& allocator = allocator_type()); // Create a 'basic_stringstream' object. Optionally specify a // 'modeBitMask' indicating whether the underlying stream-buffer may be // read from, written to, or both ('rdbuf' is created using // 'modeBitMask'). If 'modeBitMask' is not supplied, 'rdbuf' will be // created using 'ios_base::in | ios_base::out'. Optionally specify an // 'initialString' indicating the initial sequence of characters that // this stream may access or manipulate. If 'initialString' is not // supplied, the initial sequence of characters will be empty. // Optionally specify the 'allocator' used to supply memory. If // 'allocator' is not supplied, a default-constructed object of the // (template parameter) 'ALLOCATOR' type is used. If the 'ALLOCATOR' // argument is of type 'bsl::allocator' (the default), then // 'allocator', if supplied, shall be convertible to // 'bslma::Allocator *'. If the 'ALLOCATOR' argument is of type // 'bsl::allocator' and 'allocator' is not supplied, the currently // installed default allocator will be used to supply memory. If // 'initialString' is passed by 'MovableRef', it is left in a valid but // unspecified state. explicit basic_stringstream( BloombergLP::bslmf::MovableRef<StringType> initialString); basic_stringstream( BloombergLP::bslmf::MovableRef<StringType> initialString, const allocator_type& allocator); basic_stringstream( BloombergLP::bslmf::MovableRef<StringType> initialString, ios_base::openmode modeBitMask); basic_stringstream( BloombergLP::bslmf::MovableRef<StringType> initialString, ios_base::openmode modeBitMask, const allocator_type& allocator); // Create a 'basic_stringstream' object. Use the specified // 'initialString' indicating the initial sequence of characters that // this buffer will access or manipulate. Optionally specify a // 'modeBitMask' indicating whether this buffer may be read from, // written to, or both. If 'modeBitMask' is not supplied, this buffer // is created with 'ios_base::in | ios_base::out'. Optionally specify // the 'allocator' used to supply memory. If 'allocator' is not // supplied, the allocator in 'initialString' is used. 'initialString' // is left in a valid but unspecified state. template <class SALLOC> basic_stringstream( 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) // Create a 'basic_stringstream' object. Use the specified // 'initialString' indicating the initial sequence of characters that // this stream will access or manipulate. 'rdbuf' is created using // 'ios_base::in | ios_base::out'. Optionally specify the 'allocator' // used to supply memory. If 'allocator' is not supplied, a // default-constructed object of the (template parameter) 'ALLOCATOR' // type is used. If the 'ALLOCATOR' argument is of type // 'bsl::allocator' (the default), then 'allocator', if supplied, shall // be convertible to 'bslma::Allocator *'. If the 'ALLOCATOR' argument // is of type 'bsl::allocator' and 'allocator' is not supplied, the // currently installed default allocator will be used to supply memory. // // Note: implemented inline due to Sun CC compilation error. : BaseType(initialString.begin(), initialString.end(), ios_base::in | ios_base::out, allocator) , BaseStream(BaseType::rdbuf()) { } template <class SALLOC> basic_stringstream( 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) // Create a 'basic_stringstream' object. Use the specified // 'initialString' indicating the initial sequence of characters that // this stream will access or manipulate. Use the specified // 'modeBitMask' to indicate whether this stream may be read from, // written to, or both. Optionally specify the 'allocator' used to // supply memory. If 'allocator' is not supplied, a // default-constructed object of the (template parameter) 'ALLOCATOR' // type is used. If the 'ALLOCATOR' argument is of type // 'bsl::allocator' (the default), then 'allocator', if supplied, shall // be convertible to 'bslma::Allocator *'. If the 'ALLOCATOR' argument // is of type 'bsl::allocator' and 'allocator' is not supplied, the // currently installed default allocator will be used to supply memory. // // Note: implemented inline due to Sun CC compilation error. : BaseType(initialString.begin(), initialString.end(), modeBitMask, allocator) , BaseStream(BaseType::rdbuf()) { } #ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE basic_stringstream(basic_stringstream&& original); // Create a 'basic_stringstream' object having the same value as the // specified 'original' object by moving the contents of 'original' to // the newly-created object. 'original' is left in a valid but // unspecified state. #endif //! ~basic_stringstream() = default; // Destroy this object. // MANIPULATORS #ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE basic_stringstream& operator=(basic_stringstream&& rhs); // Assign to this object the value of the specified 'rhs', and return a // reference providing modifiable access to this object. The contents // of 'rhs' are move-assigned to this object. 'rhs' is left in a valid // but unspecified state. #endif void str(const StringType& value); void str(BloombergLP::bslmf::MovableRef<StringType> value); template <class SALLOC> typename bsl::enable_if<!bsl::is_same<ALLOCATOR, SALLOC>::value, void>::type str(const basic_string<CHAR_TYPE, CHAR_TRAITS, SALLOC>& value) // Reset the internally buffered sequence of characters maintained by // this stream to the specified 'value'. If 'value' is passed by // 'MovableRef', it is left in a valid but unspecified state. // // Note: implemented inline due to Sun CC compilation error. { return this->rdbuf()->str(value); } #ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS StringType str() &&; // Return the internally buffered sequence of characters maintained by // this stream, leaving the stream empty. #endif // ACCESSORS StreamBufType *rdbuf() const; // Return an address providing modifiable access to the // 'basic_stringbuf' object that is internally used by this stream // object to buffer unformatted characters. #ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS StringType str() const &; #else StringType str() const; #endif // Return the internally buffered sequence of characters maintained by // this stream object. #ifndef BSLS_PLATFORM_CMP_SUN // To be enabled once {DRQS 168075157} is resolved template <class SALLOC> typename bsl::enable_if< bsl::IsStdAllocator<SALLOC>::value, basic_string<CHAR_TYPE, CHAR_TRAITS, SALLOC> >::type str(const SALLOC& allocator) const // Return a copy of the internally buffered sequence of characters // maintained by this stream object in a 'basic_string' that uses the // specified 'allocator'. // // Note: implemented inline due to Sun CC compilation error. { return this->rdbuf()->str(allocator); } #endif ViewType view() const BSLS_KEYWORD_NOEXCEPT; // Return a view of the internally buffered sequence of characters // maintained by this stream object. }; // STANDARD TYPEDEFS typedef basic_stringstream<char, char_traits<char>, allocator<char> > stringstream; typedef basic_stringstream<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstringstream; } // close namespace bsl // TYPE TRAITS namespace BloombergLP { namespace bslma { template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> struct UsesBslmaAllocator< bsl::basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> > : bsl::true_type {}; } // close namespace bslma } // close enterprise namespace namespace bsl { // ============================================================================ // TEMPLATE FUNCTION DEFINITIONS // ============================================================================ // ------------------------ // class basic_stringstream // ------------------------ // CREATORS template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_stringstream(const allocator_type& allocator) : BaseType(ios_base::in | ios_base::out, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_stringstream(ios_base::openmode modeBitMask, const allocator_type& allocator) : BaseType(modeBitMask, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_stringstream(const StringType& initialString, const allocator_type& allocator) : BaseType(initialString, ios_base::in | ios_base::out, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_stringstream(const StringType& initialString, ios_base::openmode modeBitMask, const allocator_type& allocator) : BaseType(initialString, modeBitMask, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_stringstream(BloombergLP::bslmf::MovableRef<StringType> initialString) : BaseType(MoveUtil::move(initialString), ios_base::in | ios_base::out) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_stringstream(BloombergLP::bslmf::MovableRef<StringType> initialString, const allocator_type& allocator) : BaseType(MoveUtil::move(initialString), ios_base::in | ios_base::out, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_stringstream(BloombergLP::bslmf::MovableRef<StringType> initialString, ios_base::openmode modeBitMask) : BaseType(MoveUtil::move(initialString), modeBitMask) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_stringstream(BloombergLP::bslmf::MovableRef<StringType> initialString, ios_base::openmode modeBitMask, const allocator_type& allocator) : BaseType(MoveUtil::move(initialString), modeBitMask, allocator) , BaseStream(BaseType::rdbuf()) { } #ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_stringstream(basic_stringstream&& original) : BaseType(std::move(original)) , BaseStream(std::move(original)) { BaseStream::set_rdbuf(BaseType::rdbuf()); } #endif // MANIPULATORS #ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: operator=(basic_stringstream&& rhs) { this->BaseType::operator=(std::move(rhs)); this->BaseStream::operator=(std::move(rhs)); return *this; } #endif template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline void basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::str( const StringType& value) { this->rdbuf()->str(value); } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline void basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::str( BloombergLP::bslmf::MovableRef<StringType> value) { this->rdbuf()->str(MoveUtil::move(value)); } #ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline typename basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::StringType basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::str() && { return std::move(*this->rdbuf()).str(); } #endif // ACCESSORS template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline typename basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::StreamBufType * basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::rdbuf() const { return this->BaseType::rdbuf(); } #ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline typename basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::StringType basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::str() const & { return this->rdbuf()->str(); } #else template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline typename basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::StringType basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::str() const { return this->rdbuf()->str(); } #endif template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline typename basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::ViewType basic_stringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::view() const BSLS_KEYWORD_NOEXCEPT { return this->rdbuf()->view(); } } // close namespace bsl #endif // ---------------------------------------------------------------------------- // Copyright 2013 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------