HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
gstring.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "grapheme.hpp"
8#include "../utility/module.hpp"
9#include "../strings.hpp"
10#include <vector>
11#include <string>
12
13template<>
14struct std::char_traits<hi::grapheme> {
15 using char_type = hi::grapheme;
16 using int_type = hi::grapheme::value_type;
20 using comparison_category = std::strong_ordering;
21
22 static constexpr void assign(char_type &r, char_type const &a) noexcept
23 {
24 r = a;
25 }
26
27 static constexpr char_type *assign(char_type *p, std::size_t count, char_type a) noexcept
28 {
30 for (std::size_t i = 0; i != count; ++i) {
31 p[i] = a;
32 }
33 return p;
34 }
35
36 [[nodiscard]] static constexpr bool eq(char_type a, char_type b) noexcept
37 {
38 return a == b;
39 }
40
41 [[nodiscard]] static constexpr bool lt(char_type a, char_type b) noexcept
42 {
43 return a < b;
44 }
45
46 static constexpr char_type *move(char_type *dst, char_type const *src, std::size_t count) noexcept
47 {
50
51 if (src >= dst) {
52 for (std::size_t i = 0; i != count; ++i) {
53 dst[i] = src[i];
54 }
55 } else {
56 for (std::size_t i = count; i != 0; --i) {
57 dst[i - 1] = src[i - 1];
58 }
59 }
60 return dst;
61 }
62
63 static constexpr char_type *copy(char_type *dst, char_type const *src, std::size_t count) noexcept
64 {
67
68 for (std::size_t i = 0; i != count; ++i) {
69 dst[i] = src[i];
70 }
71 return dst;
72 }
73
74 static constexpr int compare(char_type const *s1, char_type const *s2, std::size_t count) noexcept
75 {
78
79 for (std::size_t i = 0; i != count; ++i) {
80 if (s1[i] != s2[i]) {
81 return s1[i] < s2[i] ? -1 : 1;
82 }
83 }
84 return 0;
85 }
86
87 static constexpr std::size_t length(char_type const *s) noexcept
88 {
90
91 std::size_t i = 0;
92 while (not s[i].empty()) {
93 ++i;
94 }
95 return i;
96 }
97
98 static constexpr char_type const *find(const char_type *p, std::size_t count, const char_type &ch) noexcept
99 {
101
102 for (std::size_t i = 0; i != count; ++i, ++p) {
103 if (*p == ch) {
104 return p;
105 }
106 }
107 return nullptr;
108 }
109
110 static constexpr char_type to_char_type(int_type c) noexcept
111 {
112 char_type r;
113 r._value = c;
114 return r;
115 }
116
117 static constexpr int_type to_int_type(char_type c) noexcept
118 {
119 return c._value;
120 }
121
122 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
123 {
124 return c1 == c2;
125 }
126
127 static constexpr int_type eof() noexcept
128 {
129 // An empty grapheme has all 21 bits to '1'.
130 return 0x1f'ffff;
131 }
132
133 static constexpr int_type not_eof(int_type e) noexcept
134 {
135 // When e is eof return the replacement character.
136 return e == eof() ? 0xfffd : e;
137 }
138};
139
140namespace hi::inline v1 {
141
142using gstring = std::basic_string<grapheme>;
143using gstring_view = std::basic_string_view<grapheme>;
144
145namespace pmr {
146using gstring = std::pmr::basic_string<grapheme>;
147}
148
155[[nodiscard]] gstring to_gstring(std::u32string_view rhs, char32_t new_line_char = U'\u2029') noexcept;
156
163[[nodiscard]] inline gstring to_gstring(std::string_view rhs, char32_t new_line_char = U'\u2029') noexcept
164{
165 return to_gstring(to_u32string(rhs), new_line_char);
166}
167
174[[nodiscard]] inline gstring to_gstring(std::string const &rhs, char32_t new_line_char = U'\u2029') noexcept
175{
176 return to_gstring(std::string_view{rhs}, new_line_char);
177}
178
179[[nodiscard]] inline std::string to_string(gstring_view rhs) noexcept
180{
181 auto r = std::string{};
182 r.reserve(rhs.size());
183 for (hilet c: rhs) {
184 r += to_string(c);
185 }
186 return r;
187}
188
189[[nodiscard]] inline std::string to_string(gstring const &rhs) noexcept
190{
191 return to_string(gstring_view{rhs});
192}
193
194} // namespace hi::inline v1
195
196template<>
197struct std::hash<hi::gstring> {
198 [[nodiscard]] std::size_t operator()(hi::gstring const &rhs) noexcept
199 {
200 auto r = std::hash<std::size_t>{}(rhs.size());
201 for (hilet c: rhs) {
202 r = hi::hash_mix_two(r, std::hash<hi::grapheme>{}(c));
203 }
204 return r;
205 }
206};
207
208template<>
209struct std::hash<hi::pmr::gstring> {
210 [[nodiscard]] std::size_t operator()(hi::pmr::gstring const &rhs) noexcept
211 {
212 auto r = std::hash<std::size_t>{}(rhs.size());
213 for (hilet c : rhs) {
214 r = hi::hash_mix_two(r, std::hash<hi::grapheme>{}(c));
215 }
216 return r;
217 }
218};
219
#define hi_axiom_not_null(expression,...)
Assert if an expression is not nullptr.
Definition assert.hpp:257
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
constexpr std::string to_string(std::u32string_view rhs) noexcept
Conversion from UTF-32 to UTF-8.
Definition to_string.hpp:215
constexpr std::u32string to_u32string(std::u32string_view rhs) noexcept
Identity conversion from UTF-32 to UTF-32.
Definition to_string.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
gstring to_gstring(std::u32string_view rhs, char32_t new_line_char=U'\u2029') noexcept
Convert a UTF-32 string to a grapheme-string.
geometry/margins.hpp
Definition cache.hpp:11
T assign(T... args)
T eq(T... args)
T compare(T... args)
T copy(T... args)
T count(T... args)
T eof(T... args)
T eq_int_type(T... args)
T find(T... args)
T length(T... args)
T move(T... args)
T not_eof(T... args)
T operator()(T... args)
T reserve(T... args)
T to_char_type(T... args)
T to_int_type(T... args)