Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Stream.hpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2022 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#ifndef TOOLBOX_UTIL_STREAM_HPP
18#define TOOLBOX_UTIL_STREAM_HPP
19
21
22#include <experimental/iterator>
23
24namespace toolbox {
25inline namespace util {
26namespace detail {
27
28struct ResetState {};
29TOOLBOX_API std::ostream& operator<<(std::ostream& os, ResetState) noexcept;
30
31} // namespace detail
32
34constexpr detail::ResetState reset_state{};
35
36TOOLBOX_API void reset(std::ostream& os) noexcept;
37
39template <std::size_t MaxN>
40class StreamBuf final : public std::streambuf {
41 public:
43 explicit StreamBuf(std::nullptr_t) noexcept {}
45 : storage_{make_storage<MaxN>}
46 {
47 setp(storage_->begin(), storage_->end());
48 }
49 ~StreamBuf() override = default;
50
51 // Copy.
52 StreamBuf(const StreamBuf&) = delete;
53 StreamBuf& operator=(const StreamBuf&) = delete;
54
55 // Move.
56 StreamBuf(StreamBuf&&) = delete;
58
59 const char* data() const noexcept { return pbase(); }
60 bool empty() const noexcept { return pbase() == pptr(); }
61 std::size_t size() const noexcept { return pptr() - pbase(); }
62
65 {
67 storage_.swap(storage);
68 setp(nullptr, nullptr);
69 return storage;
70 }
72 void set_storage(StoragePtr<MaxN> storage) noexcept { swap_storage(storage); }
75 {
76 if (storage_) {
77 setp(storage_->begin(), storage_->end());
78 }
79 }
80
81 private:
83 void swap_storage(StoragePtr<MaxN>& storage) noexcept
84 {
85 storage_.swap(storage);
86 if (storage_) {
87 auto* const begin = static_cast<char*>(storage_.get());
88 setp(begin, begin + MaxN);
89 } else {
90 setp(nullptr, nullptr);
91 }
92 }
93 StoragePtr<MaxN> storage_;
94};
95
97template <std::size_t MaxN>
98class OStream final : public std::ostream {
99 public:
101 explicit OStream(std::nullptr_t) noexcept
102 : std::ostream{nullptr}
103 , buf_{nullptr}
104 {
105 rdbuf(&buf_);
106 }
108 : std::ostream{nullptr}
109 {
110 rdbuf(&buf_);
111 }
112 ~OStream() override = default;
113
114 // Copy.
115 OStream(const OStream&) = delete;
116 OStream& operator=(const OStream&) = delete;
117
118 // Move.
119 OStream(OStream&&) = delete;
121
123 const char* data() const noexcept { return buf_.data(); }
124 bool empty() const noexcept { return buf_.empty(); }
125 std::size_t size() const noexcept { return buf_.size(); }
126
128 StoragePtr<MaxN> release_storage() noexcept { return buf_.release_storage(); }
131 {
132 buf_.set_storage(std::move(storage));
133 clear();
134 }
137 {
138 buf_.reset();
139 clear();
140 }
141
142 private:
143 StreamBuf<MaxN> buf_;
144};
145
146template <std::size_t MaxN>
147class StaticStreamBuf final : public std::streambuf {
148 public:
150 ~StaticStreamBuf() override = default;
151
152 // Copy.
155
156 // Move.
159
160 const char* data() const noexcept { return pbase(); }
161 bool empty() const noexcept { return pbase() == pptr(); }
162 std::size_t size() const noexcept { return pptr() - pbase(); }
163
164 std::string_view str() const noexcept { return {data(), size()}; }
166 void reset() noexcept { setp(buf_, buf_ + MaxN); };
167
168 private:
169 char buf_[MaxN];
170};
171
172template <std::size_t MaxN>
173class OStaticStream final : public std::ostream {
174 public:
176 : std::ostream{nullptr}
177 {
178 rdbuf(&buf_);
179 }
180 ~OStaticStream() override = default;
181
182 // Copy.
183 OStaticStream(const OStaticStream&) = delete;
185
186 // Move.
189
190 const char* data() const noexcept { return buf_.data(); }
191 bool empty() const noexcept { return buf_.empty(); }
192 std::size_t size() const noexcept { return buf_.size(); }
193
194 std::string_view str() const noexcept { return buf_.str(); }
195 operator std::string_view() const noexcept
196 {
197 return buf_.str();
198 } // NOLINT(hicpp-explicit-conversions)
201 {
202 buf_.reset();
203 clear();
204 };
205
206 private:
208};
209
210template <std::size_t MaxN, typename ValueT>
212{
213 static_cast<std::ostream&>(os) << std::forward<ValueT>(val);
214 return os;
215}
216
217using OStreamJoiner = std::experimental::ostream_joiner<char>;
218
219template <auto DelimT, typename ArgT, typename... ArgsT>
220void join(std::ostream& os, const ArgT& arg, const ArgsT&... args)
221{
222 os << arg;
223 (..., [&os](const auto& arg) { os << DelimT << arg; }(args));
224}
225
226} // namespace util
227} // namespace toolbox
228
230template <typename ValueT>
231ostream_joiner<char>& operator<<(ostream_joiner<char>& osj, const ValueT& value)
232{
233 osj = value;
234 return osj;
235}
236} // namespace std::experimental
237
238#endif // TOOLBOX_UTIL_STREAM_HPP
#define TOOLBOX_API
Definition Config.h:39
OStaticStream & operator=(OStaticStream &&)=delete
OStaticStream(OStaticStream &&)=delete
const char * data() const noexcept
Definition Stream.hpp:190
OStaticStream & operator=(const OStaticStream &)=delete
bool empty() const noexcept
Definition Stream.hpp:191
std::size_t size() const noexcept
Definition Stream.hpp:192
~OStaticStream() override=default
void reset() noexcept
Reset the current position back to the beginning of the buffer.
Definition Stream.hpp:200
std::string_view str() const noexcept
Definition Stream.hpp:194
OStaticStream(const OStaticStream &)=delete
OStream uses a dynamic storage acquired from the custom allocator.
Definition Stream.hpp:98
OStream(std::nullptr_t) noexcept
Constructor for initialising the StreamBuf with a null buffer.
Definition Stream.hpp:101
static StoragePtr< MaxN > make_storage()
Definition Stream.hpp:122
void reset() noexcept
Reset the current position back to the beginning of the buffer and clear i/o state.
Definition Stream.hpp:136
~OStream() override=default
StoragePtr< MaxN > release_storage() noexcept
Release the managed storage.
Definition Stream.hpp:128
OStream(OStream &&)=delete
OStream & operator=(OStream &&)=delete
std::size_t size() const noexcept
Definition Stream.hpp:125
void set_storage(StoragePtr< MaxN > storage) noexcept
Update the internal storage and clear i/o state.
Definition Stream.hpp:130
bool empty() const noexcept
Definition Stream.hpp:124
OStream & operator=(const OStream &)=delete
const char * data() const noexcept
Definition Stream.hpp:123
OStream(const OStream &)=delete
StaticStreamBuf(StaticStreamBuf &&)=delete
bool empty() const noexcept
Definition Stream.hpp:161
StaticStreamBuf(const StaticStreamBuf &)=delete
std::string_view str() const noexcept
Definition Stream.hpp:164
const char * data() const noexcept
Definition Stream.hpp:160
StaticStreamBuf & operator=(const StaticStreamBuf &)=delete
void reset() noexcept
Reset the current position back to the beginning of the buffer.
Definition Stream.hpp:166
~StaticStreamBuf() override=default
std::size_t size() const noexcept
Definition Stream.hpp:162
StaticStreamBuf & operator=(StaticStreamBuf &&)=delete
StreamBuf uses a dynamic storage acquired from the custom allocator.
Definition Stream.hpp:40
StreamBuf & operator=(StreamBuf &&)=delete
std::size_t size() const noexcept
Definition Stream.hpp:61
bool empty() const noexcept
Definition Stream.hpp:60
StreamBuf(const StreamBuf &)=delete
StreamBuf(std::nullptr_t) noexcept
Constructor for initialising the StreamBuf with a null buffer.
Definition Stream.hpp:43
StoragePtr< MaxN > release_storage() noexcept
Release the managed storage.
Definition Stream.hpp:64
StreamBuf(StreamBuf &&)=delete
StreamBuf & operator=(const StreamBuf &)=delete
~StreamBuf() override=default
void set_storage(StoragePtr< MaxN > storage) noexcept
Update the internal storage.
Definition Stream.hpp:72
void reset() noexcept
Reset the current position back to the beginning of the buffer.
Definition Stream.hpp:74
const char * data() const noexcept
Definition Stream.hpp:59
STL namespace.
ostream & operator<<(ostream &os, const pair< T, U > &p)
Definition Parser.ut.cpp:29
ostream & operator<<(ostream &os, PutPercentiles pp)
Definition Utility.cpp:96
void clear(timeval &tv) noexcept
Definition Time.hpp:294
constexpr detail::ResetState reset_state
I/O manipulator that resets I/O state.
Definition Stream.hpp:34
TOOLBOX_API void reset(std::ostream &os) noexcept
void join(std::ostream &os, const ArgT &arg, const ArgsT &... args)
Definition Stream.hpp:220
std::experimental::ostream_joiner< char > OStreamJoiner
Definition Stream.hpp:217
StoragePtr< SizeN > make_storage()
Returns a block of dynamic storage acquired from the custom allocator.
Definition Storage.hpp:38
std::unique_ptr< void, detail::StorageDeleter< SizeN > > StoragePtr
Definition Storage.hpp:34
constexpr auto bind() noexcept
Definition Slot.hpp:92