lxgui
Loading...
Searching...
No Matches
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/magic_enum.hpp>
13#include <optional>
14#include <string>
15#include <string_view>
16#include <vector>
17
20namespace lxgui::utils {
21
22using string = std::string;
23using string_view = std::string_view;
24using ustring = std::u32string;
25using 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
30void 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
53namespace impl {
54
55template<typename T>
56std::optional<T> from_string(const std::locale&, string_view);
57
58template<>
59std::optional<int> from_string<int>(const std::locale&, string_view);
60
61template<>
62std::optional<long> from_string<long>(const std::locale&, string_view);
63
64template<>
65std::optional<long long> from_string<long long>(const std::locale&, string_view);
66
67template<>
68std::optional<unsigned> from_string<unsigned>(const std::locale&, string_view);
69
70template<>
71std::optional<unsigned long> from_string<unsigned long>(const std::locale&, string_view);
72
73template<>
74std::optional<unsigned long long> from_string<unsigned long long>(const std::locale&, string_view);
75
76template<>
77std::optional<float> from_string<float>(const std::locale&, string_view);
78
79template<>
80std::optional<double> from_string<double>(const std::locale&, string_view);
81
82template<typename T>
83std::optional<T> from_string(const std::locale&, ustring_view);
84
85template<>
86std::optional<int> from_string<int>(const std::locale&, ustring_view);
87
88template<>
89std::optional<long> from_string<long>(const std::locale&, ustring_view);
90
91template<>
92std::optional<long long> from_string<long long>(const std::locale&, ustring_view);
93
94template<>
95std::optional<unsigned> from_string<unsigned>(const std::locale&, ustring_view);
96
97template<>
98std::optional<unsigned long> from_string<unsigned long>(const std::locale&, ustring_view);
99
100template<>
101std::optional<unsigned long long> from_string<unsigned long long>(const std::locale&, ustring_view);
102
103template<>
104std::optional<float> from_string<float>(const std::locale&, ustring_view);
105
106template<>
107std::optional<double> from_string<double>(const std::locale&, ustring_view);
108
109template<typename T>
110std::optional<T> from_string(string_view);
111
112template<>
113std::optional<int> from_string<int>(string_view);
114
115template<>
116std::optional<long> from_string<long>(string_view);
117
118template<>
119std::optional<long long> from_string<long long>(string_view);
120
121template<>
122std::optional<unsigned> from_string<unsigned>(string_view);
123
124template<>
125std::optional<unsigned long> from_string<unsigned long>(string_view);
126
127template<>
128std::optional<unsigned long long> from_string<unsigned long long>(string_view);
129
130template<>
131std::optional<float> from_string<float>(string_view);
132
133template<>
134std::optional<double> from_string<double>(string_view);
135
136template<>
137std::optional<bool> from_string<bool>(string_view);
138
139template<>
140std::optional<string> from_string<string>(string_view);
141
142template<typename T>
143std::optional<T> from_string(ustring_view);
144
145template<>
146std::optional<int> from_string<int>(ustring_view);
147
148template<>
149std::optional<long> from_string<long>(ustring_view);
150
151template<>
152std::optional<long long> from_string<long long>(ustring_view);
153
154template<>
155std::optional<unsigned> from_string<unsigned>(ustring_view);
156
157template<>
158std::optional<unsigned long> from_string<unsigned long>(ustring_view);
159
160template<>
161std::optional<unsigned long long> from_string<unsigned long long>(ustring_view);
162
163template<>
164std::optional<float> from_string<float>(ustring_view);
165
166template<>
167std::optional<double> from_string<double>(ustring_view);
168
169template<>
170std::optional<bool> from_string<bool>(ustring_view);
171
172template<>
173std::optional<ustring> from_string<ustring>(ustring_view);
174
175} // namespace impl
176
177template<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
186template<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
195template<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
204template<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
246template<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
251template<typename T>
252[[nodiscard]] string to_string(const T* p) {
253 return p != nullptr ? to_string(static_cast<const void*>(p)) : "null";
254}
255
256template<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
263template<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.