HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
character_attributes.hpp
1
2#pragma once
3
4#include "../i18n/module.hpp"
5#include "text_phrasing.hpp"
6
7namespace hi { inline namespace v1 {
8
9template<typename Context>
10concept character_attribute = std::same_as<Context, iso_639> or std::same_as<Context, iso_3166> or
11 std::same_as<Context, iso_15924> or std::same_as<Context, language_tag> or std::same_as<Context, text_phrasing>;
12
14public:
15 using value_type = uint64_t;
16
17 constexpr character_attributes() noexcept = default;
18 constexpr character_attributes(character_attributes const&) noexcept = default;
19 constexpr character_attributes(character_attributes&&) noexcept = default;
20 constexpr character_attributes& operator=(character_attributes const&) noexcept = default;
21 constexpr character_attributes& operator=(character_attributes&&) noexcept = default;
22 [[nodiscard]] constexpr friend bool operator==(character_attributes const&, character_attributes const&) noexcept = default;
23
24 constexpr character_attributes(intrinsic_t, value_type value) noexcept : _value(value)
25 {
26 // language 15 bits
27 // script 10 bits
28 // region 10 bits
29 // phrasing 4 bits
30 // --
31 // total 39 bits.
32 hi_axiom(_value < (value_type{1} << 39));
33 }
34
35 [[nodiscard]] constexpr value_type const& intrinsic() const
36 {
37 return _value;
38 }
39
40 [[nodiscard]] constexpr value_type& intrinsic()
41 {
42 return _value;
43 }
44
45 [[nodiscard]] constexpr hi::text_phrasing phrasing() const noexcept
46 {
47 return static_cast<hi::text_phrasing>((_value >> _phrasing_shift) & _phrasing_mask);
48 }
49
50 constexpr character_attributes& set_phrasing(hi::text_phrasing phrasing) noexcept
51 {
52 hilet phrasing_value = wide_cast<value_type>(to_underlying(phrasing));
53 hi_axiom(phrasing_value <= _phrasing_mask);
54 _value &= ~(_phrasing_mask << _phrasing_shift);
55 _value |= phrasing_value << _phrasing_shift;
56 return *this;
57 }
58
59 [[nodiscard]] constexpr iso_639 language() const noexcept
60 {
61 return iso_639{intrinsic_t{}, (_value >> _language_shift) & _language_mask};
62 }
63
64 constexpr character_attributes& set_language(iso_639 language) noexcept
65 {
66 hilet language_value = wide_cast<value_type>(language.intrinsic());
67 hi_axiom(language_value <= _language_mask);
68 _value &= ~(_language_mask << _language_shift);
69 _value |= language_value << _language_shift;
70 return *this;
71 }
72
73 [[nodiscard]] constexpr iso_15924 script() const noexcept
74 {
75 return iso_15924{intrinsic_t{}, (_value >> _script_shift) & _script_mask};
76 }
77
78 constexpr character_attributes& set_script(iso_15924 script) noexcept
79 {
80 hilet script_value = wide_cast<value_type>(script.intrinsic());
81 hi_axiom(script_value <= _script_mask);
82 _value &= ~(_script_mask << _script_shift);
83 _value |= script_value << _script_shift;
84 return *this;
85 }
86
87 [[nodiscard]] constexpr iso_3166 region() const noexcept
88 {
89 return iso_3166{intrinsic_t{}, (_value >> _region_shift) & _region_mask};
90 }
91
92 constexpr character_attributes& set_region(iso_3166 region) noexcept
93 {
94 hilet region_value = wide_cast<value_type>(region.intrinsic());
95 hi_axiom(region_value <= _region_mask);
96 _value &= ~(_region_mask << _region_shift);
97 _value |= region_value << _region_shift;
98 return *this;
99 }
100
101 constexpr hi::language_tag language_tag() const noexcept
102 {
103 return {language(), script(), region()};
104 }
105
106 constexpr character_attributes& set_language_tag(hi::language_tag language_tag) noexcept
107 {
108 return set_language(language_tag.language).set_script(language_tag.script).set_region(language_tag.region);
109 }
110
111 template<character_attribute... Args>
112 constexpr character_attributes(Args const&...args) noexcept
113 {
114 add(args...);
115 }
116
117 constexpr void add() noexcept {}
118
119 constexpr void add(iso_639 const& arg) noexcept
120 {
121 set_language(arg);
122 }
123
124 constexpr void add(iso_15924 const& arg) noexcept
125 {
126 set_script(arg);
127 }
128
129 constexpr void add(iso_3166 const& arg) noexcept
130 {
131 set_region(arg);
132 }
133
134 constexpr void add(hi::language_tag const &arg) noexcept
135 {
136 set_language_tag(arg);
137 }
138
139 constexpr void add(text_phrasing const& arg) noexcept
140 {
141 set_phrasing(arg);
142 }
143
144 template<character_attribute First, character_attribute Second, character_attribute... Rest>
145 constexpr void add(First const& first, Second const& second, Rest const&...rest) noexcept
146 {
147 add(first);
148 add(second, rest...);
149 }
150
151private:
152 constexpr static auto _phrasing_mask = value_type{0xf};
153 constexpr static auto _phrasing_shift = 35U;
154 constexpr static auto _region_mask = value_type{0x3ff};
155 constexpr static auto _region_shift = 25U;
156 constexpr static auto _script_mask = value_type{0x3ff};
157 constexpr static auto _script_shift = 15U;
158 constexpr static auto _language_mask = value_type{0x7fff};
159 constexpr static auto _language_shift = 0U;
160
168 value_type _value = {};
169};
170
171}} // namespace hi::v1
The text_phrasing type.
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Definition character_attributes.hpp:13
Tag used in constructors to set the intrinsic value of that object.
Definition utility.hpp:242
Definition character_attributes.hpp:10