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