1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors. 2*9356374aSAndroid Build Coastguard Worker // 3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*9356374aSAndroid Build Coastguard Worker // 7*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0 8*9356374aSAndroid Build Coastguard Worker // 9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*9356374aSAndroid Build Coastguard Worker // limitations under the License. 14*9356374aSAndroid Build Coastguard Worker 15*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_ 16*9356374aSAndroid Build Coastguard Worker #define ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_ 17*9356374aSAndroid Build Coastguard Worker 18*9356374aSAndroid Build Coastguard Worker #include <cassert> 19*9356374aSAndroid Build Coastguard Worker #include <ios> 20*9356374aSAndroid Build Coastguard Worker #include <ostream> 21*9356374aSAndroid Build Coastguard Worker #include <streambuf> 22*9356374aSAndroid Build Coastguard Worker #include <string> 23*9356374aSAndroid Build Coastguard Worker #include <utility> 24*9356374aSAndroid Build Coastguard Worker 25*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h" 26*9356374aSAndroid Build Coastguard Worker 27*9356374aSAndroid Build Coastguard Worker namespace absl { 28*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN 29*9356374aSAndroid Build Coastguard Worker namespace strings_internal { 30*9356374aSAndroid Build Coastguard Worker 31*9356374aSAndroid Build Coastguard Worker // The same as std::ostringstream but appends to a user-specified std::string, 32*9356374aSAndroid Build Coastguard Worker // and is faster. It is ~70% faster to create, ~50% faster to write to, and 33*9356374aSAndroid Build Coastguard Worker // completely free to extract the result std::string. 34*9356374aSAndroid Build Coastguard Worker // 35*9356374aSAndroid Build Coastguard Worker // std::string s; 36*9356374aSAndroid Build Coastguard Worker // OStringStream strm(&s); 37*9356374aSAndroid Build Coastguard Worker // strm << 42 << ' ' << 3.14; // appends to `s` 38*9356374aSAndroid Build Coastguard Worker // 39*9356374aSAndroid Build Coastguard Worker // The stream object doesn't have to be named. Starting from C++11 operator<< 40*9356374aSAndroid Build Coastguard Worker // works with rvalues of std::ostream. 41*9356374aSAndroid Build Coastguard Worker // 42*9356374aSAndroid Build Coastguard Worker // std::string s; 43*9356374aSAndroid Build Coastguard Worker // OStringStream(&s) << 42 << ' ' << 3.14; // appends to `s` 44*9356374aSAndroid Build Coastguard Worker // 45*9356374aSAndroid Build Coastguard Worker // OStringStream is faster to create than std::ostringstream but it's still 46*9356374aSAndroid Build Coastguard Worker // relatively slow. Avoid creating multiple streams where a single stream will 47*9356374aSAndroid Build Coastguard Worker // do. 48*9356374aSAndroid Build Coastguard Worker // 49*9356374aSAndroid Build Coastguard Worker // Creates unnecessary instances of OStringStream: slow. 50*9356374aSAndroid Build Coastguard Worker // 51*9356374aSAndroid Build Coastguard Worker // std::string s; 52*9356374aSAndroid Build Coastguard Worker // OStringStream(&s) << 42; 53*9356374aSAndroid Build Coastguard Worker // OStringStream(&s) << ' '; 54*9356374aSAndroid Build Coastguard Worker // OStringStream(&s) << 3.14; 55*9356374aSAndroid Build Coastguard Worker // 56*9356374aSAndroid Build Coastguard Worker // Creates a single instance of OStringStream and reuses it: fast. 57*9356374aSAndroid Build Coastguard Worker // 58*9356374aSAndroid Build Coastguard Worker // std::string s; 59*9356374aSAndroid Build Coastguard Worker // OStringStream strm(&s); 60*9356374aSAndroid Build Coastguard Worker // strm << 42; 61*9356374aSAndroid Build Coastguard Worker // strm << ' '; 62*9356374aSAndroid Build Coastguard Worker // strm << 3.14; 63*9356374aSAndroid Build Coastguard Worker // 64*9356374aSAndroid Build Coastguard Worker // Note: flush() has no effect. No reason to call it. 65*9356374aSAndroid Build Coastguard Worker class OStringStream final : public std::ostream { 66*9356374aSAndroid Build Coastguard Worker public: 67*9356374aSAndroid Build Coastguard Worker // The argument can be null, in which case you'll need to call str(p) with a 68*9356374aSAndroid Build Coastguard Worker // non-null argument before you can write to the stream. 69*9356374aSAndroid Build Coastguard Worker // 70*9356374aSAndroid Build Coastguard Worker // The destructor of OStringStream doesn't use the std::string. It's OK to 71*9356374aSAndroid Build Coastguard Worker // destroy the std::string before the stream. OStringStream(std::string * str)72*9356374aSAndroid Build Coastguard Worker explicit OStringStream(std::string* str) 73*9356374aSAndroid Build Coastguard Worker : std::ostream(&buf_), buf_(str) {} OStringStream(OStringStream && that)74*9356374aSAndroid Build Coastguard Worker OStringStream(OStringStream&& that) 75*9356374aSAndroid Build Coastguard Worker : std::ostream(std::move(static_cast<std::ostream&>(that))), 76*9356374aSAndroid Build Coastguard Worker buf_(that.buf_) { 77*9356374aSAndroid Build Coastguard Worker rdbuf(&buf_); 78*9356374aSAndroid Build Coastguard Worker } 79*9356374aSAndroid Build Coastguard Worker OStringStream& operator=(OStringStream&& that) { 80*9356374aSAndroid Build Coastguard Worker std::ostream::operator=(std::move(static_cast<std::ostream&>(that))); 81*9356374aSAndroid Build Coastguard Worker buf_ = that.buf_; 82*9356374aSAndroid Build Coastguard Worker rdbuf(&buf_); 83*9356374aSAndroid Build Coastguard Worker return *this; 84*9356374aSAndroid Build Coastguard Worker } 85*9356374aSAndroid Build Coastguard Worker str()86*9356374aSAndroid Build Coastguard Worker std::string* str() { return buf_.str(); } str()87*9356374aSAndroid Build Coastguard Worker const std::string* str() const { return buf_.str(); } str(std::string * str)88*9356374aSAndroid Build Coastguard Worker void str(std::string* str) { buf_.str(str); } 89*9356374aSAndroid Build Coastguard Worker 90*9356374aSAndroid Build Coastguard Worker private: 91*9356374aSAndroid Build Coastguard Worker class Streambuf final : public std::streambuf { 92*9356374aSAndroid Build Coastguard Worker public: Streambuf(std::string * str)93*9356374aSAndroid Build Coastguard Worker explicit Streambuf(std::string* str) : str_(str) {} 94*9356374aSAndroid Build Coastguard Worker Streambuf(const Streambuf&) = default; 95*9356374aSAndroid Build Coastguard Worker Streambuf& operator=(const Streambuf&) = default; 96*9356374aSAndroid Build Coastguard Worker str()97*9356374aSAndroid Build Coastguard Worker std::string* str() { return str_; } str()98*9356374aSAndroid Build Coastguard Worker const std::string* str() const { return str_; } str(std::string * str)99*9356374aSAndroid Build Coastguard Worker void str(std::string* str) { str_ = str; } 100*9356374aSAndroid Build Coastguard Worker 101*9356374aSAndroid Build Coastguard Worker protected: 102*9356374aSAndroid Build Coastguard Worker int_type overflow(int c) override; 103*9356374aSAndroid Build Coastguard Worker std::streamsize xsputn(const char* s, std::streamsize n) override; 104*9356374aSAndroid Build Coastguard Worker 105*9356374aSAndroid Build Coastguard Worker private: 106*9356374aSAndroid Build Coastguard Worker std::string* str_; 107*9356374aSAndroid Build Coastguard Worker } buf_; 108*9356374aSAndroid Build Coastguard Worker }; 109*9356374aSAndroid Build Coastguard Worker 110*9356374aSAndroid Build Coastguard Worker } // namespace strings_internal 111*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END 112*9356374aSAndroid Build Coastguard Worker } // namespace absl 113*9356374aSAndroid Build Coastguard Worker 114*9356374aSAndroid Build Coastguard Worker #endif // ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_ 115