Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
StringBuf.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_STRINGBUF_HPP
18#define TOOLBOX_UTIL_STRINGBUF_HPP
19
21
22#include <cstring>
23#include <string_view>
24
25#include <boost/container_hash/hash.hpp>
26
27namespace toolbox {
28inline namespace util {
29
31template <std::size_t MaxN>
32class StringBuf {
33 public:
34 template <std::size_t MaxR>
35 StringBuf(const StringBuf<MaxR>& rhs) noexcept
36 {
37 assign(rhs.data(), rhs.size());
38 }
39 explicit StringBuf(std::string_view rhs) noexcept { assign(rhs.data(), rhs.size()); }
40 constexpr StringBuf() noexcept = default;
41
43
44 // Copy.
46 StringBuf& operator=(const StringBuf& rhs) noexcept
47 {
48 assign(rhs.data(), rhs.size());
49 return *this;
50 }
51
52 // Move.
55
56 template <std::size_t MaxR>
58 {
59 assign(rhs.data(), rhs.size());
60 return *this;
61 }
62 StringBuf& operator=(std::string_view rhs) noexcept
63 {
64 assign(rhs.data(), rhs.size());
65 return *this;
66 }
67 template <std::size_t MaxR>
69 {
70 append(rhs.data(), rhs.size());
71 return *this;
72 }
73 StringBuf& operator+=(std::string_view rhs) noexcept
74 {
75 append(rhs.data(), rhs.size());
76 return *this;
77 }
78
79 constexpr const char* data() const noexcept { return buf_; }
80 constexpr bool empty() const noexcept { return len_ == 0; }
81 constexpr std::size_t size() const noexcept { return len_; }
82 constexpr void clear() noexcept { len_ = 0; }
83
84 void assign(std::string_view rhs) noexcept { assign(rhs.data(), rhs.size()); }
85 void append(std::string_view rhs) noexcept { append(rhs.data(), rhs.size()); }
86
87 template <typename TypeT>
88 auto operator<=>(const TypeT& rhs) const noexcept
89 {
90 return compare(rhs.data(), rhs.size());
91 }
92 template <typename TypeT>
93 bool operator==(const TypeT& rhs) const noexcept
94 {
95 return size() == rhs.size() && compare(rhs.data(), rhs.size()) == 0;
96 }
97
98 private:
99 void assign(const char* rdata, std::size_t rlen) noexcept
100 {
101 len_ = std::min(rlen, MaxN);
102 if (len_ > 0) {
103#pragma GCC diagnostic push
104#pragma GCC diagnostic ignored "-Wnonnull"
105 std::memcpy(buf_, rdata, len_);
106#pragma GCC diagnostic pop
107 }
108 }
109 void append(const char* rdata, std::size_t rlen) noexcept
110 {
111 rlen = std::min(rlen, MaxN - len_);
112 if (rlen > 0) {
113 std::memcpy(buf_ + len_, rdata, rlen);
114 len_ += rlen;
115 }
116 }
117 auto compare(const char* rdata, std::size_t rlen) const noexcept
118 {
119 std::strong_ordering result{std::memcmp(buf_, rdata, std::min(size(), rlen)) <=> 0};
120 if (result == nullptr) {
121 result = size() <=> rlen;
122 }
123 return result;
124 }
125 // Length in the first cache-line.
126 // Use int to save space.
127 int len_{0};
128 char buf_[MaxN];
129};
130
131template <std::size_t MaxN>
132constexpr std::string_view operator+(const StringBuf<MaxN>& s) noexcept
133{
134 return {s.data(), s.size()};
135}
136
137template <std::size_t MaxN, typename StreamT>
138 requires Streamable<StreamT>
140{
141 os << std::string_view{rhs.data(), rhs.size()};
142 return os;
143}
144
145} // namespace util
146} // namespace toolbox
147
148namespace std {
149template <std::size_t MaxN>
150struct hash<toolbox::util::StringBuf<MaxN>> {
151 inline std::size_t operator()(const toolbox::util::StringBuf<MaxN>& key) const
152 {
153 std::size_t h{0};
154 boost::hash_combine(h, +key);
155 return h;
156 }
157};
158} // namespace std
159
160#endif // TOOLBOX_UTIL_STRINGBUF_HPP
String buffer with fixed upper-bound.
Definition StringBuf.hpp:32
auto operator<=>(const TypeT &rhs) const noexcept
Definition StringBuf.hpp:88
void assign(std::string_view rhs) noexcept
Definition StringBuf.hpp:84
StringBuf & operator=(const StringBuf &rhs) noexcept
Definition StringBuf.hpp:46
StringBuf(const StringBuf< MaxR > &rhs) noexcept
Definition StringBuf.hpp:35
void append(std::string_view rhs) noexcept
Definition StringBuf.hpp:85
StringBuf & operator=(std::string_view rhs) noexcept
Definition StringBuf.hpp:62
constexpr StringBuf(StringBuf &&) noexcept=default
bool operator==(const TypeT &rhs) const noexcept
Definition StringBuf.hpp:93
StringBuf & operator+=(std::string_view rhs) noexcept
Definition StringBuf.hpp:73
StringBuf & operator+=(const StringBuf< MaxR > &rhs) noexcept
Definition StringBuf.hpp:68
constexpr bool empty() const noexcept
Definition StringBuf.hpp:80
constexpr const char * data() const noexcept
Definition StringBuf.hpp:79
StringBuf(std::string_view rhs) noexcept
Definition StringBuf.hpp:39
constexpr void clear() noexcept
Definition StringBuf.hpp:82
constexpr std::size_t size() const noexcept
Definition StringBuf.hpp:81
constexpr StringBuf() noexcept=default
STL namespace.
ostream & operator<<(ostream &os, const pair< T, U > &p)
Definition Parser.ut.cpp:29
constexpr std::string_view operator+(const StringBuf< MaxN > &s) noexcept
constexpr auto bind() noexcept
Definition Slot.hpp:92