HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
gstring.hpp
1// Copyright Take Vos 2019-2021.
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 "../required.hpp"
9#include "../strings.hpp"
10#include "../hash.hpp"
11#include <vector>
12#include <string>
13
14template<>
15struct std::char_traits<hi::grapheme> {
16 using char_type = hi::grapheme;
17 using int_type = hi::grapheme::value_type;
21 using comparison_category = std::strong_ordering;
22
23 static constexpr void assign(char_type &r, char_type const &a) noexcept
24 {
25 r = a;
26 }
27
28 static constexpr char_type *assign(char_type *p, std::size_t count, char_type a) noexcept
29 {
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 {
48 if (src >= dst) {
49 for (std::size_t i = 0; i != count; ++i) {
50 dst[i] = src[i];
51 }
52 } else {
53 for (std::size_t i = count; i != 0; --i) {
54 dst[i - 1] = src[i - 1];
55 }
56 }
57 return dst;
58 }
59
60 static constexpr char_type *copy(char_type *dst, char_type const *src, std::size_t count) noexcept
61 {
62 for (std::size_t i = 0; i != count; ++i) {
63 dst[i] = src[i];
64 }
65 return dst;
66 }
67
68 static constexpr int compare(char_type const *s1, char_type const *s2, std::size_t count) noexcept
69 {
70 for (std::size_t i = 0; i != count; ++i) {
71 if (s1[i] != s2[i]) {
72 return s1[i] < s2[i] ? -1 : 1;
73 }
74 }
75 return 0;
76 }
77
78 static constexpr std::size_t length(char_type const *s) noexcept
79 {
80 std::size_t i = 0;
81 while (not s[i].empty()) {
82 ++i;
83 }
84 return i;
85 }
86
87 static constexpr char_type const *find(const char_type *p, std::size_t count, const char_type &ch) noexcept
88 {
89 for (std::size_t i = 0; i != count; ++i, ++p) {
90 if (*p == ch) {
91 return p;
92 }
93 }
94 return nullptr;
95 }
96
97 static constexpr char_type to_char_type(int_type c) noexcept
98 {
99 char_type r;
100 r._value = c;
101 return r;
102 }
103
104 static constexpr int_type to_int_type(char_type c) noexcept
105 {
106 return c._value;
107 }
108
109 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
110 {
111 return c1 == c2;
112 }
113
114 static constexpr int_type eof() noexcept
115 {
116 // An empty grapheme has all 21 bits to '1'.
117 return 0x1f'ffff;
118 }
119
120 static constexpr int_type not_eof(int_type e) noexcept
121 {
122 // When e is eof return the replacement character.
123 return e == eof() ? 0xfffd : e;
124 }
125};
126
127namespace hi::inline v1 {
128
129using gstring = std::basic_string<grapheme>;
130using gstring_view = std::basic_string_view<grapheme>;
131
132namespace pmr {
133using gstring = std::pmr::basic_string<grapheme>;
134}
135
142[[nodiscard]] gstring to_gstring(std::u32string_view rhs, char32_t new_line_char = U'\u2029') noexcept;
143
150[[nodiscard]] inline gstring to_gstring(std::string_view rhs, char32_t new_line_char = U'\u2029') noexcept
151{
152 return to_gstring(to_u32string(rhs), new_line_char);
153}
154
155[[nodiscard]] inline std::string to_string(gstring_view rhs) noexcept
156{
157 auto r = std::string{};
158 r.reserve(rhs.size());
159 for (hilet c: rhs) {
160 r += to_string(c);
161 }
162 return r;
163}
164
165[[nodiscard]] inline std::string to_string(gstring const &rhs) noexcept
166{
167 return to_string(gstring_view{rhs});
168}
169
170} // namespace hi::inline v1
171
172template<>
173struct std::hash<hi::gstring> {
174 [[nodiscard]] std::size_t operator()(hi::gstring const &rhs) noexcept
175 {
176 auto r = std::hash<std::size_t>{}(rhs.size());
177 for (hilet c: rhs) {
178 r = hi::hash_mix_two(r, std::hash<hi::grapheme>{}(c));
179 }
180 return r;
181 }
182};
183
184template<>
185struct std::hash<hi::pmr::gstring> {
186 [[nodiscard]] std::size_t operator()(hi::pmr::gstring const &rhs) noexcept
187 {
188 auto r = std::hash<std::size_t>{}(rhs.size());
189 for (hilet c : rhs) {
190 r = hi::hash_mix_two(r, std::hash<hi::grapheme>{}(c));
191 }
192 return r;
193 }
194};
195
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
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)
Definition datum.hpp:2458
T reserve(T... args)
T to_char_type(T... args)
T to_int_type(T... args)
T to_string(T... args)