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 "../assert.hpp"
8#include "../strings.hpp"
9#include "../check.hpp"
10#include <cctype>
11
12namespace hi::inline v1 {
13
25class iso_639 {
26public:
33 template<std::size_t I>
34 constexpr friend iso_639& set(iso_639& rhs, char c)
35 {
36 hi_parse_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_axiom(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_parse_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
105 [[nodiscard]] constexpr std::size_t size() const noexcept
106 {
107 hilet tmp = _v & 0x7fff;
108 // clang-format off
109 return
110 tmp == 0 ? 0 :
111 tmp <= 0x1f ? 1 :
112 tmp <= 0x3ff ? 2 :
113 3;
114 // clang-format on
115 }
116
119 [[nodiscard]] constexpr bool empty() const noexcept
120 {
121 return _v == 0;
122 }
123
126 constexpr explicit operator bool() const noexcept
127 {
128 return not empty();
129 }
130
133 [[nodiscard]] size_t hash() const noexcept
134 {
135 return std::hash<uint16_t>{}(_v);
136 }
137
140 [[nodiscard]] constexpr std::string code() const noexcept
141 {
142 auto r = std::string{};
143 if (size() >= 2) {
144 r += get<0>(*this);
145 r += get<1>(*this);
146 }
147 if (size() == 3) {
148 r += get<2>(*this);
149 }
150 return r;
151 }
152
155 [[nodiscard]] constexpr friend bool operator==(iso_639 const& lhs, iso_639 const& rhs) noexcept = default;
156
159 [[nodiscard]] constexpr friend auto operator<=>(iso_639 const& lhs, iso_639 const& rhs) noexcept = default;
160
161private:
171 uint16_t _v;
172};
173
174} // namespace hi::inline v1
175
176template<>
177struct std::hash<hi::iso_639> {
178 [[nodiscard]] size_t operator()(hi::iso_639 const& rhs) const noexcept
179 {
180 return rhs.hash();
181 }
182};
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
@ shift
The shift key is being held.
The HikoGUI namespace.
Definition ascii.hpp:19
ISO-639 language code.
Definition iso_639.hpp:25
constexpr std::string code() const noexcept
Get the 2 or 3 letter ISO-639 code.
Definition iso_639.hpp:140
constexpr bool empty() const noexcept
Check if the language is empty.
Definition iso_639.hpp:119
size_t hash() const noexcept
Get the hash value for this language code.
Definition iso_639.hpp:133
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:105
T operator()(T... args)