7#include "algorithm.hpp"
11#include "os_detect.hpp"
12#include "concepts.hpp"
13#include "exception.hpp"
14#include "codec/UTF.hpp"
24[[nodiscard]]
constexpr bool is_upper(
char c)
noexcept
26 return c >=
'A' && c <=
'Z';
29[[nodiscard]]
constexpr bool is_lower(
char c)
noexcept
31 return c >=
'a' && c <=
'z';
34[[nodiscard]]
constexpr bool is_alpha(
char c)
noexcept
36 return is_upper(c) || is_lower(c);
39[[nodiscard]]
constexpr bool is_digit(
char c)
noexcept
41 return c >=
'0' && c <=
'9';
44[[nodiscard]]
constexpr bool is_alpha_num(
char c)
noexcept
46 return is_alpha(c) || is_digit(c);
49[[nodiscard]]
constexpr bool is_line_feed(
char c)
noexcept
51 return c ==
'\r' || c ==
'\n' || c ==
'\f' || c ==
'\v';
54[[nodiscard]]
constexpr bool is_white_space(
char c)
noexcept
56 return c ==
' ' || c ==
'\t' || is_line_feed(c);
59[[nodiscard]]
constexpr bool is_number_first(
char c)
noexcept
61 return is_digit(c) || c ==
'+' || c ==
'-';
64[[nodiscard]]
constexpr bool is_name_first(
char c)
noexcept
66 return is_alpha(c) || c ==
'_' || c ==
'$';
69[[nodiscard]]
constexpr bool is_name_next(
char c)
noexcept
71 return is_alpha_num(c) || c ==
'_' || c ==
'$';
74[[nodiscard]]
constexpr bool is_quote(
char c)
noexcept
76 return c ==
'"' || c ==
'\'' || c ==
'`';
79[[nodiscard]]
constexpr bool is_open_bracket(
char c)
noexcept
81 return c ==
'(' || c ==
'{' || c ==
'[';
84[[nodiscard]]
constexpr bool is_close_bracket(
char c)
noexcept
86 return c ==
')' || c ==
'}' || c ==
']';
89[[nodiscard]]
constexpr bool is_operator(
char c)
noexcept
91 return !is_alpha_num(c) && c !=
'_' && !is_white_space(c) && !is_quote(c) && !is_open_bracket(c) && !is_close_bracket(c);
94[[nodiscard]]
inline std::string to_lower(std::string_view str)
noexcept
100 r += (c >=
'A' && c <=
'Z') ? (c -
'A') +
'a' : c;
106[[nodiscard]]
inline std::string to_upper(std::string_view str)
noexcept
111 for (ttlet c : str) {
112 r += (c >=
'a' && c <=
'z') ? (c -
'a') +
'A' : c;
120[[nodiscard]]
inline std::string normalize_lf(std::string_view str)
noexcept
125 auto found_cr =
false;
126 for (ttlet c : str) {
130 [[unlikely]] r +=
'\n';
131 if (c !=
'\r' && c !=
'\n') {
135 }
else if (c !=
'\r') {
140 found_cr = c ==
'\r';
152[[nodiscard]]
inline std::string id_encode(std::string_view str)
noexcept
157 r += is_name_first(str.front()) ? str.front() :
'_';
158 for (ttlet c : str.substr(1)) {
159 r += is_name_next(c) ? c :
'_';
165[[nodiscard]]
constexpr uint32_t fourcc(
char const txt[5])
noexcept
168 (
static_cast<uint32_t
>(txt[0]) << 24) | (
static_cast<uint32_t
>(txt[1]) << 16) | (
static_cast<uint32_t
>(txt[2]) << 8) |
169 static_cast<uint32_t
>(txt[3]));
172[[nodiscard]]
constexpr uint32_t fourcc(uint8_t
const *txt)
noexcept
175 (
static_cast<uint32_t
>(txt[0]) << 24) | (
static_cast<uint32_t
>(txt[1]) << 16) | (
static_cast<uint32_t
>(txt[2]) << 8) |
176 static_cast<uint32_t
>(txt[3]));
179[[nodiscard]]
inline std::string fourcc_to_string(uint32_t x)
noexcept
182 c_str[0] = narrow_cast<char>((x >> 24) & 0xff);
183 c_str[1] = narrow_cast<char>((x >> 16) & 0xff);
184 c_str[2] = narrow_cast<char>((x >> 8) & 0xff);
185 c_str[3] = narrow_cast<char>(x & 0xff);
191constexpr size_t string_size(sizeable
auto str)
noexcept
193 return std::size(str);
196constexpr size_t string_size(
auto str)
noexcept
201template<
typename FirstNeedle,
typename... Needles>
203 string_find_any(std::string_view haystack,
size_t pos, FirstNeedle
const &first_needle, Needles
const &...needles)
noexcept
207 size_t first = haystack.find(first_needle, pos);
208 size_t last = first + string_size(first_needle);
210 if (first == std::string_view::npos) {
211 first = size(haystack);
212 last = size(haystack);
215 if constexpr (
sizeof...(Needles) != 0) {
216 ttlet [other_first, other_last] = string_find_any(haystack, pos, needles...);
217 if (other_first < first) {
223 return {first, last};
226template<
typename StringType,
typename... Needles>
231 std::string_view::size_type current_pos = 0;
233 while (current_pos < std::size(haystack)) {
234 ttlet [needle_first, needle_last] = string_find_any(haystack, current_pos, needles...);
235 r.
push_back(StringType{haystack.substr(current_pos, needle_first - current_pos)});
236 current_pos = needle_last;
242template<
typename... Needles>
245 return _split<std::string>(haystack, needles...);
250 return split(haystack,
' ');
253template<
typename... Needles>
256 return _split<std::string_view>(haystack, needles...);
261 return split_view(haystack,
' ');
264template<
typename CharT>
270 if (list.size() > 1) {
271 size_t final_size = (list.size() - 1) * joiner.
size();
272 for (ttlet &item : list) {
273 final_size += item.size();
279 for (ttlet &item : list) {
288template<
typename CharT>
292 return join(list, std::basic_string_view<CharT>{joiner});
295template<
typename CharT>
298 return join(list, std::basic_string_view<CharT>{joiner});
305 if (list.
size() > 1) {
306 size_t final_size = (list.
size() - 1) * joiner.
size();
307 for (ttlet &item : list) {
308 final_size += item.size();
314 for (ttlet &item : list) {
333 case '\n': line++; [[fallthrough]];
334 case '\r': column = 1;
break;
335 case '\t': column = ((((column - 1) / 8) + 1) * 8) + 1;
break;
339 return {line, column};
345template<
typename T,
size_t N>
346constexpr auto to_array_without_last(T (&rhs)[N])
noexcept
349 for (
size_t i = 0; i != (N - 1); ++i) {
358template<
typename T,
size_t N>
359constexpr auto to_array_without_last(T(&&rhs)[N])
noexcept
362 for (
size_t i = 0; i != (N - 1); ++i) {
368[[nodiscard]]
inline std::string lstrip(std::string_view haystack,
std::string needle =
" \t\r\n\f") noexcept
374[[nodiscard]]
inline std::string rstrip(std::string_view haystack,
std::string needle =
" \t\r\n\f") noexcept
380[[nodiscard]]
inline std::string strip(std::string_view haystack,
std::string needle =
" \t\r\n\f") noexcept
398 while (first != last) {
399 auto it_zero =
std::find(first, last,
wchar_t{0});
400 if (it_zero == last) {
401 throw parse_error(
"Could not find terminating zero of a string.");
404 auto ws = std::wstring_view{first, narrow_cast<size_t>(it_zero - first)};
416 if (nr_strings != -1 && std::ssize(r) != nr_strings) {
417 throw parse_error(
"Unexpected number of string in list.");
426[[nodiscard]]
inline char *make_cstr(
char const *c_str,
size_t size = -1) noexcept
432 auto r =
new char [size + 1];
440[[nodiscard]]
inline char *make_cstr(
std::string const &s)
noexcept
442 return make_cstr(s.c_str(), s.size());