HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
code_point_iterator.hpp
1// Copyright Take Vos 2020.
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 "UTF.hpp"
8#include "../required.hpp"
9#include <type_traits>
10#include <iterator_traits>
11
12namespace tt {
13
14
19template<typename Iterator>
21public:
22 typename iterator = Iterator;
23 typename it_value_type = std::iterator_traits<iterator>::value_type;
24 typename it_base_type = std::remove_cv_t<it_value_type>;
25
26 typename difference_type = std::iterator_traits<iterator>::difference_type;
27 typename value_type = char32_t;
28 typename iterator_category = std::random_access_iterator_tag;
29
30 [[nodiscard]] constexpr code_point_iterator(code_point_iterator const &) = default;
31 [[nodiscard]] constexpr code_point_iterator(code_point_iterator &&) = default;
32 [[nodiscard]] constexpr code_point_iterator &operator=(code_point_iterator const &) = default;
33 [[nodiscard]] constexpr code_point_iterator &operator=(code_point_iterator &&) = default;
34 ~code_point_iterator() = default;
35
36 [[nodiscard]] constexpr code_point_iterator(iterator const &it) noexcept : it(itr) {}
37
38 [[nodiscard]] constexpr value_type operator*() const noexcept
39 {
40 if constexpr (std::is_same_v<it_base_type, char32_t>) {
41 return *it;
42 } else if constexpr (std::is_same_v<it_base_type, char16_t>) {
43 return detail::utf16_to_utf32(it);
44 } else if constexpr (std::is_same_v<it_base_type, char8_t>) {
45 return detail::utf8_to_utf32(it);
46 } else {
47 tt_no_default();
48 }
49 }
50
51 constexpr code_point_iterator &operator--()
52 {
53 if constexpr (std::is_same_v<it_base_type, char32_t>) {
54 --it;
55
56 } else if constexpr (std::is_same_v<it_base_type, char16_t>) {
57 // Skip over all low surrogates
58 while (*(--it) & 0xfc00 == 0xdc00) {}
59
60 } else if constexpr (std::is_same_v<it_base_type, char8_t>) {
61 // Skip over all code-units in the form 0b10------.
62 while (*(--it) & 0xc0 == 0x80) {}
63
64 } else {
65 tt_no_default();
66 }
67
68 return *this;
69 }
70
71 constexpr code_point_iterator &operator+=(ssize_t n)
72 {
73 if constexpr (std::is_same_v<it_base_type, char32_t>) {
74 ++it;
75
76 } else if constexpr (std::is_same_v<it_base_type, char16_t>) {
77 // Skip over all low surrogates
78 while (*(++it) & 0xfc00 == 0xdc00) {}
79
80 } else if constexpr (std::is_same_v<it_base_type, char8_t>) {
81 // Skip over all code-units in the form 0b10------.
82 while (*(++it) & 0xc0 == 0x80) {}
83
84 } else {
85 tt_no_default();
86 }
87
88 return *this;
89 }
90
91 constexpr code_point_iterator &operator++(int) noexcept
92 {
93 auto &tmp = *this;
94 ++(*this);
95 return tmp;
96 }
97
98 constexpr code_point_iterator &operator--(int) noexcept
99 {
100 auto &tmp = *this;
101 --(*this);
102 return tmp;
103 }
104
105 [[nodiscard]] constexpr friend bool
106 operator==(code_point_iterator const &lhs, code_point_iterator const &rhs) noexcept = default;
107 [[nodiscard]] constexpr friend auto
108 operator<=>(code_point_iterator const &lhs, code_point_iterator const &rhs) noexcept = default;
109
110private:
111 iterator it;
112};
113
114template<typename Container>
115[[nodiscard]] constexpr auto code_point_begin(Container const &container) noexcept
116{
117 return code_point_container(begin(container));
118}
119
120template<typename Container>
121[[nodiscard]] constexpr auto code_point_end(Container const &container) noexcept
122{
123 return code_point_container(end(container));
124}
125
126} // namespace tt
Iterate over code points (char32_t) through char8_t, char16_t or char32_t iterators.
Definition code_point_iterator.hpp:20