lxgui
utils_string.hpp
1 #ifndef LXGUI_UTILS_STRING_HPP
2 #define LXGUI_UTILS_STRING_HPP
3 
4 #include "lxgui/lxgui.hpp"
5 #include "lxgui/utils.hpp"
6 #include "lxgui/utils_variant.hpp"
7 
8 #include <algorithm>
9 #include <array>
10 #include <iostream>
11 #include <locale>
12 #include <magic_enum.hpp>
13 #include <optional>
14 #include <string>
15 #include <string_view>
16 #include <vector>
17 
20 namespace lxgui::utils {
21 
22 using string = std::string;
23 using string_view = std::string_view;
24 using ustring = std::u32string;
25 using ustring_view = std::u32string_view;
26 
27 [[nodiscard]] string_view trim(string_view s, char c_pattern);
28 [[nodiscard]] string_view trim(string_view s, string_view patterns);
29 
30 void replace(string& s, string_view pattern, string_view replacement);
31 
32 [[nodiscard]] std::size_t count_occurrences(string_view s, string_view pattern);
33 
34 [[nodiscard]] std::vector<string_view> cut(string_view s, string_view delim);
35 [[nodiscard]] std::vector<ustring_view> cut(ustring_view s, ustring_view delim);
36 
37 [[nodiscard]] std::vector<string_view> cut_each(string_view s, string_view delim);
38 [[nodiscard]] std::vector<ustring_view> cut_each(ustring_view s, ustring_view delim);
39 
40 [[nodiscard]] std::pair<string_view, string_view> cut_first(string_view s, string_view delim);
41 [[nodiscard]] std::pair<ustring_view, ustring_view> cut_first(ustring_view s, ustring_view delim);
42 
43 [[nodiscard]] bool starts_with(string_view s, string_view pattern);
44 [[nodiscard]] bool ends_with(string_view s, string_view pattern);
45 
46 [[nodiscard]] bool has_no_content(string_view s);
47 
48 [[nodiscard]] ustring utf8_to_unicode(string_view s);
49 [[nodiscard]] string unicode_to_utf8(ustring_view s);
50 
51 [[nodiscard]] std::size_t hex_to_uint(string_view s);
52 
53 namespace impl {
54 
55 template<typename T>
56 std::optional<T> from_string(const std::locale&, string_view);
57 
58 template<>
59 std::optional<int> from_string<int>(const std::locale&, string_view);
60 
61 template<>
62 std::optional<long> from_string<long>(const std::locale&, string_view);
63 
64 template<>
65 std::optional<long long> from_string<long long>(const std::locale&, string_view);
66 
67 template<>
68 std::optional<unsigned> from_string<unsigned>(const std::locale&, string_view);
69 
70 template<>
71 std::optional<unsigned long> from_string<unsigned long>(const std::locale&, string_view);
72 
73 template<>
74 std::optional<unsigned long long> from_string<unsigned long long>(const std::locale&, string_view);
75 
76 template<>
77 std::optional<float> from_string<float>(const std::locale&, string_view);
78 
79 template<>
80 std::optional<double> from_string<double>(const std::locale&, string_view);
81 
82 template<typename T>
83 std::optional<T> from_string(const std::locale&, ustring_view);
84 
85 template<>
86 std::optional<int> from_string<int>(const std::locale&, ustring_view);
87 
88 template<>
89 std::optional<long> from_string<long>(const std::locale&, ustring_view);
90 
91 template<>
92 std::optional<long long> from_string<long long>(const std::locale&, ustring_view);
93 
94 template<>
95 std::optional<unsigned> from_string<unsigned>(const std::locale&, ustring_view);
96 
97 template<>
98 std::optional<unsigned long> from_string<unsigned long>(const std::locale&, ustring_view);
99 
100 template<>
101 std::optional<unsigned long long> from_string<unsigned long long>(const std::locale&, ustring_view);
102 
103 template<>
104 std::optional<float> from_string<float>(const std::locale&, ustring_view);
105 
106 template<>
107 std::optional<double> from_string<double>(const std::locale&, ustring_view);
108 
109 template<typename T>
110 std::optional<T> from_string(string_view);
111 
112 template<>
113 std::optional<int> from_string<int>(string_view);
114 
115 template<>
116 std::optional<long> from_string<long>(string_view);
117 
118 template<>
119 std::optional<long long> from_string<long long>(string_view);
120 
121 template<>
122 std::optional<unsigned> from_string<unsigned>(string_view);
123 
124 template<>
125 std::optional<unsigned long> from_string<unsigned long>(string_view);
126 
127 template<>
128 std::optional<unsigned long long> from_string<unsigned long long>(string_view);
129 
130 template<>
131 std::optional<float> from_string<float>(string_view);
132 
133 template<>
134 std::optional<double> from_string<double>(string_view);
135 
136 template<>
137 std::optional<bool> from_string<bool>(string_view);
138 
139 template<>
140 std::optional<string> from_string<string>(string_view);
141 
142 template<typename T>
143 std::optional<T> from_string(ustring_view);
144 
145 template<>
146 std::optional<int> from_string<int>(ustring_view);
147 
148 template<>
149 std::optional<long> from_string<long>(ustring_view);
150 
151 template<>
152 std::optional<long long> from_string<long long>(ustring_view);
153 
154 template<>
155 std::optional<unsigned> from_string<unsigned>(ustring_view);
156 
157 template<>
158 std::optional<unsigned long> from_string<unsigned long>(ustring_view);
159 
160 template<>
161 std::optional<unsigned long long> from_string<unsigned long long>(ustring_view);
162 
163 template<>
164 std::optional<float> from_string<float>(ustring_view);
165 
166 template<>
167 std::optional<double> from_string<double>(ustring_view);
168 
169 template<>
170 std::optional<bool> from_string<bool>(ustring_view);
171 
172 template<>
173 std::optional<ustring> from_string<ustring>(ustring_view);
174 
175 } // namespace impl
176 
177 template<typename T>
178 [[nodiscard]] std::optional<T> from_string(const std::locale& loc, string_view s) {
179  if constexpr (std::is_enum_v<T>) {
180  return magic_enum::enum_cast<T>(s, magic_enum::case_insensitive);
181  } else {
182  return impl::from_string<T>(loc, s);
183  }
184 }
185 
186 template<typename T>
187 [[nodiscard]] std::optional<T> from_string(const std::locale& loc, ustring_view s) {
188  if constexpr (std::is_enum_v<T>) {
189  return magic_enum::enum_cast<T>(unicode_to_utf8(s), magic_enum::case_insensitive);
190  } else {
191  return impl::from_string<T>(loc, s);
192  }
193 }
194 
195 template<typename T>
196 [[nodiscard]] std::optional<T> from_string(string_view s) {
197  if constexpr (std::is_enum_v<T>) {
198  return magic_enum::enum_cast<T>(s, magic_enum::case_insensitive);
199  } else {
200  return impl::from_string<T>(s);
201  }
202 }
203 
204 template<typename T>
205 [[nodiscard]] std::optional<T> from_string(ustring_view s) {
206  if constexpr (std::is_enum_v<T>) {
207  return magic_enum::enum_cast<T>(unicode_to_utf8(s), magic_enum::case_insensitive);
208  } else {
209  return impl::from_string<T>(s);
210  }
211 }
212 
213 [[nodiscard]] bool is_number(const std::locale& loc, string_view s);
214 [[nodiscard]] bool is_number(const std::locale& loc, ustring_view s);
215 [[nodiscard]] bool is_integer(const std::locale& loc, string_view s);
216 [[nodiscard]] bool is_integer(const std::locale& loc, ustring_view s);
217 
218 [[nodiscard]] bool is_number(string_view s);
219 [[nodiscard]] bool is_number(ustring_view s);
220 [[nodiscard]] bool is_integer(string_view s);
221 [[nodiscard]] bool is_integer(ustring_view s);
222 
223 [[nodiscard]] bool is_number(char s);
224 [[nodiscard]] bool is_number(char32_t s);
225 [[nodiscard]] bool is_integer(char s);
226 [[nodiscard]] bool is_integer(char32_t s);
227 
228 [[nodiscard]] bool is_boolean(string_view s);
229 [[nodiscard]] bool is_boolean(ustring_view s);
230 
231 [[nodiscard]] bool is_whitespace(char c);
232 [[nodiscard]] bool is_whitespace(char32_t c);
233 
234 [[nodiscard]] string to_string(int v);
235 [[nodiscard]] string to_string(long v);
236 [[nodiscard]] string to_string(long long v);
237 [[nodiscard]] string to_string(unsigned v);
238 [[nodiscard]] string to_string(unsigned long v);
239 [[nodiscard]] string to_string(unsigned long long v);
240 [[nodiscard]] string to_string(float v);
241 [[nodiscard]] string to_string(double v);
242 [[nodiscard]] string to_string(bool v);
243 [[nodiscard]] string to_string(bool b);
244 [[nodiscard]] string to_string(const void* p);
245 
246 template<typename T, typename enable = std::enable_if_t<std::is_enum_v<T>>>
247 [[nodiscard]] string to_string(T v) {
248  return string{magic_enum::enum_name(v)};
249 }
250 
251 template<typename T>
252 [[nodiscard]] string to_string(const T* p) {
253  return p != nullptr ? to_string(static_cast<const void*>(p)) : "null";
254 }
255 
256 template<typename T>
257 [[nodiscard]] string to_string(T* p) {
258  return p != nullptr ? to_string(static_cast<void*>(p)) : "null";
259 }
260 
261 [[nodiscard]] string to_string(const utils::variant& value);
262 
263 template<typename... Args>
264 [[nodiscard]] ustring to_ustring(Args&&... args) {
265  return utils::utf8_to_unicode(to_string(std::forward<Args>(args)...));
266 }
267 
268 [[nodiscard]] string to_lower(string str);
269 
270 } // namespace lxgui::utils
271 
275 #endif
std::variant< empty, bool, std::int64_t, std::int32_t, std::int16_t, std::int8_t, std::uint64_t, std::uint32_t, std::uint16_t, std::uint8_t, double, float, std::string > variant
Type-erased value for passing arguments to events.