Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:27:25

0001 // Copyright 2017 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
0014 
0015 #ifndef ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_
0016 #define ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_
0017 
0018 #include <cassert>
0019 #include <ios>
0020 #include <ostream>
0021 #include <streambuf>
0022 #include <string>
0023 #include <utility>
0024 
0025 #include "absl/base/config.h"
0026 
0027 namespace absl {
0028 ABSL_NAMESPACE_BEGIN
0029 namespace strings_internal {
0030 
0031 // The same as std::ostringstream but appends to a user-specified std::string,
0032 // and is faster. It is ~70% faster to create, ~50% faster to write to, and
0033 // completely free to extract the result std::string.
0034 //
0035 //   std::string s;
0036 //   OStringStream strm(&s);
0037 //   strm << 42 << ' ' << 3.14;  // appends to `s`
0038 //
0039 // The stream object doesn't have to be named. Starting from C++11 operator<<
0040 // works with rvalues of std::ostream.
0041 //
0042 //   std::string s;
0043 //   OStringStream(&s) << 42 << ' ' << 3.14;  // appends to `s`
0044 //
0045 // OStringStream is faster to create than std::ostringstream but it's still
0046 // relatively slow. Avoid creating multiple streams where a single stream will
0047 // do.
0048 //
0049 // Creates unnecessary instances of OStringStream: slow.
0050 //
0051 //   std::string s;
0052 //   OStringStream(&s) << 42;
0053 //   OStringStream(&s) << ' ';
0054 //   OStringStream(&s) << 3.14;
0055 //
0056 // Creates a single instance of OStringStream and reuses it: fast.
0057 //
0058 //   std::string s;
0059 //   OStringStream strm(&s);
0060 //   strm << 42;
0061 //   strm << ' ';
0062 //   strm << 3.14;
0063 //
0064 // Note: flush() has no effect. No reason to call it.
0065 class OStringStream final : public std::ostream {
0066  public:
0067   // The argument can be null, in which case you'll need to call str(p) with a
0068   // non-null argument before you can write to the stream.
0069   //
0070   // The destructor of OStringStream doesn't use the std::string. It's OK to
0071   // destroy the std::string before the stream.
0072   explicit OStringStream(std::string* str)
0073       : std::ostream(&buf_), buf_(str) {}
0074   OStringStream(OStringStream&& that)
0075       : std::ostream(std::move(static_cast<std::ostream&>(that))),
0076         buf_(that.buf_) {
0077     rdbuf(&buf_);
0078   }
0079   OStringStream& operator=(OStringStream&& that) {
0080     std::ostream::operator=(std::move(static_cast<std::ostream&>(that)));
0081     buf_ = that.buf_;
0082     rdbuf(&buf_);
0083     return *this;
0084   }
0085 
0086   std::string* str() { return buf_.str(); }
0087   const std::string* str() const { return buf_.str(); }
0088   void str(std::string* str) { buf_.str(str); }
0089 
0090  private:
0091   class Streambuf final : public std::streambuf {
0092    public:
0093     explicit Streambuf(std::string* str) : str_(str) {}
0094     Streambuf(const Streambuf&) = default;
0095     Streambuf& operator=(const Streambuf&) = default;
0096 
0097     std::string* str() { return str_; }
0098     const std::string* str() const { return str_; }
0099     void str(std::string* str) { str_ = str; }
0100 
0101    protected:
0102     int_type overflow(int c) override;
0103     std::streamsize xsputn(const char* s, std::streamsize n) override;
0104 
0105    private:
0106     std::string* str_;
0107   } buf_;
0108 };
0109 
0110 }  // namespace strings_internal
0111 ABSL_NAMESPACE_END
0112 }  // namespace absl
0113 
0114 #endif  // ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_