40 tt_force_inline
Grapheme() noexcept : value(1) {}
48 if (other.has_pointer()) {
49 value = create_pointer(other.get_pointer()->
data(), other.size());
57 if (other.has_pointer()) {
58 value = create_pointer(other.get_pointer()->
data(), other.size());
76 explicit Grapheme(std::u32string_view codePoints)
noexcept;
78 tt_force_inline
explicit Grapheme(
char32_t codePoint) noexcept :
79 Grapheme(std::u32string_view{&codePoint, 1}) {}
81 Grapheme& operator=(std::u32string_view codePoints)
noexcept {
86 Grapheme& operator=(
char32_t codePoint)
noexcept {
93 return {get_pointer()->
data(), size()};
96 auto tmp = value >> 1;
97 for (
size_t i = 0; i < 3; i++, tmp >>= 21) {
98 if (
auto codePoint =
static_cast<char32_t>(tmp & 0x1f'ffff)) {
108 operator bool ()
const noexcept {
112 [[nodiscard]]
size_t hash()
const noexcept {
114 for (
ssize_t i = 0; i != ssize(*
this); ++i) {
120 [[nodiscard]] tt_force_inline
size_t size()
const noexcept {
124 auto tmp = value >> 1;
126 for (i = 0; i < 3; i++, tmp >>= 21) {
127 if ((tmp & 0x1f'ffff) == 0) {
135 [[nodiscard]]
char32_t front()
const noexcept {
143 [[nodiscard]]
char32_t operator[](
size_t i)
const noexcept {
145 tt_assume(i < std::tuple_size_v<long_Grapheme>);
146 return (*get_pointer())[i];
150 return (value >> ((i * 21) + 1)) & 0x1f'ffff;
157 for (
ssize_t i = 0; i != ssize(*
this); ++i) {
170 return tt::to_string(g.NFC());
174 return lhs << to_string(rhs);
178 [[nodiscard]] tt_force_inline
bool has_pointer()
const noexcept {
179 return (value & 1) == 0;
182 [[nodiscard]]
static uint64_t create_pointer(
char32_t const *data,
size_t size)
noexcept {
183 tt_assert(size <= std::tuple_size<long_Grapheme>::value);
186 memcpy(ptr->data(), data, size);
188 auto iptr =
reinterpret_cast<ptrdiff_t
>(ptr);
189 auto uptr =
static_cast<uint64_t
>(iptr << 16) >> 16;
190 return (size << 48) | uptr;
193 [[nodiscard]] tt_force_inline
long_Grapheme *get_pointer()
const noexcept {
194 auto uptr = (value << 16);
195 auto iptr =
static_cast<ptrdiff_t
>(uptr) >> 16;
196 return std::launder(
reinterpret_cast<long_Grapheme *
>(iptr));
199 tt_force_inline
void delete_pointer()
noexcept {
201 delete get_pointer();
205 [[nodiscard]]
friend bool operator<(
Grapheme const& a,
Grapheme const& b)
noexcept {
206 ttlet length =
std::min(ssize(a), ssize(b));
208 for (
ssize_t i = 0; i != length; ++i) {
213 return ssize(a) < ssize(b);
216 [[nodiscard]]
friend bool operator==(
Grapheme const& a,
Grapheme const& b)
noexcept {
217 if (a.value == b.value) {
221 if (ssize(a) != ssize(b)) {
225 for (
ssize_t i = 0; i != ssize(a); ++i) {
233 [[nodiscard]]
friend bool operator==(
Grapheme const &lhs,
char32_t const &rhs)
noexcept {
234 return (ssize(lhs) == 1) && (lhs[0] == rhs);
237 [[nodiscard]]
friend bool operator!=(
Grapheme const &lhs,
char32_t const &rhs)
noexcept {
238 return !(lhs == rhs);
241 [[nodiscard]]
friend bool operator==(
Grapheme const &lhs,
char const &rhs)
noexcept {
242 return lhs ==
static_cast<char32_t>(rhs);
245 [[nodiscard]]
friend bool operator!=(
Grapheme const &lhs,
char const &rhs)
noexcept {
246 return !(lhs == rhs);