summaryrefslogtreecommitdiffstats
path: root/server/src/util.cppm
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/util.cppm')
-rw-r--r--server/src/util.cppm109
1 files changed, 30 insertions, 79 deletions
diff --git a/server/src/util.cppm b/server/src/util.cppm
index bdccf10..2857fe5 100644
--- a/server/src/util.cppm
+++ b/server/src/util.cppm
@@ -13,7 +13,7 @@ struct overloaded : Ts...
13 using Ts::operator()...; 13 using Ts::operator()...;
14}; 14};
15 15
16export constexpr auto parse_double( 16constexpr auto parse_double(
17 std::string_view s, 17 std::string_view s,
18 std::chars_format fmt = std::chars_format::general) noexcept 18 std::chars_format fmt = std::chars_format::general) noexcept
19 -> std::optional<double> 19 -> std::optional<double>
@@ -30,7 +30,7 @@ export constexpr auto parse_double(
30 } 30 }
31} 31}
32 32
33export constexpr auto parse_float( 33constexpr auto parse_float(
34 std::string_view s, 34 std::string_view s,
35 std::chars_format fmt = std::chars_format::general) noexcept 35 std::chars_format fmt = std::chars_format::general) noexcept
36 -> std::optional<float> 36 -> std::optional<float>
@@ -47,7 +47,7 @@ export constexpr auto parse_float(
47 } 47 }
48} 48}
49 49
50export template <class T> 50template <class T>
51class aolist : public std::enable_shared_from_this<aolist<T>> 51class aolist : public std::enable_shared_from_this<aolist<T>>
52{ 52{
53 T v_; 53 T v_;
@@ -72,7 +72,7 @@ public:
72 auto value() const noexcept -> T const& { return v_; } 72 auto value() const noexcept -> T const& { return v_; }
73}; 73};
74 74
75export constexpr auto size_from_int(int x) -> std::optional<std::size_t> 75constexpr auto size_from_int(int x) -> std::optional<std::size_t>
76{ 76{
77 static_assert( 77 static_assert(
78 sizeof(int) <= sizeof(std::size_t), 78 sizeof(int) <= sizeof(std::size_t),
@@ -82,7 +82,7 @@ export constexpr auto size_from_int(int x) -> std::optional<std::size_t>
82 return static_cast<std::size_t>(x); 82 return static_cast<std::size_t>(x);
83} 83}
84 84
85export constexpr auto int_from_size(std::size_t x) -> std::optional<int> 85constexpr auto int_from_size(std::size_t x) -> std::optional<int>
86{ 86{
87 constexpr auto int_max = size_from_int(std::numeric_limits<int>::max()); 87 constexpr auto int_max = size_from_int(std::numeric_limits<int>::max());
88 static_assert(int_max.has_value()); 88 static_assert(int_max.has_value());
@@ -91,7 +91,7 @@ export constexpr auto int_from_size(std::size_t x) -> std::optional<int>
91 return static_cast<int>(x); 91 return static_cast<int>(x);
92} 92}
93 93
94export class zstring_view 94class zstring_view
95{ 95{
96 char const* s_; 96 char const* s_;
97 std::size_t length_; 97 std::size_t length_;
@@ -107,13 +107,16 @@ public:
107 { 107 {
108 } 108 }
109 109
110 auto length() const -> std::size_t { return length_; } 110 constexpr auto length() const -> std::size_t { return length_; }
111 111
112 auto c_str() const -> char const* { return s_; } 112 constexpr auto c_str() const -> char const* { return s_; }
113 113
114 operator std::string_view() const { return std::string_view{s_, length_}; } 114 constexpr operator std::string_view() const
115 {
116 return std::string_view{s_, length_};
117 }
115 118
116 operator char const*() const { return s_; } 119 constexpr operator char const*() const { return s_; }
117}; 120};
118 121
119// View for null-terminated strings for which we might not 122// View for null-terminated strings for which we might not
@@ -123,7 +126,7 @@ public:
123// 126//
124// It is undefined behavior to assign to a lazy_zstring_view when 127// It is undefined behavior to assign to a lazy_zstring_view when
125// it is in use by other threads. 128// it is in use by other threads.
126export class lazy_zstring_view 129class lazy_zstring_view
127{ 130{
128 static constexpr auto unset_length = std::numeric_limits<std::size_t>::max(); 131 static constexpr auto unset_length = std::numeric_limits<std::size_t>::max();
129 132
@@ -136,70 +139,21 @@ public:
136 : s_{s}, length_{s ? unset_length : 0} 139 : s_{s}, length_{s ? unset_length : 0}
137 { 140 {
138 } 141 }
142 lazy_zstring_view(lazy_zstring_view const& sv) noexcept;
143 lazy_zstring_view(lazy_zstring_view&& sv) noexcept;
139 144
140 ~lazy_zstring_view() = default; 145 ~lazy_zstring_view() = default;
141 146
142 lazy_zstring_view(lazy_zstring_view const& sv) noexcept 147 auto operator=(lazy_zstring_view const& rhs) noexcept -> lazy_zstring_view&;
143 : s_{sv.s_}, length_{sv.length_.load(std::memory_order_acquire)} 148 auto operator=(lazy_zstring_view&& rhs) noexcept -> lazy_zstring_view&;
144 {
145 }
146
147 lazy_zstring_view(lazy_zstring_view&& sv) noexcept
148 : s_{sv.s_}, length_{sv.length_.load(std::memory_order_acquire)}
149 {
150 }
151
152 auto operator=(lazy_zstring_view const& rhs) noexcept -> lazy_zstring_view&
153 {
154 if (this != &rhs)
155 {
156 s_ = rhs.s_;
157 length_.store(
158 rhs.length_.load(std::memory_order_acquire),
159 std::memory_order_release);
160 }
161 return *this;
162 }
163
164 auto operator=(lazy_zstring_view&& rhs) noexcept -> lazy_zstring_view&
165 {
166 return *this = rhs; // use the copy assignment operator
167 }
168
169 auto length() const noexcept -> std::size_t
170 {
171 if (auto v = length_.load(std::memory_order_acquire); v != unset_length)
172 return v;
173 auto l = std::char_traits<char>::length(s_);
174 length_.store(l, std::memory_order_release);
175 return l;
176 }
177
178 auto c_str() const noexcept -> char const* { return s_; }
179 149
180 operator std::string_view() const noexcept 150 auto length() const noexcept -> std::size_t;
181 { 151 auto c_str() const noexcept -> char const*;
182 return std::string_view{s_, length()};
183 }
184 152
185 operator char const*() const noexcept { return s_; } 153 operator std::string_view() const noexcept;
154 operator char const*() const noexcept;
186 155
187 auto operator==(std::string_view sv) const noexcept -> bool 156 auto operator==(std::string_view sv) const noexcept -> bool;
188 {
189 if (auto v = length_.load(std::memory_order_acquire); v != unset_length)
190 if (sv.length() != v)
191 return false;
192 auto res = std::char_traits<char>::compare(s_, sv.data(), sv.length());
193 if (res != 0)
194 return false;
195 // Strings are equal for sv.length() characters.
196 if (s_[sv.length()] != '\0')
197 return false;
198 // Strings are actually equal, and we have just found out the
199 // length of this string, so we might as well set it.
200 length_.store(sv.length(), std::memory_order_release);
201 return true;
202 }
203}; 157};
204 158
205constexpr auto operator""_zsv(char const* s, std::size_t length) noexcept 159constexpr auto operator""_zsv(char const* s, std::size_t length) noexcept
@@ -208,12 +162,9 @@ constexpr auto operator""_zsv(char const* s, std::size_t length) noexcept
208 return zstring_view{s, length}; 162 return zstring_view{s, length};
209} 163}
210 164
211auto operator==(zstring_view lhs, zstring_view rhs) -> bool 165auto operator==(zstring_view lhs, zstring_view rhs) -> bool;
212{
213 return std::string_view{lhs} == std::string_view{rhs};
214}
215 166
216export constexpr auto split_on(std::string_view s, char c) 167constexpr auto split_on(std::string_view s, char c)
217 -> std::pair<std::string_view, std::optional<std::string_view>> 168 -> std::pair<std::string_view, std::optional<std::string_view>>
218{ 169{
219 if (auto i = s.find(c); i != std::string_view::npos) 170 if (auto i = s.find(c); i != std::string_view::npos)
@@ -221,10 +172,10 @@ export constexpr auto split_on(std::string_view s, char c)
221 return std::make_pair(s, std::nullopt); 172 return std::make_pair(s, std::nullopt);
222} 173}
223 174
224export template <class T> 175template <class T>
225class not_null; 176class not_null;
226 177
227export template <class T> 178template <class T>
228class not_null<T*> 179class not_null<T*>
229{ 180{
230 T* p_; 181 T* p_;
@@ -264,10 +215,10 @@ public:
264 215
265 auto operator->() const noexcept -> T* { return p_; } 216 auto operator->() const noexcept -> T* { return p_; }
266}; 217};
267export template <class T> 218template <class T>
268explicit not_null(T*) -> not_null<T*>; 219explicit not_null(T*) -> not_null<T*>;
269 220
270export template <> 221template <>
271class not_null<lazy_zstring_view> 222class not_null<lazy_zstring_view>
272{ 223{
273 lazy_zstring_view s_; 224 lazy_zstring_view s_;
@@ -285,6 +236,6 @@ public:
285 operator std::string_view() const noexcept { return s_; } 236 operator std::string_view() const noexcept { return s_; }
286 operator char const*() const noexcept { return s_; } 237 operator char const*() const noexcept { return s_; }
287}; 238};
288export explicit not_null(lazy_zstring_view s) -> not_null<lazy_zstring_view>; 239explicit not_null(lazy_zstring_view s) -> not_null<lazy_zstring_view>;
289 240
290} // namespace routemon::util 241} // namespace routemon::util