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