HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
cp_1252.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 "char_converter.hpp"
8#include "../cast.hpp"
9#include "../required.hpp"
10#include "../architecture.hpp"
11#include <cstdint>
12#include <utility>
13
14namespace hi::inline v1 {
15namespace detail {
16
17constexpr auto cp_1252_make_table_0000_02DC() noexcept
18{
20 for (auto i = 0x0; i != 0x2dd; ++i) {
21 r[i] = 0x3f; // '?'
22 }
23 for (auto i = 0_uz; i != 0x80; ++i) {
24 r[i] = char_cast<uint8_t>(i);
25 }
26 r[0x81] = 0x81;
27 r[0x8d] = 0x8d;
28 r[0x8f] = 0x8f;
29 r[0x90] = 0x90;
30 r[0x9d] = 0x9d;
31 for (auto i = 0xa0; i != 0x100; ++i) {
32 r[i] = char_cast<uint8_t>(i);
33 }
34
35 r[0x192] = 0x83;
36 r[0x2c6] = 0x88;
37 r[0x160] = 0x8a;
38 r[0x152] = 0x8c;
39 r[0x17d] = 0x8e;
40
41 r[0x2dc] = 0x98;
42 r[0x161] = 0x9a;
43 r[0x153] = 0x9c;
44 r[0x17e] = 0x9e;
45 r[0x178] = 0x9f;
46
47 return r;
48}
49
50constexpr auto cp_1252_make_table_2000_2122() noexcept
51{
53 for (auto i = 0x0; i != 0x123; ++i) {
54 r[i] = 0x3f; // '?'
55 }
56
57 r[0xac] = 0x80;
58 r[0x1a] = 0x82;
59 r[0x1e] = 0x84;
60 r[0x26] = 0x85;
61 r[0x20] = 0x86;
62 r[0x21] = 0x87;
63 r[0x30] = 0x89;
64 r[0x39] = 0x8b;
65
66 r[0x18] = 0x91;
67 r[0x19] = 0x92;
68 r[0x1c] = 0x93;
69 r[0x1d] = 0x94;
70 r[0x22] = 0x95;
71 r[0x13] = 0x96;
72 r[0x14] = 0x97;
73 r[0x122] = 0x99;
74 r[0x3a] = 0x9b;
75
76 return r;
77}
78
79} // namespace detail
80
81template<>
82struct char_map<"cp-1252"> {
83 using char_type = char;
84
85 [[nodiscard]] constexpr std::endian guess_endian(void const *ptr, size_t size, std::endian endian) const noexcept
86 {
87 return std::endian::native;
88 }
89
90 template<typename It, typename EndIt>
91 [[nodiscard]] constexpr std::pair<char32_t, bool> read(It& it, EndIt last) const noexcept
92 {
93 // clang-format off
94 hi_axiom(it != last);
95 hilet c = char_cast<char8_t>(*it++);
96 switch (c) {
97 case 0x80: return {0x20ac, true};
98 case 0x81: return {0x81, true};
99 case 0x82: return {0x201a, true};
100 case 0x83: return {0x0192, true};
101 case 0x84: return {0x201e, true};
102 case 0x85: return {0x2026, true};
103 case 0x86: return {0x2020, true};
104 case 0x87: return {0x2021, true};
105 case 0x88: return {0x02c6, true};
106 case 0x89: return {0x2030, true};
107 case 0x8a: return {0x0160, true};
108 case 0x8b: return {0x2039, true};
109 case 0x8c: return {0x0152, true};
110 case 0x8d: return {0x8d, true};
111 case 0x8e: return {0x017d, true};
112 case 0x8f: return {0x8f, true};
113
114 case 0x90: return {0x90, true};
115 case 0x91: return {0x2018, true};
116 case 0x92: return {0x2019, true};
117 case 0x93: return {0x201c, true};
118 case 0x94: return {0x201d, true};
119 case 0x95: return {0x2022, true};
120 case 0x96: return {0x2013, true};
121 case 0x97: return {0x2014, true};
122 case 0x98: return {0x02dc, true};
123 case 0x99: return {0x2122, true};
124 case 0x9a: return {0x0161, true};
125 case 0x9b: return {0x203a, true};
126 case 0x9c: return {0x0153, true};
127 case 0x9d: return {0x9d, true};
128 case 0x9e: return {0x017e, true};
129 case 0x9f: return {0x0178, true};
130 default: return {c, true};
131 }
132 // clang-format on
133 }
134
135 constexpr static auto range_0000_02DC = detail::cp_1252_make_table_0000_02DC();
136 constexpr static auto range_2000_2122 = detail::cp_1252_make_table_2000_2122();
137
138 [[nodiscard]] constexpr std::pair<uint8_t, bool> size(char32_t code_point) const noexcept
139 {
140 hi_axiom(code_point < 0x11'0000);
141 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
142
143 if (code_point < 0x2dd) {
144 if (code_point == 0x3f) {
145 return {uint8_t{1}, true};
146 } else {
147 return {uint8_t{1}, range_0000_02DC[code_point] != 0x3f};
148 }
149 } else if (code_point < 0x2000) {
150 return {uint8_t{1}, false};
151
152 } else if (code_point < 0x2123) {
153 return {uint8_t{1}, range_2000_2122[code_point - 0x2000] != 0x3f};
154
155 } else {
156 return {uint8_t{1}, false};
157 }
158 }
159
160 template<typename It>
161 constexpr void write(char32_t code_point, It& dst) const noexcept
162 {
163 hi_axiom(code_point < 0x11'0000);
164 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
165
166 if (code_point < 0x2dd) {
167 *dst++ = char_cast<char_type>(range_0000_02DC[code_point]);
168
169 } else if (code_point < 0x2000) {
170 *dst++ = char_cast<char_type>(0x3f);
171
172 } else if (code_point < 0x2123) {
173 *dst++ = char_cast<char_type>(range_2000_2122[code_point - 0x2000]);
174
175 } else {
176 *dst++ = char_cast<char_type>(0x3f);
177 }
178 }
179
180#if defined(HI_HAS_SSE2)
181 template<typename It>
182 hi_force_inline __m128i read_ascii_chunk16(It it) const noexcept
183 {
184 return _mm_loadu_si128(reinterpret_cast<__m128i const *>(std::addressof(*it)));
185 }
186
187 template<typename It>
188 hi_force_inline void write_ascii_chunk16(__m128i chunk, It dst) const noexcept
189 {
190 _mm_storeu_si128(reinterpret_cast<__m128i *>(std::addressof(*dst)), chunk);
191 }
192#endif
193};
194
195} // namespace hi::inline v1
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
Character encoder/decoder template.
Definition char_converter.hpp:34
T addressof(T... args)