HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
iso_639.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 "../utility/utility.hpp"
8#include "../macros.hpp"
9#include <cctype>
10
11hi_export_module(hikogui.i18n.iso_639);
12
13namespace hi::inline v1 {
14
25hi_export class iso_639 {
26public:
33 template<std::size_t I>
34 constexpr friend iso_639& set(iso_639& rhs, char c)
35 {
36 hi_check(
37 c == 0 or (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or (c >= '1' and c <= '5'),
38 "Must be letters or the digits between '1' and '5', or nul");
39
40 // clang-format off
41 uint16_t const x =
42 (c >= 'a' and c <= 'z') ? c - 'a' + 1 :
43 (c >= 'A' and c <= 'Z') ? c - 'A' + 1 :
44 (c >= '1' and c <= '5') ? c - '1' + 27 :
45 0;
46 // clang-format on
47
48 hi_assert(x <= 0x1f);
49 constexpr auto shift = I * 5;
50 rhs._v &= ~(0x1f << shift);
51 rhs._v |= x << shift;
52 return rhs;
53 }
54
61 template<std::size_t I>
62 [[nodiscard]] constexpr friend char get(iso_639 const& rhs) noexcept
63 {
64 constexpr auto shift = I * 5;
65 hilet x = (rhs._v >> shift) & 0x1f;
66 if (x == 0) {
67 return 0;
68 } else if (x <= 26) {
69 return 'a' + narrow_cast<char>(x - 1);
70 } else {
71 return '1' + narrow_cast<char>(x - 27);
72 }
73 }
74
75 constexpr iso_639(iso_639 const&) noexcept = default;
76 constexpr iso_639(iso_639&&) noexcept = default;
77 constexpr iso_639& operator=(iso_639 const&) noexcept = default;
78 constexpr iso_639& operator=(iso_639&&) noexcept = default;
79
82 constexpr iso_639() noexcept : _v(0) {}
83
86 constexpr iso_639(std::string_view str) : _v(0)
87 {
88 try {
89 hi_check(str.size() == 2 or str.size() == 3, "ISO-639 incorrect length.");
90
91 set<0>(*this, str[0]);
92 set<1>(*this, str[1]);
93 if (str.size() == 3) {
94 set<2>(*this, str[2]);
95 }
96 } catch (...) {
97 throw parse_error(std::format("A ISO-639 language code must be 2 or 3 letters in length, got '{}'", str));
98 }
99 }
100
101 constexpr iso_639(intrinsic_t, uint16_t v) noexcept : _v(v) {}
102
103 [[nodiscard]] constexpr uint16_t const& intrinsic() const noexcept
104 {
105 return _v;
106 }
107
108 [[nodiscard]] constexpr uint16_t& intrinsic() noexcept
109 {
110 return _v;
111 }
112
117 [[nodiscard]] constexpr std::size_t size() const noexcept
118 {
119 hilet tmp = _v & 0x7fff;
120 // clang-format off
121 return
122 tmp == 0 ? 0 :
123 tmp <= 0x1f ? 1 :
124 tmp <= 0x3ff ? 2 :
125 3;
126 // clang-format on
127 }
128
131 [[nodiscard]] constexpr bool empty() const noexcept
132 {
133 return _v == 0;
134 }
135
138 constexpr explicit operator bool() const noexcept
139 {
140 return not empty();
141 }
142
145 [[nodiscard]] size_t hash() const noexcept
146 {
147 return std::hash<uint16_t>{}(_v);
148 }
149
152 [[nodiscard]] constexpr std::string code() const noexcept
153 {
154 auto r = std::string{};
155 if (size() >= 2) {
156 r += get<0>(*this);
157 r += get<1>(*this);
158 }
159 if (size() == 3) {
160 r += get<2>(*this);
161 }
162 return r;
163 }
164
165 [[nodiscard]] constexpr friend std::string to_string(iso_639 const &rhs) noexcept
166 {
167 return rhs.code();
168 }
169
172 [[nodiscard]] constexpr friend bool operator==(iso_639 const& lhs, iso_639 const& rhs) noexcept = default;
173
176 [[nodiscard]] constexpr friend auto operator<=>(iso_639 const& lhs, iso_639 const& rhs) noexcept = default;
177
184 [[nodiscard]] constexpr friend bool matches(iso_639 const& lhs, iso_639 const& rhs) noexcept
185 {
186 return lhs.empty() or lhs == rhs;
187 }
188
189private:
199 uint16_t _v;
200};
201
202} // namespace hi::inline v1
203
204hi_export template<>
205struct std::hash<hi::iso_639> {
206 [[nodiscard]] size_t operator()(hi::iso_639 const& rhs) const noexcept
207 {
208 return rhs.hash();
209 }
210};
DOXYGEN BUG.
Definition algorithm.hpp:16
@ shift
The shift key is being held.
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
ISO-639 language code.
Definition iso_639.hpp:25
constexpr friend bool matches(iso_639 const &lhs, iso_639 const &rhs) noexcept
Check if rhs matches with lhs.
Definition iso_639.hpp:184
constexpr std::string code() const noexcept
Get the 2 or 3 letter ISO-639 code.
Definition iso_639.hpp:152
constexpr bool empty() const noexcept
Check if the language is empty.
Definition iso_639.hpp:131
size_t hash() const noexcept
Get the hash value for this language code.
Definition iso_639.hpp:145
constexpr friend char get(iso_639 const &rhs) noexcept
Get the letter at a specific position.
Definition iso_639.hpp:62
constexpr friend iso_639 & set(iso_639 &rhs, char c)
Set the letter at a specific position.
Definition iso_639.hpp:34
constexpr friend auto operator<=>(iso_639 const &lhs, iso_639 const &rhs) noexcept=default
Compare two language codes.
constexpr iso_639(std::string_view str)
Construct a language from the 2 or 3 letter code.
Definition iso_639.hpp:86
constexpr friend bool operator==(iso_639 const &lhs, iso_639 const &rhs) noexcept=default
Compare two language codes.
constexpr std::size_t size() const noexcept
Get the number of character.
Definition iso_639.hpp:117
T operator()(T... args)