// bslstl_istringstream.h -*-C++-*- #ifndef INCLUDED_BSLSTL_ISTRINGSTREAM #define INCLUDED_BSLSTL_ISTRINGSTREAM #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a C++03-compatible 'istringstream' class. // //@CLASSES: // bsl::istringstream: C++03-compatible 'istringstream' 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_istringstream', // implementing a standard input stream that provides a constructor (as well as // a manipulator) allowing clients to set the sequence of characters // from which input is streamed to a supplied 'bsl::basic_string' (see // 27.8.3 [istringstream] of the C++11 standard). This component also defines // two standard aliases, 'bsl::istringstream' and 'bsl::wistringstream', that // refer to specializations of the 'bsl::basic_istringstream' template for // 'char' and 'wchar_t' types, respectively. The 'bsl::basic_istringstream' // 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_istringstream' 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::istringstream' and 'bsl::wistringstream' both use 'bsl::allocator'. // ///'bslma'-Style Allocators /// - - - - - - - - - - - - // If the type supplied for the 'ALLOCATOR' template parameter of an // 'istringstream' 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 Operations ///- - - - - - - - - - - - - - - - - // The following example demonstrates the use of 'bsl::istringstream' to read // data of various types from a 'bsl::string' object. // // Suppose we want to implement a simplified converter from 'bsl::string' to a // generic type, 'TYPE'. We use 'bsl::istringstream' to implement the // 'fromString' function. We initialize the input stream with the string // passed as a parameter and then we read the data from the input stream with // 'operator>>': //.. // template <class TYPE> // TYPE fromString(const bsl::string& from) // { // bsl::istringstream in(from); // TYPE val; // in >> val; // return val; // } //.. // Finally, we verify that our 'fromString' function works on some simple test // cases: //.. // assert(fromString<int>("1234") == 1234); // // assert(fromString<short>("-5") == -5); // // assert(fromString<bsl::string>("abc") == "abc"); //.. #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_stringview.h> #include <bslstl_stringbuf.h> #include <ios> #include <istream> #ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE # include <utility> #endif namespace bsl { // ========================= // class basic_istringstream // ========================= template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> class basic_istringstream : private StringBufContainer<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> , public std::basic_istream<CHAR_TYPE, CHAR_TRAITS> { // This class implements a standard input stream that provides a // constructor and manipulator for setting the sequence of characters from // which input is streamed to a supplied 'bsl::basic_string'. 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_istream<CHAR_TYPE, CHAR_TRAITS> BaseStream; typedef std::ios_base ios_base; typedef BloombergLP::bslmf::MovableRefUtil MoveUtil; private: // NOT IMPLEMENTED basic_istringstream(const basic_istringstream&); // = delete basic_istringstream& operator=(const basic_istringstream&); // = 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_istringstream(const allocator_type& allocator = allocator_type()); explicit basic_istringstream(ios_base::openmode modeBitMask, const allocator_type& allocator = allocator_type()); explicit basic_istringstream(const StringType& initialString, const allocator_type& allocator = allocator_type()); basic_istringstream(const StringType& initialString, ios_base::openmode modeBitMask, const allocator_type& allocator = allocator_type()); // Create a 'basic_istringstream' object. Optionally specify a // 'modeBitMask' indicating whether the underlying stream-buffer may // also be written to ('rdbuf' is created using // 'modeBitMask | ios_base::in'). If 'modeBitMask' is not supplied, // 'rdbuf' will be created using 'ios_base::in'. Optionally specify an // 'initialString' indicating the sequence of characters from which // input will be streamed. If 'initialString' is not supplied, there // will not be data to stream (until a subsequent call to the 'str' // manipulator). 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_istringstream( BloombergLP::bslmf::MovableRef<StringType> initialString); basic_istringstream( BloombergLP::bslmf::MovableRef<StringType> initialString, const allocator_type& allocator); basic_istringstream( BloombergLP::bslmf::MovableRef<StringType> initialString, ios_base::openmode modeBitMask); basic_istringstream( BloombergLP::bslmf::MovableRef<StringType> initialString, ios_base::openmode modeBitMask, const allocator_type& allocator); // Create a 'basic_istringstream' object. Use the specified // 'initialString' indicating the initial sequence of characters from // which input will be streamed. Optionally specify a 'modeBitMask' // indicating whether the underlying stream-buffer may also be written // to ('rdbuf' is created using 'modeBitMask | ios_base::in'). If // 'modeBitMask' is not supplied, 'rdbuf' will be created using // 'ios_base::in'. 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_istringstream( 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_istringstream' object. Use the specified // 'initialString' indicating the sequence of characters from which // input will be streamed. 'rdbuf' is created using 'ios_base::in'. // 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, allocator) , BaseStream(BaseType::rdbuf()) { } template <class SALLOC> basic_istringstream( 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_istringstream' object. Use the specified // 'initialString' indicating the sequence of characters from which // input will be streamed. Use the specified 'modeBitMask' to indicate // whether this buffer 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 | ios_base::in, allocator) , BaseStream(BaseType::rdbuf()) { } #ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE basic_istringstream(basic_istringstream&& original); // Create a 'basic_istringstream' 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_istringstream() = default; // Destroy this object. // MANIPULATORS #ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE basic_istringstream& operator=(basic_istringstream&& 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 provided as // input 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. { 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 string // stream 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_istringstream<char, char_traits<char>, allocator<char> > istringstream; typedef basic_istringstream<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wistringstream; // ============================================================================ // TEMPLATE FUNCTION DEFINITIONS // ============================================================================ // ------------------------- // class basic_istringstream // ------------------------- // CREATORS template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_istringstream(const allocator_type& allocator) : BaseType(ios_base::in, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_istringstream(ios_base::openmode modeBitMask, const allocator_type& allocator) : BaseType(modeBitMask | ios_base::in, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_istringstream(const StringType& initialString, const allocator_type& allocator) : BaseType(initialString, ios_base::in, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_istringstream(const StringType& initialString, ios_base::openmode modeBitMask, const allocator_type& allocator) : BaseType(initialString, modeBitMask | ios_base::in, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_istringstream(BloombergLP::bslmf::MovableRef<StringType> initialString) : BaseType(MoveUtil::move(initialString), ios_base::in) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_istringstream(BloombergLP::bslmf::MovableRef<StringType> initialString, const allocator_type& allocator) : BaseType(MoveUtil::move(initialString), ios_base::in, allocator) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_istringstream(BloombergLP::bslmf::MovableRef<StringType> initialString, ios_base::openmode modeBitMask) : BaseType(MoveUtil::move(initialString), modeBitMask | ios_base::in) , BaseStream(BaseType::rdbuf()) { } template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_istringstream(BloombergLP::bslmf::MovableRef<StringType> initialString, ios_base::openmode modeBitMask, const allocator_type& allocator) : BaseType(MoveUtil::move(initialString), modeBitMask | ios_base::in, allocator) , BaseStream(BaseType::rdbuf()) { } #ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_STREAM_MOVE template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: basic_istringstream(basic_istringstream&& 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_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>:: operator=(basic_istringstream&& 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_istringstream<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_istringstream<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_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::StringType basic_istringstream<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_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::StreamBufType * basic_istringstream<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_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::StringType basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::str() const & { return this->rdbuf()->str(); } #else template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline typename basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::StringType basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::str() const { return this->rdbuf()->str(); } #endif template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> inline typename basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::ViewType basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>::view() const BSLS_KEYWORD_NOEXCEPT { return this->rdbuf()->view(); } } // close namespace bsl // ============================================================================ // TYPE TRAITS // ============================================================================ namespace BloombergLP { namespace bslma { template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR> struct UsesBslmaAllocator< bsl::basic_istringstream<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> > : bsl::true_type {}; } // close namespace bslma } // close enterprise namespace #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 ----------------------------------