OpenTTD Source 15.0-beta2
utf8.hpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
12#ifndef UTF8_HPP
13#define UTF8_HPP
14
15#include <iterator>
16#include "../string_func.h"
17
18[[nodiscard]] std::pair<char[4], size_t> EncodeUtf8(char32_t c);
19[[nodiscard]] std::pair<size_t, char32_t> DecodeUtf8(std::string_view buf);
20
24class Utf8View {
25 std::string_view src;
26public:
27 Utf8View() = default;
28 Utf8View(std::string_view src) : src(src) {}
29
37 class iterator {
38 std::string_view src;
39 size_t position = 0;
40 public:
41 using value_type = char32_t;
42 using difference_type = std::ptrdiff_t;
43 using iterator_category = std::bidirectional_iterator_tag;
44 using pointer = void;
45 using reference = void;
46
47 iterator() = default;
48 iterator(std::string_view src, size_t position) : src(src), position(position) {}
49
50 size_t GetByteOffset() const
51 {
52 return this->position;
53 }
54
55 bool operator==(const iterator &rhs) const
56 {
57 assert(this->src.data() == rhs.src.data());
58 return this->position == rhs.position;
59 }
60
61 std::strong_ordering operator<=>(const iterator &rhs) const
62 {
63 assert(this->src.data() == rhs.src.data());
64 return this->position <=> rhs.position;
65 }
66
67 char32_t operator*() const
68 {
69 assert(this->position < this->src.size());
70 auto [len, c] = DecodeUtf8(this->src.substr(this->position));
71 return len > 0 ? c : '?';
72 }
73
74 iterator& operator++()
75 {
76 auto size = this->src.size();
77 assert(this->position < size);
78 do {
79 ++this->position;
80 } while (this->position < size && IsUtf8Part(this->src[this->position]));
81 return *this;
82 }
83
84 iterator operator++(int)
85 {
86 iterator result = *this;
87 ++*this;
88 return result;
89 }
90
91 iterator& operator--()
92 {
93 assert(this->position > 0);
94 do {
95 --this->position;
96 } while (this->position > 0 && IsUtf8Part(this->src[this->position]));
97 return *this;
98 }
99
100 iterator operator--(int)
101 {
102 iterator result = *this;
103 --*this;
104 return result;
105 }
106 };
107
108 iterator begin() const
109 {
110 return iterator(this->src, 0);
111 }
112
113 iterator end() const
114 {
115 return iterator(this->src, this->src.size());
116 }
117
118 iterator GetIterAtByte(size_t offset) const;
119};
120
121#endif /* UTF8_HPP */
Bidirectional input iterator over codepoints.
Definition utf8.hpp:37
Constant span of UTF-8 encoded data.
Definition utf8.hpp:24
iterator GetIterAtByte(size_t offset) const
Create iterator pointing at codepoint, which occupies the byte position "offset".
Definition utf8.cpp:83
std::pair< size_t, char32_t > DecodeUtf8(std::string_view buf)
Decode a character from UTF-8.
Definition utf8.cpp:48
std::pair< char[4], size_t > EncodeUtf8(char32_t c)
Encode a character to UTF-8.
Definition utf8.cpp:21