Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
String.hpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2023 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_STRING_HPP
18#define TOOLBOX_UTIL_STRING_HPP
19
22
23#include <charconv>
24#include <cstring>
25#include <sstream>
26
27namespace toolbox {
28inline namespace util {
29
30template <typename ValueT>
31constexpr ValueT from_string(std::string_view sv)
32{
34 return Traits::from_string(sv);
35}
36static_assert(from_string<int>(std::string_view{"-123"}) == -123);
37
38template <typename ValueT>
39constexpr ValueT from_string(const std::string& s)
40{
42 return Traits::from_string(s);
43}
44
45template <typename ValueT>
46constexpr ValueT from_string(const char* s)
47{
49 return Traits::from_string(std::string_view{s});
50}
51static_assert(from_string<int>("-123") == -123);
52
53template <typename ValueT>
54std::string to_string(ValueT&& val)
55{
56 std::stringstream ss;
57 ss << val;
58 return ss.str();
59}
60
61template <typename ValueT>
62// clang-format off
63requires Arithmetic<ValueT>
64std::string to_string(ValueT&& val)
65// clang-format on
66{
67 return std::to_string(val);
68}
69
70template <std::size_t SizeN>
71constexpr std::string_view to_string_view(const char (&val)[SizeN]) noexcept
72{
73 return {val, strnlen(val, SizeN)};
74}
75
76TOOLBOX_API void ltrim(std::string_view& s) noexcept;
77
78TOOLBOX_API void ltrim(std::string& s) noexcept;
79
80TOOLBOX_API void rtrim(std::string_view& s) noexcept;
81
82TOOLBOX_API void rtrim(std::string& s) noexcept;
83
84inline void trim(std::string_view& s) noexcept
85{
86 ltrim(s);
87 rtrim(s);
88}
89
90inline void trim(std::string& s) noexcept
91{
92 ltrim(s);
93 rtrim(s);
94}
95
96inline std::string_view ltrim_copy(std::string_view s) noexcept
97{
98 ltrim(s);
99 return s;
100}
101
102inline std::string ltrim_copy(std::string s) noexcept
103{
104 ltrim(s);
105 return s;
106}
107
108inline std::string_view rtrim_copy(std::string_view s) noexcept
109{
110 rtrim(s);
111 return s;
112}
113
114inline std::string rtrim_copy(std::string s) noexcept
115{
116 rtrim(s);
117 return s;
118}
119
120inline std::string_view trim_copy(std::string_view s) noexcept
121{
122 trim(s);
123 return s;
124}
125
126inline std::string trim_copy(std::string s) noexcept
127{
128 trim(s);
129 return s;
130}
131
132TOOLBOX_API std::pair<std::string_view, std::string_view> split_pair(std::string_view s,
133 std::string_view delim) noexcept;
134
135TOOLBOX_API std::pair<std::string, std::string> split_pair(const std::string& s,
136 std::string_view delim);
137
138TOOLBOX_API std::pair<std::string_view, std::string_view> split_pair(std::string_view s,
139 char delim) noexcept;
140
141TOOLBOX_API std::pair<std::string, std::string> split_pair(const std::string& s, char delim);
142
148template <char PadC>
149constexpr std::size_t pstrlen(const char* src, std::size_t n) noexcept
150{
151 if constexpr (PadC == '\0') {
152 // Optimised case.
153 return strnlen(src, n);
154 } else {
155 std::size_t i{0};
156 while (i < n && src[i] != PadC) {
157 ++i;
158 }
159 return i;
160 }
161}
162
168template <char PadC, std::size_t SizeN>
169constexpr std::size_t pstrlen(const char (&src)[SizeN]) noexcept
170{
171 return pstrlen<PadC>(src, SizeN);
172}
173
180template <char PadC>
181constexpr std::size_t pstrcpy(char* dst, const char* src, std::size_t n) noexcept
182{
183 if constexpr (PadC == '\0') {
184#ifndef __clang__
185#pragma GCC diagnostic push
186#pragma GCC diagnostic ignored "-Wstringop-truncation"
187#endif
188 // Optimised case.
189 return stpncpy(dst, src, n) - dst;
190#ifndef __clang__
191#pragma GCC diagnostic pop
192#endif
193 } else {
194 std::size_t i{0};
195 for (; i < n && src[i] != '\0'; ++i) {
196 dst[i] = src[i];
197 }
198 if (i < n) {
199 std::memset(dst + i, PadC, n - i);
200 }
201 return i;
202 }
203}
204
211template <char PadC, std::size_t SizeN>
212constexpr std::size_t pstrcpy(char (&dst)[SizeN], const char* src) noexcept
213{
214 return pstrcpy<PadC>(dst, src, SizeN);
215}
216
223template <char PadC>
224constexpr std::size_t pstrcpy(char* dst, std::string_view src, std::size_t n) noexcept
225{
226 const std::size_t len{std::min(n, src.size())};
227 if (len > 0) {
228 std::memcpy(dst, src.data(), len);
229 }
230 if (len < n) {
231 std::memset(dst + len, PadC, n - len);
232 }
233 return len;
234}
235
242template <char PadC, std::size_t SizeN>
243constexpr std::size_t pstrcpy(char (&dst)[SizeN], std::string_view src) noexcept
244{
245 return pstrcpy<PadC>(dst, src, SizeN);
246}
247
248template <char PadC>
249constexpr std::size_t pstrcpyid(char* dst, std::int64_t id, std::size_t n) noexcept
250{
251 auto* end = dst + n;
252 const auto [eptr, ec] = std::to_chars(dst, end, id);
253 if (ec == std::errc::value_too_large) {
254 return 0;
255 }
256 if (eptr < end) {
257 std::memset(eptr, PadC, end - eptr);
258 }
259 return eptr - dst;
260}
261
262template <char PadC, std::size_t SizeN>
263constexpr std::size_t pstrcpyid(char (&dst)[SizeN], std::int64_t id) noexcept
264{
265 return pstrcpyid<PadC>(dst, id, SizeN);
266}
267
273template <char PadC>
274constexpr std::size_t lpstrlen(const char* src, std::size_t n) noexcept
275{
276 std::size_t i{0};
277 while (i < n && src[i] == PadC) {
278 ++i;
279 }
280 return n - i;
281}
282
288template <char PadC, std::size_t SizeN>
289constexpr std::size_t lpstrlen(const char (&src)[SizeN]) noexcept
290{
291 return lpstrlen<PadC>(src, SizeN);
292}
293
300template <char PadC>
301constexpr std::size_t lpstrcpy(char* dst, const char* src, std::size_t n) noexcept
302{
303 const std::size_t len{strnlen(src, n)};
304 if (len < n) {
305 std::memset(dst, PadC, n - len);
306 }
307 if (len > 0) {
308 std::memcpy(dst + (n - len), src, len);
309 }
310 return len;
311}
312
319template <char PadC, std::size_t SizeN>
320constexpr std::size_t lpstrcpy(char (&dst)[SizeN], const char* src) noexcept
321{
322 return lpstrcpy<PadC>(dst, src, SizeN);
323}
324
331template <char PadC>
332constexpr std::size_t lpstrcpy(char* dst, std::string_view src, std::size_t n) noexcept
333{
334 const std::size_t len{std::min(n, src.size())};
335 if (len < n) {
336 std::memset(dst, PadC, n - len);
337 }
338 if (len > 0) {
339 std::memcpy(dst + (n - len), src.data(), len);
340 }
341 return len;
342}
343
350template <char PadC, std::size_t SizeN>
351constexpr std::size_t lpstrcpy(char (&dst)[SizeN], std::string_view src) noexcept
352{
353 return lpstrcpy<PadC>(dst, src, SizeN);
354}
355
356template <typename... ArgsT>
357std::string make_string(ArgsT&&... args)
358{
359 std::stringstream os;
360 (os << ... << args);
361 return os.str();
362}
363} // namespace util
364} // namespace toolbox
365
366#endif // TOOLBOX_UTIL_STRING_HPP
#define TOOLBOX_API
Definition Config.h:39
pair< string_view, string_view > split_pair(string_view s, string_view delim) noexcept
Definition String.cpp:52
std::string to_string(ValueT &&val)
Definition String.hpp:54
void rtrim(string_view &s) noexcept
Definition String.cpp:40
void trim(std::string_view &s) noexcept
Definition String.hpp:84
constexpr std::size_t lpstrlen(const char *src, std::size_t n) noexcept
Definition String.hpp:274
std::string make_string(ArgsT &&... args)
Definition String.hpp:357
std::string_view ltrim_copy(std::string_view s) noexcept
Definition String.hpp:96
std::string_view rtrim_copy(std::string_view s) noexcept
Definition String.hpp:108
void ltrim(string_view &s) noexcept
Definition String.cpp:28
constexpr std::string_view to_string_view(const char(&val)[SizeN]) noexcept
Definition String.hpp:71
constexpr std::size_t pstrlen(const char *src, std::size_t n) noexcept
Definition String.hpp:149
constexpr ValueT from_string(std::string_view sv)
Definition String.hpp:31
std::string_view sv
Definition Tokeniser.hpp:26
std::string_view trim_copy(std::string_view s) noexcept
Definition String.hpp:120
constexpr std::size_t pstrcpy(char *dst, const char *src, std::size_t n) noexcept
Definition String.hpp:181
constexpr std::size_t pstrcpyid(char *dst, std::int64_t id, std::size_t n) noexcept
Definition String.hpp:249
constexpr std::size_t lpstrcpy(char *dst, const char *src, std::size_t n) noexcept
Definition String.hpp:301
constexpr auto bind() noexcept
Definition Slot.hpp:92