7#include "../utility/utility.hpp"
8#include "../char_maps/char_maps.hpp"
9#include "algorithm_misc.hpp"
10#include "../macros.hpp"
20hi_export_module(hikogui.algorithm.strings);
26hi_warning_ignore_msvc(26409);
28hi_export
namespace hi::inline
v1 {
30[[nodiscard]]
constexpr bool is_upper(
char c)
noexcept
32 return c >=
'A' && c <=
'Z';
35[[nodiscard]]
constexpr bool is_lower(
char c)
noexcept
37 return c >=
'a' && c <=
'z';
40[[nodiscard]]
constexpr bool is_alpha(
char c)
noexcept
42 return is_upper(c) || is_lower(c);
45[[nodiscard]]
constexpr bool is_digit(
char c)
noexcept
47 return c >=
'0' && c <=
'9';
50[[nodiscard]]
constexpr bool is_alpha_num(
char c)
noexcept
52 return is_alpha(c) || is_digit(c);
55[[nodiscard]]
constexpr bool is_line_feed(
char c)
noexcept
57 return c ==
'\r' || c ==
'\n' || c ==
'\f' || c ==
'\v';
60[[nodiscard]]
constexpr bool is_white_space(
char c)
noexcept
62 return c ==
' ' || c ==
'\t' || is_line_feed(c);
65[[nodiscard]]
constexpr bool is_number_first(
char c)
noexcept
67 return is_digit(c) || c ==
'+' || c ==
'-';
70[[nodiscard]]
constexpr bool is_name_first(
char c)
noexcept
72 return is_alpha(c) or c ==
'_' or c ==
'$' or (c & 0x80);
75[[nodiscard]]
constexpr bool is_name_next(
char c)
noexcept
77 return is_alpha_num(c) or c ==
'_' or c ==
'$' or (c & 0x80);
80[[nodiscard]]
constexpr bool is_quote(
char c)
noexcept
82 return c ==
'"' || c ==
'\'' || c ==
'`';
85[[nodiscard]]
constexpr bool is_open_bracket(
char c)
noexcept
87 return c ==
'(' || c ==
'{' || c ==
'[';
90[[nodiscard]]
constexpr bool is_close_bracket(
char c)
noexcept
92 return c ==
')' || c ==
'}' || c ==
']';
95[[nodiscard]]
constexpr bool is_operator(
char c)
noexcept
97 return !is_alpha_num(c) && c !=
'_' && !is_white_space(c) && !is_quote(c) && !is_open_bracket(c) && !is_close_bracket(c);
100[[nodiscard]]
constexpr bool is_digit(std::string_view str)
noexcept
102 for (
auto const c : str) {
103 if (not is_digit(c)) {
110[[nodiscard]]
constexpr bool is_alpha(std::string_view str)
noexcept
112 for (
auto const c : str) {
113 if (not is_alpha(c)) {
120[[nodiscard]]
constexpr char to_lower(
char c)
noexcept
122 return (c >=
'A' and c <=
'Z') ? (c -
'A') +
'a' : c;
125[[nodiscard]]
constexpr char to_upper(
char c)
noexcept
127 return (c >=
'a' and c <=
'z') ? (c -
'a') +
'A' : c;
130[[nodiscard]]
inline std::string to_lower(std::string_view str)
noexcept
135 for (
auto const c : str) {
142[[nodiscard]]
inline std::string to_upper(std::string_view str)
noexcept
147 for (
auto const c : str) {
168 }
else if (c ==
' ') {
184[[nodiscard]]
constexpr fixed_string<N>
to_title(fixed_string<N>
const &rhs)
noexcept
193 }
else if (c ==
' ') {
210 auto found_cr =
false;
211 for (
auto const c : str) {
215 [[unlikely]] r +=
'\n';
216 if (c !=
'\r' && c !=
'\n') {
220 }
else if (c !=
'\r') {
225 found_cr = c ==
'\r';
242 r += is_name_first(str.front()) ? str.front() :
'_';
243 for (
auto const c : str.substr(1)) {
244 r += is_name_next(c) ? c :
'_';
260 for (
auto const c : str) {
261 if (is_alpha_num(c)) {
264 }
else if (dash_count++ == 0) {
272[[nodiscard]]
constexpr bool is_slug(std::string_view str)
noexcept
274 for (
auto const c : str) {
275 if (not (is_alpha_num(c) or c ==
'-')) {
296 for (
auto const c : str) {
297 if (is_alpha_num(c)) {
300 }
else if (letter_count++ == 0) {
307 }
else if (space_count++ == 0) {
320template<
typename T,
size_t N>
321[[nodiscard]]
constexpr uint32_t fourcc(T
const (&txt)[N])
noexcept requires(
sizeof(T) == 1 and (N == 4 or N == 5))
324 r |= truncate<uint8_t>(txt[0]);
326 r |= truncate<uint8_t>(txt[1]);
328 r |= truncate<uint8_t>(txt[2]);
330 r |= truncate<uint8_t>(txt[3]);
332 if constexpr (N == 5) {
333 hi_axiom(txt[4] == 0);
338[[nodiscard]]
constexpr uint32_t fourcc_from_cstr(
char const *txt)
noexcept
340 hi_assert_not_null(txt);
342 (char_cast<uint32_t>(txt[0]) << 24) |
343 (char_cast<uint32_t>(txt[1]) << 16) |
344 (char_cast<uint32_t>(txt[2]) << 8) |
345 char_cast<uint32_t>(txt[3]);
348[[nodiscard]]
inline std::string fourcc_to_string(uint32_t x)
noexcept
351 r += truncate<char>((x >> 24) & 0xff);
352 r += truncate<char>((x >> 16) & 0xff);
353 r += truncate<char>((x >> 8) & 0xff);
354 r += truncate<char>(x & 0xff);
358constexpr std::size_t string_size(sizeable
auto str)
noexcept
363constexpr std::size_t string_size(
auto str)
noexcept
368template<
typename FirstNeedle,
typename... Needles>
370string_find_any(std::string_view haystack,
std::size_t pos, FirstNeedle
const& first_needle, Needles
const&...needles)
noexcept
374 std::size_t first = haystack.find(first_needle, pos);
375 std::size_t last = first + string_size(first_needle);
377 if (first == std::string_view::npos) {
378 first = size(haystack);
379 last = size(haystack);
382 if constexpr (
sizeof...(Needles) != 0) {
383 auto const[other_first, other_last] = string_find_any(haystack, pos, needles...);
384 if (other_first < first) {
390 return {first, last};
393template<
typename StringType,
typename... Needles>
398 std::string_view::size_type current_pos = 0;
400 while (current_pos < size(haystack)) {
401 auto const[needle_first, needle_last] = string_find_any(haystack, current_pos, needles...);
402 r.
push_back(StringType{haystack.substr(current_pos, needle_first - current_pos)});
403 current_pos = needle_last;
409template<
typename... Needles>
412 return _split<std::string>(haystack, needles...);
417 return split(haystack,
' ');
420template<
typename... Needles>
423 return _split<std::string_view>(haystack, needles...);
428 return split_view(haystack,
' ');
431template<
typename CharT>
437 if (list.size() > 1) {
438 std::size_t final_size = (list.size() - 1) * joiner.size();
439 for (
auto const& item : list) {
440 final_size += item.size();
446 for (
auto const& item : list) {
455template<
typename CharT>
459 return join(list, std::basic_string_view<CharT>{joiner});
462template<
typename CharT>
465 return join(list, std::basic_string_view<CharT>{joiner});
472 if (list.
size() > 1) {
474 for (
auto const item : list) {
475 final_size += item.size();
481 for (
auto const item : list) {
498 for (; begin != end; begin++) {
507 column = ((((column - 1) / 8) + 1) * 8) + 1;
513 return {line, column};
519template<
typename T, std::
size_t N>
532template<
typename T, std::
size_t N>
542[[nodiscard]]
inline std::string lstrip(std::string_view haystack,
std::string needle =
" \t\r\n\f") noexcept
544 auto first = front_strip(begin(haystack), end(haystack), begin(needle), end(needle));
548[[nodiscard]]
inline std::string rstrip(std::string_view haystack,
std::string needle =
" \t\r\n\f") noexcept
554[[nodiscard]]
inline std::string strip(std::string_view haystack,
std::string needle =
" \t\r\n\f") noexcept
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
constexpr std::string make_slug(std::string_view str) noexcept
Create a slug from a string.
Definition strings.hpp:254
constexpr std::string to_title(std::string_view rhs) noexcept
Convert the current string to using title case.
Definition strings.hpp:159
constexpr auto to_array_without_last(T(&rhs)[N]) noexcept
Create an std::array from a one dimensional array, without the last element.
Definition strings.hpp:520
DataIt front_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last) noexcept
Strip data from the front side.
Definition algorithm_misc.hpp:327
std::string make_title(std::string_view str) noexcept
Create a title from a string.
Definition strings.hpp:288
std::string make_identifier(std::string_view str) noexcept
Encode a string to be usable as an id.
Definition strings.hpp:237
DataIt back_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last) noexcept
Strip data from the back side.
Definition algorithm_misc.hpp:348
std::string normalize_lf(std::string_view str) noexcept
Normalize string to use only line-feeds.
Definition strings.hpp:205
std::pair< int, int > count_line_and_columns(It begin, It const end)
Definition strings.hpp:493