7#include "algorithm.hpp"
11#include "architecture.hpp"
12#include "concepts.hpp"
13#include "exception.hpp"
14#include "codec/UTF.hpp"
25[[nodiscard]]
constexpr bool is_upper(
char c)
noexcept
27 return c >=
'A' && c <=
'Z';
30[[nodiscard]]
constexpr bool is_lower(
char c)
noexcept
32 return c >=
'a' && c <=
'z';
35[[nodiscard]]
constexpr bool is_alpha(
char c)
noexcept
37 return is_upper(c) || is_lower(c);
40[[nodiscard]]
constexpr bool is_digit(
char c)
noexcept
42 return c >=
'0' && c <=
'9';
45[[nodiscard]]
constexpr bool is_alpha_num(
char c)
noexcept
47 return is_alpha(c) || is_digit(c);
50[[nodiscard]]
constexpr bool is_line_feed(
char c)
noexcept
52 return c ==
'\r' || c ==
'\n' || c ==
'\f' || c ==
'\v';
55[[nodiscard]]
constexpr bool is_white_space(
char c)
noexcept
57 return c ==
' ' || c ==
'\t' || is_line_feed(c);
60[[nodiscard]]
constexpr bool is_number_first(
char c)
noexcept
62 return is_digit(c) || c ==
'+' || c ==
'-';
65[[nodiscard]]
constexpr bool is_name_first(
char c)
noexcept
67 return is_alpha(c) or c ==
'_' or c ==
'$' or (c & 0x80);
70[[nodiscard]]
constexpr bool is_name_next(
char c)
noexcept
72 return is_alpha_num(c) or c ==
'_' or c ==
'$' or (c & 0x80);
75[[nodiscard]]
constexpr bool is_quote(
char c)
noexcept
77 return c ==
'"' || c ==
'\'' || c ==
'`';
80[[nodiscard]]
constexpr bool is_open_bracket(
char c)
noexcept
82 return c ==
'(' || c ==
'{' || c ==
'[';
85[[nodiscard]]
constexpr bool is_close_bracket(
char c)
noexcept
87 return c ==
')' || c ==
'}' || c ==
']';
90[[nodiscard]]
constexpr bool is_operator(
char c)
noexcept
92 return !is_alpha_num(c) && c !=
'_' && !is_white_space(c) && !is_quote(c) && !is_open_bracket(c) && !is_close_bracket(c);
95[[nodiscard]]
constexpr char to_lower(
char c)
noexcept
97 return (c >=
'A' and c <=
'Z') ? (c -
'A') +
'a' : c;
100[[nodiscard]]
constexpr char to_upper(
char c)
noexcept
102 return (c >=
'a' and c <=
'z') ? (c -
'a') +
'A' : c;
105[[nodiscard]]
inline std::string to_lower(std::string_view str)
noexcept
110 for (ttlet c : str) {
117[[nodiscard]]
inline std::string to_upper(std::string_view str)
noexcept
122 for (ttlet c : str) {
131[[nodiscard]]
inline std::string normalize_lf(std::string_view str)
noexcept
136 auto found_cr =
false;
137 for (ttlet c : str) {
141 [[unlikely]] r +=
'\n';
142 if (c !=
'\r' && c !=
'\n') {
146 }
else if (c !=
'\r') {
151 found_cr = c ==
'\r';
163[[nodiscard]]
inline std::string make_identifier(std::string_view str)
noexcept
168 r += is_name_first(str.front()) ? str.front() :
'_';
169 for (ttlet c : str.substr(1)) {
170 r += is_name_next(c) ? c :
'_';
180[[nodiscard]]
inline std::string make_slug(std::string_view str)
noexcept
185 size_t dash_count = 0;
186 for (ttlet c : str) {
187 if (is_alpha_num(c)) {
190 }
else if (dash_count++ == 0) {
204[[nodiscard]]
inline std::string make_title(std::string_view str)
noexcept
210 size_t space_count = 1;
211 size_t letter_count = 0;
212 for (ttlet c : str) {
213 if (is_alpha_num(c)) {
216 }
else if (letter_count++ == 0) {
223 }
else if (space_count++ == 0) {
236[[nodiscard]]
constexpr uint32_t fourcc(
char const txt[5])
noexcept
239 (
static_cast<uint32_t
>(txt[0]) << 24) | (
static_cast<uint32_t
>(txt[1]) << 16) | (
static_cast<uint32_t
>(txt[2]) << 8) |
240 static_cast<uint32_t
>(txt[3]));
243[[nodiscard]]
constexpr uint32_t fourcc(uint8_t
const *txt)
noexcept
246 (
static_cast<uint32_t
>(txt[0]) << 24) | (
static_cast<uint32_t
>(txt[1]) << 16) | (
static_cast<uint32_t
>(txt[2]) << 8) |
247 static_cast<uint32_t
>(txt[3]));
250[[nodiscard]]
inline std::string fourcc_to_string(uint32_t x)
noexcept
253 c_str[0] = narrow_cast<char>((x >> 24) & 0xff);
254 c_str[1] = narrow_cast<char>((x >> 16) & 0xff);
255 c_str[2] = narrow_cast<char>((x >> 8) & 0xff);
256 c_str[3] = narrow_cast<char>(x & 0xff);
262constexpr size_t string_size(sizeable
auto str)
noexcept
264 return std::size(str);
267constexpr size_t string_size(
auto str)
noexcept
272template<
typename FirstNeedle,
typename... Needles>
274string_find_any(std::string_view haystack,
size_t pos, FirstNeedle
const &first_needle, Needles
const &...needles)
noexcept
278 size_t first = haystack.find(first_needle, pos);
279 size_t last = first + string_size(first_needle);
281 if (first == std::string_view::npos) {
282 first = size(haystack);
283 last = size(haystack);
286 if constexpr (
sizeof...(Needles) != 0) {
287 ttlet[other_first, other_last] = string_find_any(haystack, pos, needles...);
288 if (other_first < first) {
294 return {first, last};
297template<
typename StringType,
typename... Needles>
302 std::string_view::size_type current_pos = 0;
304 while (current_pos < std::size(haystack)) {
305 ttlet[needle_first, needle_last] = string_find_any(haystack, current_pos, needles...);
306 r.
push_back(StringType{haystack.substr(current_pos, needle_first - current_pos)});
307 current_pos = needle_last;
313template<
typename... Needles>
316 return _split<std::string>(haystack, needles...);
321 return split(haystack,
' ');
324template<
typename... Needles>
327 return _split<std::string_view>(haystack, needles...);
332 return split_view(haystack,
' ');
335template<
typename CharT>
341 if (list.size() > 1) {
342 size_t final_size = (list.size() - 1) * joiner.
size();
343 for (ttlet &item : list) {
344 final_size += item.size();
350 for (ttlet &item : list) {
359template<
typename CharT>
363 return join(list, std::basic_string_view<CharT>{joiner});
366template<
typename CharT>
369 return join(list, std::basic_string_view<CharT>{joiner});
376 if (list.
size() > 1) {
377 size_t final_size = (list.
size() - 1) * joiner.
size();
378 for (ttlet &item : list) {
379 final_size += item.size();
385 for (ttlet &item : list) {
404 case '\n': line++; [[fallthrough]];
405 case '\r': column = 1;
break;
406 case '\t': column = ((((column - 1) / 8) + 1) * 8) + 1;
break;
410 return {line, column};
416template<
typename T,
size_t N>
417constexpr auto to_array_without_last(T (&rhs)[N])
noexcept
420 for (
size_t i = 0; i != (N - 1); ++i) {
429template<
typename T,
size_t N>
430constexpr auto to_array_without_last(T(&&rhs)[N])
noexcept
433 for (
size_t i = 0; i != (N - 1); ++i) {
439[[nodiscard]]
inline std::string lstrip(std::string_view haystack,
std::string needle =
" \t\r\n\f") noexcept
445[[nodiscard]]
inline std::string rstrip(std::string_view haystack,
std::string needle =
" \t\r\n\f") noexcept
451[[nodiscard]]
inline std::string strip(std::string_view haystack,
std::string needle =
" \t\r\n\f") noexcept
465[[nodiscard]]
inline std::vector<std::string> ZZWSTR_to_string(
wchar_t *first,
wchar_t *last, ssize_t nr_strings = -1)
469 while (first != last) {
470 auto it_zero =
std::find(first, last,
wchar_t{0});
471 if (it_zero == last) {
472 throw parse_error(
"Could not find terminating zero of a string.");
475 auto ws = std::wstring_view{first, narrow_cast<size_t>(it_zero - first)};
487 if (nr_strings != -1 && std::ssize(r) != nr_strings) {
488 throw parse_error(
"Unexpected number of string in list.");
497[[nodiscard]]
inline char *make_cstr(
char const *c_str,
size_t size = -1) noexcept
503 auto r =
new char[size + 1];
511[[nodiscard]]
inline char *make_cstr(
std::string const &s)
noexcept
513 return make_cstr(s.c_str(), s.size());