llvm-mos-sdk
charset.h
Go to the documentation of this file.
1 // Copyright 2023 LLVM-MOS Project Licensed under the Apache License,
2 // Version 2.0 with LLVM Exceptions. See
3 // https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license
4 // information.
5 
6 #if __cplusplus < 202002L
7 #error charset support requies C++20
8 #else
9 #ifndef _CHARSET_H
10 #define _CHARSET_H
11 
12 #include <cstddef>
13 
14 namespace charset_impl {
15 
16 template <size_t N> struct AtasciiString {
17  char Str[N]{};
18 
19  constexpr AtasciiString(char const (&Src)[N]) {
20  for (size_t I = 0; I < N; ++I) {
21  if (Src[I] >= 0x80)
22  throw "use U prefix for unicode string literals";
23  Str[I] = TranslateUnicode(Src[I]);
24  }
25  }
26 
27  constexpr AtasciiString(char16_t const (&Src)[N]) {
28  for (size_t I = 0; I < N; ++I) {
29  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
30  throw "use U prefix for unicode string literals";
31  Str[I] = TranslateUnicode(Src[I]);
32  }
33  }
34 
35  constexpr AtasciiString(char32_t const (&Src)[N]) {
36  for (size_t I = 0; I < N; ++I)
37  Str[I] = TranslateUnicode(Src[I]);
38  }
39 
40  constexpr char TranslateUnicode(char32_t C) {
41  switch (C) {
42  default:
43  throw "Unsupported";
44 
45  // C0 control codes are uninterpreted.
46  case 0x0000 ... 0x001f:
47  return C;
48 
49  // Name: Map from Atari 8-bit series (interchange) graphics character
50  // set to Unicode
51 
52  // Date: 2018 April 20
53 
54  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
55 
56  case 0x2665:
57  return 0x00; // BLACK HEART SUIT
58  case 0x251C:
59  return 0x01; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
60  case 0x23B9:
61  return 0x02; // RIGHT VERTICAL BOX LINE
62  case 0x2518:
63  return 0x03; // BOX DRAWINGS LIGHT UP AND LEFT
64  case 0x2524:
65  return 0x04; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
66  case 0x2510:
67  return 0x05; // BOX DRAWINGS LIGHT DOWN AND LEFT
68  case 0x2571:
69  return 0x06; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
70  case 0x2572:
71  return 0x07; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
72  case 0x25E2:
73  return 0x08; // BLACK LOWER RIGHT TRIANGLE
74  case 0x2597:
75  return 0x09; // QUADRANT LOWER RIGHT
76  case 0x25E3:
77  return 0x0A; // BLACK LOWER LEFT TRIANGLE
78  case 0x259D:
79  return 0x0B; // QUADRANT UPPER RIGHT
80  case 0x2598:
81  return 0x0C; // QUADRANT UPPER LEFT
82  case 0x23BA:
83  return 0x0D; // HORIZONTAL SCAN LINE-1
84  case 0x23BD:
85  return 0x0E; // HORIZONTAL SCAN LINE-9
86  case 0x2596:
87  return 0x0F; // QUADRANT LOWER LEFT
88  case 0x2663:
89  return 0x10; // BLACK CLUB SUIT
90  case 0x250C:
91  return 0x11; // BOX DRAWINGS LIGHT DOWN AND RIGHT
92  case 0x2500:
93  return 0x12; // BOX DRAWINGS LIGHT HORIZONTAL
94  case 0x253C:
95  return 0x13; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
96  case 0x2022:
97  return 0x14; // BULLET
98  case 0x2584:
99  return 0x15; // LOWER HALF BLOCK
100  case 0x23B8:
101  return 0x16; // LEFT VERTICAL BOX LINE
102  case 0x252C:
103  return 0x17; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
104  case 0x2534:
105  return 0x18; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
106  case 0x258C:
107  return 0x19; // LEFT HALF BLOCK
108  case 0x2514:
109  return 0x1A; // BOX DRAWINGS LIGHT UP AND RIGHT
110  case 0x0020:
111  return 0x20; // SPACE
112  case 0x0021:
113  return 0x21; // EXCLAMATION MARK
114  case 0x0022:
115  return 0x22; // QUOTATION MARK
116  case 0x0023:
117  return 0x23; // NUMBER SIGN
118  case 0x0024:
119  return 0x24; // DOLLAR SIGN
120  case 0x0025:
121  return 0x25; // PERCENT SIGN
122  case 0x0026:
123  return 0x26; // AMPERSAND
124  case 0x0027:
125  return 0x27; // APOSTROPHE
126  case 0x0028:
127  return 0x28; // LEFT PARENTHESIS
128  case 0x0029:
129  return 0x29; // RIGHT PARENTHESIS
130  case 0x002A:
131  return 0x2A; // ASTERISK
132  case 0x002B:
133  return 0x2B; // PLUS SIGN
134  case 0x002C:
135  return 0x2C; // COMMA
136  case 0x002D:
137  return 0x2D; // HYPHEN-MINUS
138  case 0x002E:
139  return 0x2E; // FULL STOP
140  case 0x002F:
141  return 0x2F; // SOLIDUS
142  case 0x0030:
143  return 0x30; // DIGIT ZERO
144  case 0x0031:
145  return 0x31; // DIGIT ONE
146  case 0x0032:
147  return 0x32; // DIGIT TWO
148  case 0x0033:
149  return 0x33; // DIGIT THREE
150  case 0x0034:
151  return 0x34; // DIGIT FOUR
152  case 0x0035:
153  return 0x35; // DIGIT FIVE
154  case 0x0036:
155  return 0x36; // DIGIT SIX
156  case 0x0037:
157  return 0x37; // DIGIT SEVEN
158  case 0x0038:
159  return 0x38; // DIGIT EIGHT
160  case 0x0039:
161  return 0x39; // DIGIT NINE
162  case 0x003A:
163  return 0x3A; // COLON
164  case 0x003B:
165  return 0x3B; // SEMICOLON
166  case 0x003C:
167  return 0x3C; // LESS-THAN SIGN
168  case 0x003D:
169  return 0x3D; // EQUALS SIGN
170  case 0x003E:
171  return 0x3E; // GREATER-THAN SIGN
172  case 0x003F:
173  return 0x3F; // QUESTION MARK
174  case 0x0040:
175  return 0x40; // COMMERCIAL AT
176  case 0x0041:
177  return 0x41; // LATIN CAPITAL LETTER A
178  case 0x0042:
179  return 0x42; // LATIN CAPITAL LETTER B
180  case 0x0043:
181  return 0x43; // LATIN CAPITAL LETTER C
182  case 0x0044:
183  return 0x44; // LATIN CAPITAL LETTER D
184  case 0x0045:
185  return 0x45; // LATIN CAPITAL LETTER E
186  case 0x0046:
187  return 0x46; // LATIN CAPITAL LETTER F
188  case 0x0047:
189  return 0x47; // LATIN CAPITAL LETTER G
190  case 0x0048:
191  return 0x48; // LATIN CAPITAL LETTER H
192  case 0x0049:
193  return 0x49; // LATIN CAPITAL LETTER I
194  case 0x004A:
195  return 0x4A; // LATIN CAPITAL LETTER J
196  case 0x004B:
197  return 0x4B; // LATIN CAPITAL LETTER K
198  case 0x004C:
199  return 0x4C; // LATIN CAPITAL LETTER L
200  case 0x004D:
201  return 0x4D; // LATIN CAPITAL LETTER M
202  case 0x004E:
203  return 0x4E; // LATIN CAPITAL LETTER N
204  case 0x004F:
205  return 0x4F; // LATIN CAPITAL LETTER O
206  case 0x0050:
207  return 0x50; // LATIN CAPITAL LETTER P
208  case 0x0051:
209  return 0x51; // LATIN CAPITAL LETTER Q
210  case 0x0052:
211  return 0x52; // LATIN CAPITAL LETTER R
212  case 0x0053:
213  return 0x53; // LATIN CAPITAL LETTER S
214  case 0x0054:
215  return 0x54; // LATIN CAPITAL LETTER T
216  case 0x0055:
217  return 0x55; // LATIN CAPITAL LETTER U
218  case 0x0056:
219  return 0x56; // LATIN CAPITAL LETTER V
220  case 0x0057:
221  return 0x57; // LATIN CAPITAL LETTER W
222  case 0x0058:
223  return 0x58; // LATIN CAPITAL LETTER X
224  case 0x0059:
225  return 0x59; // LATIN CAPITAL LETTER Y
226  case 0x005A:
227  return 0x5A; // LATIN CAPITAL LETTER Z
228  case 0x005B:
229  return 0x5B; // LEFT SQUARE BRACKET
230  case 0x005C:
231  return 0x5C; // REVERSE SOLIDUS
232  case 0x005D:
233  return 0x5D; // RIGHT SQUARE BRACKET
234  case 0x005E:
235  return 0x5E; // CIRCUMFLEX ACCENT
236  case 0x005F:
237  return 0x5F; // LOW LINE
238  case 0x2666:
239  return 0x60; // BLACK DIAMOND SUIT
240  case 0x0061:
241  return 0x61; // LATIN SMALL LETTER A
242  case 0x0062:
243  return 0x62; // LATIN SMALL LETTER B
244  case 0x0063:
245  return 0x63; // LATIN SMALL LETTER C
246  case 0x0064:
247  return 0x64; // LATIN SMALL LETTER D
248  case 0x0065:
249  return 0x65; // LATIN SMALL LETTER E
250  case 0x0066:
251  return 0x66; // LATIN SMALL LETTER F
252  case 0x0067:
253  return 0x67; // LATIN SMALL LETTER G
254  case 0x0068:
255  return 0x68; // LATIN SMALL LETTER H
256  case 0x0069:
257  return 0x69; // LATIN SMALL LETTER I
258  case 0x006A:
259  return 0x6A; // LATIN SMALL LETTER J
260  case 0x006B:
261  return 0x6B; // LATIN SMALL LETTER K
262  case 0x006C:
263  return 0x6C; // LATIN SMALL LETTER L
264  case 0x006D:
265  return 0x6D; // LATIN SMALL LETTER M
266  case 0x006E:
267  return 0x6E; // LATIN SMALL LETTER N
268  case 0x006F:
269  return 0x6F; // LATIN SMALL LETTER O
270  case 0x0070:
271  return 0x70; // LATIN SMALL LETTER P
272  case 0x0071:
273  return 0x71; // LATIN SMALL LETTER Q
274  case 0x0072:
275  return 0x72; // LATIN SMALL LETTER R
276  case 0x0073:
277  return 0x73; // LATIN SMALL LETTER S
278  case 0x0074:
279  return 0x74; // LATIN SMALL LETTER T
280  case 0x0075:
281  return 0x75; // LATIN SMALL LETTER U
282  case 0x0076:
283  return 0x76; // LATIN SMALL LETTER V
284  case 0x0077:
285  return 0x77; // LATIN SMALL LETTER W
286  case 0x0078:
287  return 0x78; // LATIN SMALL LETTER X
288  case 0x0079:
289  return 0x79; // LATIN SMALL LETTER Y
290  case 0x007A:
291  return 0x7A; // LATIN SMALL LETTER Z
292  case 0x2660:
293  return 0x7B; // BLACK SPADE SUIT
294  case 0x007C:
295  return 0x7C; // VERTICAL LINE
296  case 0x25E4:
297  return 0x88; // BLACK UPPER LEFT TRIANGLE
298  case 0x259B:
299  return 0x89; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
300  case 0x25E5:
301  return 0x8A; // BLACK UPPER RIGHT TRIANGLE
302  case 0x2599:
303  return 0x8B; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
304  case 0x259F:
305  return 0x8C; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
306  case 0x259C:
307  return 0x8F; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
308  case 0x25D8:
309  return 0x94; // INVERSE BULLET
310  case 0x2580:
311  return 0x95; // UPPER HALF BLOCK
312  case 0x2590:
313  return 0x99; // RIGHT HALF BLOCK
314  }
315  }
316 };
317 
318 template <size_t N> struct AtasciiInternationalString {
319  char Str[N]{};
320 
321  constexpr AtasciiInternationalString(char const (&Src)[N]) {
322  for (size_t I = 0; I < N; ++I) {
323  if (Src[I] >= 0x80)
324  throw "use U prefix for unicode string literals";
325  Str[I] = TranslateUnicode(Src[I]);
326  }
327  }
328 
329  constexpr AtasciiInternationalString(char16_t const (&Src)[N]) {
330  for (size_t I = 0; I < N; ++I) {
331  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
332  throw "use U prefix for unicode string literals";
333  Str[I] = TranslateUnicode(Src[I]);
334  }
335  }
336 
337  constexpr AtasciiInternationalString(char32_t const (&Src)[N]) {
338  for (size_t I = 0; I < N; ++I)
339  Str[I] = TranslateUnicode(Src[I]);
340  }
341 
342  constexpr char TranslateUnicode(char32_t C) {
343  switch (C) {
344  default:
345  throw "Unsupported";
346 
347  // C0 control codes are uninterpreted.
348  case 0x0000 ... 0x001f:
349  return C;
350 
351  // Name: Map from Atari 8-bit series (interchange) international
352  // character set to Unicode
353 
354  // Date: 2018 April 20
355 
356  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
357 
358  case 0x00E1:
359  return 0x00; // LATIN SMALL LETTER A WITH ACUTE
360  case 0x00F9:
361  return 0x01; // LATIN SMALL LETTER U WITH GRAVE
362  case 0x00D1:
363  return 0x02; // LATIN CAPITAL LETTER N WITH TILDE
364  case 0x00C9:
365  return 0x03; // LATIN CAPITAL LETTER E WITH ACUTE
366  case 0x00E7:
367  return 0x04; // LATIN SMALL LETTER C WITH CEDILLA
368  case 0x00F4:
369  return 0x05; // LATIN SMALL LETTER O WITH CIRCUMFLEX
370  case 0x00F2:
371  return 0x06; // LATIN SMALL LETTER O WITH GRAVE
372  case 0x00EC:
373  return 0x07; // LATIN SMALL LETTER I WITH GRAVE
374  case 0x00A3:
375  return 0x08; // POUND SIGN
376  case 0x00EF:
377  return 0x09; // LATIN SMALL LETTER I WITH DIAERESIS
378  case 0x00FC:
379  return 0x0A; // LATIN SMALL LETTER U WITH DIAERESIS
380  case 0x00E4:
381  return 0x0B; // LATIN SMALL LETTER A WITH DIAERESIS
382  case 0x00D6:
383  return 0x0C; // LATIN CAPITAL LETTER O WITH DIAERESIS
384  case 0x00FA:
385  return 0x0D; // LATIN SMALL LETTER U WITH ACUTE
386  case 0x00F3:
387  return 0x0E; // LATIN SMALL LETTER O WITH ACUTE
388  case 0x00F6:
389  return 0x0F; // LATIN SMALL LETTER O WITH DIAERESIS
390  case 0x00DC:
391  return 0x10; // LATIN CAPITAL LETTER U WITH DIAERESIS
392  case 0x00E2:
393  return 0x11; // LATIN SMALL LETTER A WITH CIRCUMFLEX
394  case 0x00FB:
395  return 0x12; // LATIN SMALL LETTER U WITH CIRCUMFLEX
396  case 0x00EE:
397  return 0x13; // LATIN SMALL LETTER I WITH CIRCUMFLEX
398  case 0x00E9:
399  return 0x14; // LATIN SMALL LETTER E WITH ACUTE
400  case 0x00E8:
401  return 0x15; // LATIN SMALL LETTER E WITH GRAVE
402  case 0x00F1:
403  return 0x16; // LATIN SMALL LETTER N WITH TILDE
404  case 0x00EA:
405  return 0x17; // LATIN SMALL LETTER E WITH CIRCUMFLEX
406  case 0x00E5:
407  return 0x18; // LATIN SMALL LETTER A WITH RING ABOVE
408  case 0x00E0:
409  return 0x19; // LATIN SMALL LETTER A WITH GRAVE
410  case 0x00C5:
411  return 0x1A; // LATIN CAPITAL LETTER A WITH RING ABOVE
412  case 0x0020:
413  return 0x20; // SPACE
414  case 0x0021:
415  return 0x21; // EXCLAMATION MARK
416  case 0x0022:
417  return 0x22; // QUOTATION MARK
418  case 0x0023:
419  return 0x23; // NUMBER SIGN
420  case 0x0024:
421  return 0x24; // DOLLAR SIGN
422  case 0x0025:
423  return 0x25; // PERCENT SIGN
424  case 0x0026:
425  return 0x26; // AMPERSAND
426  case 0x0027:
427  return 0x27; // APOSTROPHE
428  case 0x0028:
429  return 0x28; // LEFT PARENTHESIS
430  case 0x0029:
431  return 0x29; // RIGHT PARENTHESIS
432  case 0x002A:
433  return 0x2A; // ASTERISK
434  case 0x002B:
435  return 0x2B; // PLUS SIGN
436  case 0x002C:
437  return 0x2C; // COMMA
438  case 0x002D:
439  return 0x2D; // HYPHEN-MINUS
440  case 0x002E:
441  return 0x2E; // FULL STOP
442  case 0x002F:
443  return 0x2F; // SOLIDUS
444  case 0x0030:
445  return 0x30; // DIGIT ZERO
446  case 0x0031:
447  return 0x31; // DIGIT ONE
448  case 0x0032:
449  return 0x32; // DIGIT TWO
450  case 0x0033:
451  return 0x33; // DIGIT THREE
452  case 0x0034:
453  return 0x34; // DIGIT FOUR
454  case 0x0035:
455  return 0x35; // DIGIT FIVE
456  case 0x0036:
457  return 0x36; // DIGIT SIX
458  case 0x0037:
459  return 0x37; // DIGIT SEVEN
460  case 0x0038:
461  return 0x38; // DIGIT EIGHT
462  case 0x0039:
463  return 0x39; // DIGIT NINE
464  case 0x003A:
465  return 0x3A; // COLON
466  case 0x003B:
467  return 0x3B; // SEMICOLON
468  case 0x003C:
469  return 0x3C; // LESS-THAN SIGN
470  case 0x003D:
471  return 0x3D; // EQUALS SIGN
472  case 0x003E:
473  return 0x3E; // GREATER-THAN SIGN
474  case 0x003F:
475  return 0x3F; // QUESTION MARK
476  case 0x0040:
477  return 0x40; // COMMERCIAL AT
478  case 0x0041:
479  return 0x41; // LATIN CAPITAL LETTER A
480  case 0x0042:
481  return 0x42; // LATIN CAPITAL LETTER B
482  case 0x0043:
483  return 0x43; // LATIN CAPITAL LETTER C
484  case 0x0044:
485  return 0x44; // LATIN CAPITAL LETTER D
486  case 0x0045:
487  return 0x45; // LATIN CAPITAL LETTER E
488  case 0x0046:
489  return 0x46; // LATIN CAPITAL LETTER F
490  case 0x0047:
491  return 0x47; // LATIN CAPITAL LETTER G
492  case 0x0048:
493  return 0x48; // LATIN CAPITAL LETTER H
494  case 0x0049:
495  return 0x49; // LATIN CAPITAL LETTER I
496  case 0x004A:
497  return 0x4A; // LATIN CAPITAL LETTER J
498  case 0x004B:
499  return 0x4B; // LATIN CAPITAL LETTER K
500  case 0x004C:
501  return 0x4C; // LATIN CAPITAL LETTER L
502  case 0x004D:
503  return 0x4D; // LATIN CAPITAL LETTER M
504  case 0x004E:
505  return 0x4E; // LATIN CAPITAL LETTER N
506  case 0x004F:
507  return 0x4F; // LATIN CAPITAL LETTER O
508  case 0x0050:
509  return 0x50; // LATIN CAPITAL LETTER P
510  case 0x0051:
511  return 0x51; // LATIN CAPITAL LETTER Q
512  case 0x0052:
513  return 0x52; // LATIN CAPITAL LETTER R
514  case 0x0053:
515  return 0x53; // LATIN CAPITAL LETTER S
516  case 0x0054:
517  return 0x54; // LATIN CAPITAL LETTER T
518  case 0x0055:
519  return 0x55; // LATIN CAPITAL LETTER U
520  case 0x0056:
521  return 0x56; // LATIN CAPITAL LETTER V
522  case 0x0057:
523  return 0x57; // LATIN CAPITAL LETTER W
524  case 0x0058:
525  return 0x58; // LATIN CAPITAL LETTER X
526  case 0x0059:
527  return 0x59; // LATIN CAPITAL LETTER Y
528  case 0x005A:
529  return 0x5A; // LATIN CAPITAL LETTER Z
530  case 0x005B:
531  return 0x5B; // LEFT SQUARE BRACKET
532  case 0x005C:
533  return 0x5C; // REVERSE SOLIDUS
534  case 0x005D:
535  return 0x5D; // RIGHT SQUARE BRACKET
536  case 0x005E:
537  return 0x5E; // CIRCUMFLEX ACCENT
538  case 0x005F:
539  return 0x5F; // LOW LINE
540  case 0x00A1:
541  return 0x60; // INVERTED EXCLAMATION MARK
542  case 0x0061:
543  return 0x61; // LATIN SMALL LETTER A
544  case 0x0062:
545  return 0x62; // LATIN SMALL LETTER B
546  case 0x0063:
547  return 0x63; // LATIN SMALL LETTER C
548  case 0x0064:
549  return 0x64; // LATIN SMALL LETTER D
550  case 0x0065:
551  return 0x65; // LATIN SMALL LETTER E
552  case 0x0066:
553  return 0x66; // LATIN SMALL LETTER F
554  case 0x0067:
555  return 0x67; // LATIN SMALL LETTER G
556  case 0x0068:
557  return 0x68; // LATIN SMALL LETTER H
558  case 0x0069:
559  return 0x69; // LATIN SMALL LETTER I
560  case 0x006A:
561  return 0x6A; // LATIN SMALL LETTER J
562  case 0x006B:
563  return 0x6B; // LATIN SMALL LETTER K
564  case 0x006C:
565  return 0x6C; // LATIN SMALL LETTER L
566  case 0x006D:
567  return 0x6D; // LATIN SMALL LETTER M
568  case 0x006E:
569  return 0x6E; // LATIN SMALL LETTER N
570  case 0x006F:
571  return 0x6F; // LATIN SMALL LETTER O
572  case 0x0070:
573  return 0x70; // LATIN SMALL LETTER P
574  case 0x0071:
575  return 0x71; // LATIN SMALL LETTER Q
576  case 0x0072:
577  return 0x72; // LATIN SMALL LETTER R
578  case 0x0073:
579  return 0x73; // LATIN SMALL LETTER S
580  case 0x0074:
581  return 0x74; // LATIN SMALL LETTER T
582  case 0x0075:
583  return 0x75; // LATIN SMALL LETTER U
584  case 0x0076:
585  return 0x76; // LATIN SMALL LETTER V
586  case 0x0077:
587  return 0x77; // LATIN SMALL LETTER W
588  case 0x0078:
589  return 0x78; // LATIN SMALL LETTER X
590  case 0x0079:
591  return 0x79; // LATIN SMALL LETTER Y
592  case 0x007A:
593  return 0x7A; // LATIN SMALL LETTER Z
594  case 0x00C4:
595  return 0x7B; // LATIN CAPITAL LETTER A WITH DIAERESIS
596  case 0x007C:
597  return 0x7C; // VERTICAL LINE
598  }
599  };
600 };
601 
602 template <size_t N> struct AtasciiVideoString {
603  char Str[N]{};
604 
605  constexpr AtasciiVideoString(char const (&Src)[N]) {
606  for (size_t I = 0; I < N; ++I) {
607  if (Src[I] >= 0x80)
608  throw "use U prefix for unicode string literals";
609  Str[I] = TranslateUnicode(Src[I]);
610  }
611  }
612 
613  constexpr AtasciiVideoString(char16_t const (&Src)[N]) {
614  for (size_t I = 0; I < N; ++I) {
615  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
616  throw "use U prefix for unicode string literals";
617  Str[I] = TranslateUnicode(Src[I]);
618  }
619  }
620 
621  constexpr AtasciiVideoString(char32_t const (&Src)[N]) {
622  for (size_t I = 0; I < N; ++I)
623  Str[I] = TranslateUnicode(Src[I]);
624  }
625 
626  constexpr char TranslateUnicode(char32_t C) {
627  switch (C) {
628  default:
629  throw "Unsupported";
630 
631  // Preserve NUL
632  case 0x0000:
633  return 0x00;
634 
635  // Name: Map from Atari 8-bit series (video) graphics character set to
636  // Unicode
637 
638  // Date: 2018 August 16
639 
640  // Author: Rebecca Bettencourt <support@kreativekorp.com>
641 
642  case 0x0020:
643  return 0x00; // SPACE
644  case 0x0021:
645  return 0x01; // EXCLAMATION MARK
646  case 0x0022:
647  return 0x02; // QUOTATION MARK
648  case 0x0023:
649  return 0x03; // NUMBER SIGN
650  case 0x0024:
651  return 0x04; // DOLLAR SIGN
652  case 0x0025:
653  return 0x05; // PERCENT SIGN
654  case 0x0026:
655  return 0x06; // AMPERSAND
656  case 0x0027:
657  return 0x07; // APOSTROPHE
658  case 0x0028:
659  return 0x08; // LEFT PARENTHESIS
660  case 0x0029:
661  return 0x09; // RIGHT PARENTHESIS
662  case 0x002A:
663  return 0x0A; // ASTERISK
664  case 0x002B:
665  return 0x0B; // PLUS SIGN
666  case 0x002C:
667  return 0x0C; // COMMA
668  case 0x002D:
669  return 0x0D; // HYPHEN-MINUS
670  case 0x002E:
671  return 0x0E; // FULL STOP
672  case 0x002F:
673  return 0x0F; // SOLIDUS
674  case 0x0030:
675  return 0x10; // DIGIT ZERO
676  case 0x0031:
677  return 0x11; // DIGIT ONE
678  case 0x0032:
679  return 0x12; // DIGIT TWO
680  case 0x0033:
681  return 0x13; // DIGIT THREE
682  case 0x0034:
683  return 0x14; // DIGIT FOUR
684  case 0x0035:
685  return 0x15; // DIGIT FIVE
686  case 0x0036:
687  return 0x16; // DIGIT SIX
688  case 0x0037:
689  return 0x17; // DIGIT SEVEN
690  case 0x0038:
691  return 0x18; // DIGIT EIGHT
692  case 0x0039:
693  return 0x19; // DIGIT NINE
694  case 0x003A:
695  return 0x1A; // COLON
696  case 0x003B:
697  return 0x1B; // SEMICOLON
698  case 0x003C:
699  return 0x1C; // LESS-THAN SIGN
700  case 0x003D:
701  return 0x1D; // EQUALS SIGN
702  case 0x003E:
703  return 0x1E; // GREATER-THAN SIGN
704  case 0x003F:
705  return 0x1F; // QUESTION MARK
706  case 0x0040:
707  return 0x20; // COMMERCIAL AT
708  case 0x0041:
709  return 0x21; // LATIN CAPITAL LETTER A
710  case 0x0042:
711  return 0x22; // LATIN CAPITAL LETTER B
712  case 0x0043:
713  return 0x23; // LATIN CAPITAL LETTER C
714  case 0x0044:
715  return 0x24; // LATIN CAPITAL LETTER D
716  case 0x0045:
717  return 0x25; // LATIN CAPITAL LETTER E
718  case 0x0046:
719  return 0x26; // LATIN CAPITAL LETTER F
720  case 0x0047:
721  return 0x27; // LATIN CAPITAL LETTER G
722  case 0x0048:
723  return 0x28; // LATIN CAPITAL LETTER H
724  case 0x0049:
725  return 0x29; // LATIN CAPITAL LETTER I
726  case 0x004A:
727  return 0x2A; // LATIN CAPITAL LETTER J
728  case 0x004B:
729  return 0x2B; // LATIN CAPITAL LETTER K
730  case 0x004C:
731  return 0x2C; // LATIN CAPITAL LETTER L
732  case 0x004D:
733  return 0x2D; // LATIN CAPITAL LETTER M
734  case 0x004E:
735  return 0x2E; // LATIN CAPITAL LETTER N
736  case 0x004F:
737  return 0x2F; // LATIN CAPITAL LETTER O
738  case 0x0050:
739  return 0x30; // LATIN CAPITAL LETTER P
740  case 0x0051:
741  return 0x31; // LATIN CAPITAL LETTER Q
742  case 0x0052:
743  return 0x32; // LATIN CAPITAL LETTER R
744  case 0x0053:
745  return 0x33; // LATIN CAPITAL LETTER S
746  case 0x0054:
747  return 0x34; // LATIN CAPITAL LETTER T
748  case 0x0055:
749  return 0x35; // LATIN CAPITAL LETTER U
750  case 0x0056:
751  return 0x36; // LATIN CAPITAL LETTER V
752  case 0x0057:
753  return 0x37; // LATIN CAPITAL LETTER W
754  case 0x0058:
755  return 0x38; // LATIN CAPITAL LETTER X
756  case 0x0059:
757  return 0x39; // LATIN CAPITAL LETTER Y
758  case 0x005A:
759  return 0x3A; // LATIN CAPITAL LETTER Z
760  case 0x005B:
761  return 0x3B; // LEFT SQUARE BRACKET
762  case 0x005C:
763  return 0x3C; // REVERSE SOLIDUS
764  case 0x005D:
765  return 0x3D; // RIGHT SQUARE BRACKET
766  case 0x005E:
767  return 0x3E; // CIRCUMFLEX ACCENT
768  case 0x005F:
769  return 0x3F; // LOW LINE
770  case 0x2665:
771  return 0x40; // BLACK HEART SUIT
772  case 0x251C:
773  return 0x41; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
774  case 0x23B9:
775  return 0x42; // RIGHT VERTICAL BOX LINE
776  case 0x2518:
777  return 0x43; // BOX DRAWINGS LIGHT UP AND LEFT
778  case 0x2524:
779  return 0x44; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
780  case 0x2510:
781  return 0x45; // BOX DRAWINGS LIGHT DOWN AND LEFT
782  case 0x2571:
783  return 0x46; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
784  case 0x2572:
785  return 0x47; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
786  case 0x25E2:
787  return 0x48; // BLACK LOWER RIGHT TRIANGLE
788  case 0x2597:
789  return 0x49; // QUADRANT LOWER RIGHT
790  case 0x25E3:
791  return 0x4A; // BLACK LOWER LEFT TRIANGLE
792  case 0x259D:
793  return 0x4B; // QUADRANT UPPER RIGHT
794  case 0x2598:
795  return 0x4C; // QUADRANT UPPER LEFT
796  case 0x23BA:
797  return 0x4D; // HORIZONTAL SCAN LINE-1
798  case 0x23BD:
799  return 0x4E; // HORIZONTAL SCAN LINE-9
800  case 0x2596:
801  return 0x4F; // QUADRANT LOWER LEFT
802  case 0x2663:
803  return 0x50; // BLACK CLUB SUIT
804  case 0x250C:
805  return 0x51; // BOX DRAWINGS LIGHT DOWN AND RIGHT
806  case 0x2500:
807  return 0x52; // BOX DRAWINGS LIGHT HORIZONTAL
808  case 0x253C:
809  return 0x53; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
810  case 0x2022:
811  return 0x54; // BULLET
812  case 0x2584:
813  return 0x55; // LOWER HALF BLOCK
814  case 0x23B8:
815  return 0x56; // LEFT VERTICAL BOX LINE
816  case 0x252C:
817  return 0x57; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
818  case 0x2534:
819  return 0x58; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
820  case 0x258C:
821  return 0x59; // LEFT HALF BLOCK
822  case 0x2514:
823  return 0x5A; // BOX DRAWINGS LIGHT UP AND RIGHT
824  case 0x241B:
825  return 0x5B; // SYMBOL FOR ESCAPE
826  case 0x2191:
827  return 0x5C; // UPWARDS ARROW
828  case 0x2193:
829  return 0x5D; // DOWNWARDS ARROW
830  case 0x2190:
831  return 0x5E; // LEFTWARDS ARROW
832  case 0x2192:
833  return 0x5F; // RIGHTWARDS ARROW
834  case 0x2666:
835  return 0x60; // BLACK DIAMOND SUIT
836  case 0x0061:
837  return 0x61; // LATIN SMALL LETTER A
838  case 0x0062:
839  return 0x62; // LATIN SMALL LETTER B
840  case 0x0063:
841  return 0x63; // LATIN SMALL LETTER C
842  case 0x0064:
843  return 0x64; // LATIN SMALL LETTER D
844  case 0x0065:
845  return 0x65; // LATIN SMALL LETTER E
846  case 0x0066:
847  return 0x66; // LATIN SMALL LETTER F
848  case 0x0067:
849  return 0x67; // LATIN SMALL LETTER G
850  case 0x0068:
851  return 0x68; // LATIN SMALL LETTER H
852  case 0x0069:
853  return 0x69; // LATIN SMALL LETTER I
854  case 0x006A:
855  return 0x6A; // LATIN SMALL LETTER J
856  case 0x006B:
857  return 0x6B; // LATIN SMALL LETTER K
858  case 0x006C:
859  return 0x6C; // LATIN SMALL LETTER L
860  case 0x006D:
861  return 0x6D; // LATIN SMALL LETTER M
862  case 0x006E:
863  return 0x6E; // LATIN SMALL LETTER N
864  case 0x006F:
865  return 0x6F; // LATIN SMALL LETTER O
866  case 0x0070:
867  return 0x70; // LATIN SMALL LETTER P
868  case 0x0071:
869  return 0x71; // LATIN SMALL LETTER Q
870  case 0x0072:
871  return 0x72; // LATIN SMALL LETTER R
872  case 0x0073:
873  return 0x73; // LATIN SMALL LETTER S
874  case 0x0074:
875  return 0x74; // LATIN SMALL LETTER T
876  case 0x0075:
877  return 0x75; // LATIN SMALL LETTER U
878  case 0x0076:
879  return 0x76; // LATIN SMALL LETTER V
880  case 0x0077:
881  return 0x77; // LATIN SMALL LETTER W
882  case 0x0078:
883  return 0x78; // LATIN SMALL LETTER X
884  case 0x0079:
885  return 0x79; // LATIN SMALL LETTER Y
886  case 0x007A:
887  return 0x7A; // LATIN SMALL LETTER Z
888  case 0x2660:
889  return 0x7B; // BLACK SPADE SUIT
890  case 0x007C:
891  return 0x7C; // VERTICAL LINE
892  case 0x1F8B0:
893  return 0x7D; // ARROW POINTING UPWARDS THEN NORTH WEST
894  case 0x25C0:
895  return 0x7E; // BLACK LEFT-POINTING TRIANGLE
896  case 0x25B6:
897  return 0x7F; // BLACK RIGHT-POINTING TRIANGLE
898  case 0x25E4:
899  return 0xC8; // BLACK UPPER LEFT TRIANGLE
900  case 0x259B:
901  return 0xC9; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
902  case 0x25E5:
903  return 0xCA; // BLACK UPPER RIGHT TRIANGLE
904  case 0x2599:
905  return 0xCB; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
906  case 0x259F:
907  return 0xCC; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
908  case 0x259C:
909  return 0xCF; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
910  case 0x25D8:
911  return 0xD4; // INVERSE BULLET
912  case 0x2580:
913  return 0xD5; // UPPER HALF BLOCK
914  case 0x2590:
915  return 0xD9; // RIGHT HALF BLOCK
916  }
917  }
918 };
919 
920 template <size_t N> struct AtasciiReverseVideoString {
921  char Str[N]{};
922 
923  constexpr AtasciiReverseVideoString(char const (&Src)[N]) {
924  for (size_t I = 0; I < N; ++I) {
925  if (Src[I] >= 0x80)
926  throw "use U prefix for unicode string literals";
927  Str[I] = TranslateUnicode(Src[I]);
928  }
929  }
930 
931  constexpr AtasciiReverseVideoString(char16_t const (&Src)[N]) {
932  for (size_t I = 0; I < N; ++I) {
933  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
934  throw "use U prefix for unicode string literals";
935  Str[I] = TranslateUnicode(Src[I]);
936  }
937  }
938 
939  constexpr AtasciiReverseVideoString(char32_t const (&Src)[N]) {
940  for (size_t I = 0; I < N; ++I)
941  Str[I] = TranslateUnicode(Src[I]);
942  }
943 
944  constexpr char TranslateUnicode(char32_t C) {
945  switch (C) {
946  default:
947  throw "Unsupported";
948 
949  // Preserve NUL
950  case 0x0000:
951  return 0x00;
952 
953  // Name: Map from Atari 8-bit series (video) graphics character set to
954  // Unicode
955 
956  // Date: 2018 August 16
957 
958  // Author: Rebecca Bettencourt <support@kreativekorp.com>
959 
960  case 0x0020:
961  return 0x80; // SPACE
962  case 0x0021:
963  return 0x81; // EXCLAMATION MARK
964  case 0x0022:
965  return 0x82; // QUOTATION MARK
966  case 0x0023:
967  return 0x83; // NUMBER SIGN
968  case 0x0024:
969  return 0x84; // DOLLAR SIGN
970  case 0x0025:
971  return 0x85; // PERCENT SIGN
972  case 0x0026:
973  return 0x86; // AMPERSAND
974  case 0x0027:
975  return 0x87; // APOSTROPHE
976  case 0x0028:
977  return 0x88; // LEFT PARENTHESIS
978  case 0x0029:
979  return 0x89; // RIGHT PARENTHESIS
980  case 0x002A:
981  return 0x8A; // ASTERISK
982  case 0x002B:
983  return 0x8B; // PLUS SIGN
984  case 0x002C:
985  return 0x8C; // COMMA
986  case 0x002D:
987  return 0x8D; // HYPHEN-MINUS
988  case 0x002E:
989  return 0x8E; // FULL STOP
990  case 0x002F:
991  return 0x8F; // SOLIDUS
992  case 0x0030:
993  return 0x90; // DIGIT ZERO
994  case 0x0031:
995  return 0x91; // DIGIT ONE
996  case 0x0032:
997  return 0x92; // DIGIT TWO
998  case 0x0033:
999  return 0x93; // DIGIT THREE
1000  case 0x0034:
1001  return 0x94; // DIGIT FOUR
1002  case 0x0035:
1003  return 0x95; // DIGIT FIVE
1004  case 0x0036:
1005  return 0x96; // DIGIT SIX
1006  case 0x0037:
1007  return 0x97; // DIGIT SEVEN
1008  case 0x0038:
1009  return 0x98; // DIGIT EIGHT
1010  case 0x0039:
1011  return 0x99; // DIGIT NINE
1012  case 0x003A:
1013  return 0x9A; // COLON
1014  case 0x003B:
1015  return 0x9B; // SEMICOLON
1016  case 0x003C:
1017  return 0x9C; // LESS-THAN SIGN
1018  case 0x003D:
1019  return 0x9D; // EQUALS SIGN
1020  case 0x003E:
1021  return 0x9E; // GREATER-THAN SIGN
1022  case 0x003F:
1023  return 0x9F; // QUESTION MARK
1024  case 0x0040:
1025  return 0xA0; // COMMERCIAL AT
1026  case 0x0041:
1027  return 0xA1; // LATIN CAPITAL LETTER A
1028  case 0x0042:
1029  return 0xA2; // LATIN CAPITAL LETTER B
1030  case 0x0043:
1031  return 0xA3; // LATIN CAPITAL LETTER C
1032  case 0x0044:
1033  return 0xA4; // LATIN CAPITAL LETTER D
1034  case 0x0045:
1035  return 0xA5; // LATIN CAPITAL LETTER E
1036  case 0x0046:
1037  return 0xA6; // LATIN CAPITAL LETTER F
1038  case 0x0047:
1039  return 0xA7; // LATIN CAPITAL LETTER G
1040  case 0x0048:
1041  return 0xA8; // LATIN CAPITAL LETTER H
1042  case 0x0049:
1043  return 0xA9; // LATIN CAPITAL LETTER I
1044  case 0x004A:
1045  return 0xAA; // LATIN CAPITAL LETTER J
1046  case 0x004B:
1047  return 0xAB; // LATIN CAPITAL LETTER K
1048  case 0x004C:
1049  return 0xAC; // LATIN CAPITAL LETTER L
1050  case 0x004D:
1051  return 0xAD; // LATIN CAPITAL LETTER M
1052  case 0x004E:
1053  return 0xAE; // LATIN CAPITAL LETTER N
1054  case 0x004F:
1055  return 0xAF; // LATIN CAPITAL LETTER O
1056  case 0x0050:
1057  return 0xB0; // LATIN CAPITAL LETTER P
1058  case 0x0051:
1059  return 0xB1; // LATIN CAPITAL LETTER Q
1060  case 0x0052:
1061  return 0xB2; // LATIN CAPITAL LETTER R
1062  case 0x0053:
1063  return 0xB3; // LATIN CAPITAL LETTER S
1064  case 0x0054:
1065  return 0xB4; // LATIN CAPITAL LETTER T
1066  case 0x0055:
1067  return 0xB5; // LATIN CAPITAL LETTER U
1068  case 0x0056:
1069  return 0xB6; // LATIN CAPITAL LETTER V
1070  case 0x0057:
1071  return 0xB7; // LATIN CAPITAL LETTER W
1072  case 0x0058:
1073  return 0xB8; // LATIN CAPITAL LETTER X
1074  case 0x0059:
1075  return 0xB9; // LATIN CAPITAL LETTER Y
1076  case 0x005A:
1077  return 0xBA; // LATIN CAPITAL LETTER Z
1078  case 0x005B:
1079  return 0xBB; // LEFT SQUARE BRACKET
1080  case 0x005C:
1081  return 0xBC; // REVERSE SOLIDUS
1082  case 0x005D:
1083  return 0xBD; // RIGHT SQUARE BRACKET
1084  case 0x005E:
1085  return 0xBE; // CIRCUMFLEX ACCENT
1086  case 0x005F:
1087  return 0xBF; // LOW LINE
1088  case 0x2665:
1089  return 0xC0; // BLACK HEART SUIT
1090  case 0x251C:
1091  return 0xC1; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
1092  case 0x23B9:
1093  return 0xC2; // RIGHT VERTICAL BOX LINE
1094  case 0x2518:
1095  return 0xC3; // BOX DRAWINGS LIGHT UP AND LEFT
1096  case 0x2524:
1097  return 0xC4; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
1098  case 0x2510:
1099  return 0xC5; // BOX DRAWINGS LIGHT DOWN AND LEFT
1100  case 0x2571:
1101  return 0xC6; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
1102  case 0x2572:
1103  return 0xC7; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
1104  case 0x23BA:
1105  return 0xCD; // HORIZONTAL SCAN LINE-1
1106  case 0x23BD:
1107  return 0xCE; // HORIZONTAL SCAN LINE-9
1108  case 0x2663:
1109  return 0xD0; // BLACK CLUB SUIT
1110  case 0x250C:
1111  return 0xD1; // BOX DRAWINGS LIGHT DOWN AND RIGHT
1112  case 0x2500:
1113  return 0xD2; // BOX DRAWINGS LIGHT HORIZONTAL
1114  case 0x253C:
1115  return 0xD3; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
1116  case 0x23B8:
1117  return 0xD6; // LEFT VERTICAL BOX LINE
1118  case 0x252C:
1119  return 0xD7; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
1120  case 0x2534:
1121  return 0xD8; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
1122  case 0x2514:
1123  return 0xDA; // BOX DRAWINGS LIGHT UP AND RIGHT
1124  case 0x241B:
1125  return 0xDB; // SYMBOL FOR ESCAPE
1126  case 0x2191:
1127  return 0xDC; // UPWARDS ARROW
1128  case 0x2193:
1129  return 0xDD; // DOWNWARDS ARROW
1130  case 0x2190:
1131  return 0xDE; // LEFTWARDS ARROW
1132  case 0x2192:
1133  return 0xDF; // RIGHTWARDS ARROW
1134  case 0x2666:
1135  return 0xE0; // BLACK DIAMOND SUIT
1136  case 0x0061:
1137  return 0xE1; // LATIN SMALL LETTER A
1138  case 0x0062:
1139  return 0xE2; // LATIN SMALL LETTER B
1140  case 0x0063:
1141  return 0xE3; // LATIN SMALL LETTER C
1142  case 0x0064:
1143  return 0xE4; // LATIN SMALL LETTER D
1144  case 0x0065:
1145  return 0xE5; // LATIN SMALL LETTER E
1146  case 0x0066:
1147  return 0xE6; // LATIN SMALL LETTER F
1148  case 0x0067:
1149  return 0xE7; // LATIN SMALL LETTER G
1150  case 0x0068:
1151  return 0xE8; // LATIN SMALL LETTER H
1152  case 0x0069:
1153  return 0xE9; // LATIN SMALL LETTER I
1154  case 0x006A:
1155  return 0xEA; // LATIN SMALL LETTER J
1156  case 0x006B:
1157  return 0xEB; // LATIN SMALL LETTER K
1158  case 0x006C:
1159  return 0xEC; // LATIN SMALL LETTER L
1160  case 0x006D:
1161  return 0xED; // LATIN SMALL LETTER M
1162  case 0x006E:
1163  return 0xEE; // LATIN SMALL LETTER N
1164  case 0x006F:
1165  return 0xEF; // LATIN SMALL LETTER O
1166  case 0x0070:
1167  return 0xF0; // LATIN SMALL LETTER P
1168  case 0x0071:
1169  return 0xF1; // LATIN SMALL LETTER Q
1170  case 0x0072:
1171  return 0xF2; // LATIN SMALL LETTER R
1172  case 0x0073:
1173  return 0xF3; // LATIN SMALL LETTER S
1174  case 0x0074:
1175  return 0xF4; // LATIN SMALL LETTER T
1176  case 0x0075:
1177  return 0xF5; // LATIN SMALL LETTER U
1178  case 0x0076:
1179  return 0xF6; // LATIN SMALL LETTER V
1180  case 0x0077:
1181  return 0xF7; // LATIN SMALL LETTER W
1182  case 0x0078:
1183  return 0xF8; // LATIN SMALL LETTER X
1184  case 0x0079:
1185  return 0xF9; // LATIN SMALL LETTER Y
1186  case 0x007A:
1187  return 0xFA; // LATIN SMALL LETTER Z
1188  case 0x2660:
1189  return 0xFB; // BLACK SPADE SUIT
1190  case 0x007C:
1191  return 0xFC; // VERTICAL LINE
1192  case 0x1F8B0:
1193  return 0xFD; // ARROW POINTING UPWARDS THEN NORTH WEST
1194  case 0x25C0:
1195  return 0xFE; // BLACK LEFT-POINTING TRIANGLE
1196  case 0x25B6:
1197  return 0xFF; // BLACK RIGHT-POINTING TRIANGLE
1198  }
1199  }
1200 };
1201 
1202 template <size_t N> struct AtasciiInternationalVideoString {
1203  char Str[N]{};
1204 
1205  constexpr AtasciiInternationalVideoString(char const (&Src)[N]) {
1206  for (size_t I = 0; I < N; ++I) {
1207  if (Src[I] >= 0x80)
1208  throw "use U prefix for unicode string literals";
1209  Str[I] = TranslateUnicode(Src[I]);
1210  }
1211  }
1212 
1213  constexpr AtasciiInternationalVideoString(char16_t const (&Src)[N]) {
1214  for (size_t I = 0; I < N; ++I) {
1215  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
1216  throw "use U prefix for unicode string literals";
1217  Str[I] = TranslateUnicode(Src[I]);
1218  }
1219  }
1220 
1221  constexpr AtasciiInternationalVideoString(char32_t const (&Src)[N]) {
1222  for (size_t I = 0; I < N; ++I)
1223  Str[I] = TranslateUnicode(Src[I]);
1224  }
1225 
1226  constexpr char TranslateUnicode(char32_t C) {
1227  switch (C) {
1228  default:
1229  throw "Unsupported";
1230 
1231  // Preserve NUL
1232  case 0x0000:
1233  return 0x00;
1234 
1235  // Name: Map from Atari 8-bit series (video) international character set
1236  // to Unicode
1237 
1238  // Date: 2018 August 16
1239 
1240  // Author: Rebecca Bettencourt <support@kreativekorp.com>
1241 
1242  case 0x0020:
1243  return 0x00; // SPACE
1244  case 0x0021:
1245  return 0x01; // EXCLAMATION MARK
1246  case 0x0022:
1247  return 0x02; // QUOTATION MARK
1248  case 0x0023:
1249  return 0x03; // NUMBER SIGN
1250  case 0x0024:
1251  return 0x04; // DOLLAR SIGN
1252  case 0x0025:
1253  return 0x05; // PERCENT SIGN
1254  case 0x0026:
1255  return 0x06; // AMPERSAND
1256  case 0x0027:
1257  return 0x07; // APOSTROPHE
1258  case 0x0028:
1259  return 0x08; // LEFT PARENTHESIS
1260  case 0x0029:
1261  return 0x09; // RIGHT PARENTHESIS
1262  case 0x002A:
1263  return 0x0A; // ASTERISK
1264  case 0x002B:
1265  return 0x0B; // PLUS SIGN
1266  case 0x002C:
1267  return 0x0C; // COMMA
1268  case 0x002D:
1269  return 0x0D; // HYPHEN-MINUS
1270  case 0x002E:
1271  return 0x0E; // FULL STOP
1272  case 0x002F:
1273  return 0x0F; // SOLIDUS
1274  case 0x0030:
1275  return 0x10; // DIGIT ZERO
1276  case 0x0031:
1277  return 0x11; // DIGIT ONE
1278  case 0x0032:
1279  return 0x12; // DIGIT TWO
1280  case 0x0033:
1281  return 0x13; // DIGIT THREE
1282  case 0x0034:
1283  return 0x14; // DIGIT FOUR
1284  case 0x0035:
1285  return 0x15; // DIGIT FIVE
1286  case 0x0036:
1287  return 0x16; // DIGIT SIX
1288  case 0x0037:
1289  return 0x17; // DIGIT SEVEN
1290  case 0x0038:
1291  return 0x18; // DIGIT EIGHT
1292  case 0x0039:
1293  return 0x19; // DIGIT NINE
1294  case 0x003A:
1295  return 0x1A; // COLON
1296  case 0x003B:
1297  return 0x1B; // SEMICOLON
1298  case 0x003C:
1299  return 0x1C; // LESS-THAN SIGN
1300  case 0x003D:
1301  return 0x1D; // EQUALS SIGN
1302  case 0x003E:
1303  return 0x1E; // GREATER-THAN SIGN
1304  case 0x003F:
1305  return 0x1F; // QUESTION MARK
1306  case 0x0040:
1307  return 0x20; // COMMERCIAL AT
1308  case 0x0041:
1309  return 0x21; // LATIN CAPITAL LETTER A
1310  case 0x0042:
1311  return 0x22; // LATIN CAPITAL LETTER B
1312  case 0x0043:
1313  return 0x23; // LATIN CAPITAL LETTER C
1314  case 0x0044:
1315  return 0x24; // LATIN CAPITAL LETTER D
1316  case 0x0045:
1317  return 0x25; // LATIN CAPITAL LETTER E
1318  case 0x0046:
1319  return 0x26; // LATIN CAPITAL LETTER F
1320  case 0x0047:
1321  return 0x27; // LATIN CAPITAL LETTER G
1322  case 0x0048:
1323  return 0x28; // LATIN CAPITAL LETTER H
1324  case 0x0049:
1325  return 0x29; // LATIN CAPITAL LETTER I
1326  case 0x004A:
1327  return 0x2A; // LATIN CAPITAL LETTER J
1328  case 0x004B:
1329  return 0x2B; // LATIN CAPITAL LETTER K
1330  case 0x004C:
1331  return 0x2C; // LATIN CAPITAL LETTER L
1332  case 0x004D:
1333  return 0x2D; // LATIN CAPITAL LETTER M
1334  case 0x004E:
1335  return 0x2E; // LATIN CAPITAL LETTER N
1336  case 0x004F:
1337  return 0x2F; // LATIN CAPITAL LETTER O
1338  case 0x0050:
1339  return 0x30; // LATIN CAPITAL LETTER P
1340  case 0x0051:
1341  return 0x31; // LATIN CAPITAL LETTER Q
1342  case 0x0052:
1343  return 0x32; // LATIN CAPITAL LETTER R
1344  case 0x0053:
1345  return 0x33; // LATIN CAPITAL LETTER S
1346  case 0x0054:
1347  return 0x34; // LATIN CAPITAL LETTER T
1348  case 0x0055:
1349  return 0x35; // LATIN CAPITAL LETTER U
1350  case 0x0056:
1351  return 0x36; // LATIN CAPITAL LETTER V
1352  case 0x0057:
1353  return 0x37; // LATIN CAPITAL LETTER W
1354  case 0x0058:
1355  return 0x38; // LATIN CAPITAL LETTER X
1356  case 0x0059:
1357  return 0x39; // LATIN CAPITAL LETTER Y
1358  case 0x005A:
1359  return 0x3A; // LATIN CAPITAL LETTER Z
1360  case 0x005B:
1361  return 0x3B; // LEFT SQUARE BRACKET
1362  case 0x005C:
1363  return 0x3C; // REVERSE SOLIDUS
1364  case 0x005D:
1365  return 0x3D; // RIGHT SQUARE BRACKET
1366  case 0x005E:
1367  return 0x3E; // CIRCUMFLEX ACCENT
1368  case 0x005F:
1369  return 0x3F; // LOW LINE
1370  case 0x00E1:
1371  return 0x40; // LATIN SMALL LETTER A WITH ACUTE
1372  case 0x00F9:
1373  return 0x41; // LATIN SMALL LETTER U WITH GRAVE
1374  case 0x00D1:
1375  return 0x42; // LATIN CAPITAL LETTER N WITH TILDE
1376  case 0x00C9:
1377  return 0x43; // LATIN CAPITAL LETTER E WITH ACUTE
1378  case 0x00E7:
1379  return 0x44; // LATIN SMALL LETTER C WITH CEDILLA
1380  case 0x00F4:
1381  return 0x45; // LATIN SMALL LETTER O WITH CIRCUMFLEX
1382  case 0x00F2:
1383  return 0x46; // LATIN SMALL LETTER O WITH GRAVE
1384  case 0x00EC:
1385  return 0x47; // LATIN SMALL LETTER I WITH GRAVE
1386  case 0x00A3:
1387  return 0x48; // POUND SIGN
1388  case 0x00EF:
1389  return 0x49; // LATIN SMALL LETTER I WITH DIAERESIS
1390  case 0x00FC:
1391  return 0x4A; // LATIN SMALL LETTER U WITH DIAERESIS
1392  case 0x00E4:
1393  return 0x4B; // LATIN SMALL LETTER A WITH DIAERESIS
1394  case 0x00D6:
1395  return 0x4C; // LATIN CAPITAL LETTER O WITH DIAERESIS
1396  case 0x00FA:
1397  return 0x4D; // LATIN SMALL LETTER U WITH ACUTE
1398  case 0x00F3:
1399  return 0x4E; // LATIN SMALL LETTER O WITH ACUTE
1400  case 0x00F6:
1401  return 0x4F; // LATIN SMALL LETTER O WITH DIAERESIS
1402  case 0x00DC:
1403  return 0x50; // LATIN CAPITAL LETTER U WITH DIAERESIS
1404  case 0x00E2:
1405  return 0x51; // LATIN SMALL LETTER A WITH CIRCUMFLEX
1406  case 0x00FB:
1407  return 0x52; // LATIN SMALL LETTER U WITH CIRCUMFLEX
1408  case 0x00EE:
1409  return 0x53; // LATIN SMALL LETTER I WITH CIRCUMFLEX
1410  case 0x00E9:
1411  return 0x54; // LATIN SMALL LETTER E WITH ACUTE
1412  case 0x00E8:
1413  return 0x55; // LATIN SMALL LETTER E WITH GRAVE
1414  case 0x00F1:
1415  return 0x56; // LATIN SMALL LETTER N WITH TILDE
1416  case 0x00EA:
1417  return 0x57; // LATIN SMALL LETTER E WITH CIRCUMFLEX
1418  case 0x00E5:
1419  return 0x58; // LATIN SMALL LETTER A WITH RING ABOVE
1420  case 0x00E0:
1421  return 0x59; // LATIN SMALL LETTER A WITH GRAVE
1422  case 0x00C5:
1423  return 0x5A; // LATIN CAPITAL LETTER A WITH RING ABOVE
1424  case 0x241B:
1425  return 0x5B; // SYMBOL FOR ESCAPE
1426  case 0x2191:
1427  return 0x5C; // UPWARDS ARROW
1428  case 0x2193:
1429  return 0x5D; // DOWNWARDS ARROW
1430  case 0x2190:
1431  return 0x5E; // LEFTWARDS ARROW
1432  case 0x2192:
1433  return 0x5F; // RIGHTWARDS ARROW
1434  case 0x00A1:
1435  return 0x60; // INVERTED EXCLAMATION MARK
1436  case 0x0061:
1437  return 0x61; // LATIN SMALL LETTER A
1438  case 0x0062:
1439  return 0x62; // LATIN SMALL LETTER B
1440  case 0x0063:
1441  return 0x63; // LATIN SMALL LETTER C
1442  case 0x0064:
1443  return 0x64; // LATIN SMALL LETTER D
1444  case 0x0065:
1445  return 0x65; // LATIN SMALL LETTER E
1446  case 0x0066:
1447  return 0x66; // LATIN SMALL LETTER F
1448  case 0x0067:
1449  return 0x67; // LATIN SMALL LETTER G
1450  case 0x0068:
1451  return 0x68; // LATIN SMALL LETTER H
1452  case 0x0069:
1453  return 0x69; // LATIN SMALL LETTER I
1454  case 0x006A:
1455  return 0x6A; // LATIN SMALL LETTER J
1456  case 0x006B:
1457  return 0x6B; // LATIN SMALL LETTER K
1458  case 0x006C:
1459  return 0x6C; // LATIN SMALL LETTER L
1460  case 0x006D:
1461  return 0x6D; // LATIN SMALL LETTER M
1462  case 0x006E:
1463  return 0x6E; // LATIN SMALL LETTER N
1464  case 0x006F:
1465  return 0x6F; // LATIN SMALL LETTER O
1466  case 0x0070:
1467  return 0x70; // LATIN SMALL LETTER P
1468  case 0x0071:
1469  return 0x71; // LATIN SMALL LETTER Q
1470  case 0x0072:
1471  return 0x72; // LATIN SMALL LETTER R
1472  case 0x0073:
1473  return 0x73; // LATIN SMALL LETTER S
1474  case 0x0074:
1475  return 0x74; // LATIN SMALL LETTER T
1476  case 0x0075:
1477  return 0x75; // LATIN SMALL LETTER U
1478  case 0x0076:
1479  return 0x76; // LATIN SMALL LETTER V
1480  case 0x0077:
1481  return 0x77; // LATIN SMALL LETTER W
1482  case 0x0078:
1483  return 0x78; // LATIN SMALL LETTER X
1484  case 0x0079:
1485  return 0x79; // LATIN SMALL LETTER Y
1486  case 0x007A:
1487  return 0x7A; // LATIN SMALL LETTER Z
1488  case 0x00C4:
1489  return 0x7B; // LATIN CAPITAL LETTER A WITH DIAERESIS
1490  case 0x007C:
1491  return 0x7C; // VERTICAL LINE
1492  case 0x1F8B0:
1493  return 0x7D; // ARROW POINTING UPWARDS THEN NORTH WEST
1494  case 0x25C0:
1495  return 0x7E; // BLACK LEFT-POINTING TRIANGLE
1496  case 0x25B6:
1497  return 0x7F; // BLACK RIGHT-POINTING TRIANGLE
1498  }
1499  }
1500 };
1501 
1502 template <size_t N> struct AtasciiInternationalReverseVideoString {
1503  char Str[N]{};
1504 
1505  constexpr AtasciiInternationalReverseVideoString(char const (&Src)[N]) {
1506  for (size_t I = 0; I < N; ++I) {
1507  if (Src[I] >= 0x80)
1508  throw "use U prefix for unicode string literals";
1509  Str[I] = TranslateUnicode(Src[I]);
1510  }
1511  }
1512 
1513  constexpr AtasciiInternationalReverseVideoString(char16_t const (&Src)[N]) {
1514  for (size_t I = 0; I < N; ++I) {
1515  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
1516  throw "use U prefix for unicode string literals";
1517  Str[I] = TranslateUnicode(Src[I]);
1518  }
1519  }
1520 
1521  constexpr AtasciiInternationalReverseVideoString(char32_t const (&Src)[N]) {
1522  for (size_t I = 0; I < N; ++I)
1523  Str[I] = TranslateUnicode(Src[I]);
1524  }
1525 
1526  constexpr char TranslateUnicode(char32_t C) {
1527  switch (C) {
1528  default:
1529  throw "Unsupported";
1530 
1531  // Preserve NUL
1532  case 0x0000:
1533  return 0x00;
1534 
1535  // Name: Map from Atari 8-bit series (video) international character set
1536  // to Unicode
1537 
1538  // Date: 2018 August 16
1539 
1540  // Author: Rebecca Bettencourt <support@kreativekorp.com>
1541 
1542  case 0x0020:
1543  return 0x80; // SPACE
1544  case 0x0021:
1545  return 0x81; // EXCLAMATION MARK
1546  case 0x0022:
1547  return 0x82; // QUOTATION MARK
1548  case 0x0023:
1549  return 0x83; // NUMBER SIGN
1550  case 0x0024:
1551  return 0x84; // DOLLAR SIGN
1552  case 0x0025:
1553  return 0x85; // PERCENT SIGN
1554  case 0x0026:
1555  return 0x86; // AMPERSAND
1556  case 0x0027:
1557  return 0x87; // APOSTROPHE
1558  case 0x0028:
1559  return 0x88; // LEFT PARENTHESIS
1560  case 0x0029:
1561  return 0x89; // RIGHT PARENTHESIS
1562  case 0x002A:
1563  return 0x8A; // ASTERISK
1564  case 0x002B:
1565  return 0x8B; // PLUS SIGN
1566  case 0x002C:
1567  return 0x8C; // COMMA
1568  case 0x002D:
1569  return 0x8D; // HYPHEN-MINUS
1570  case 0x002E:
1571  return 0x8E; // FULL STOP
1572  case 0x002F:
1573  return 0x8F; // SOLIDUS
1574  case 0x0030:
1575  return 0x90; // DIGIT ZERO
1576  case 0x0031:
1577  return 0x91; // DIGIT ONE
1578  case 0x0032:
1579  return 0x92; // DIGIT TWO
1580  case 0x0033:
1581  return 0x93; // DIGIT THREE
1582  case 0x0034:
1583  return 0x94; // DIGIT FOUR
1584  case 0x0035:
1585  return 0x95; // DIGIT FIVE
1586  case 0x0036:
1587  return 0x96; // DIGIT SIX
1588  case 0x0037:
1589  return 0x97; // DIGIT SEVEN
1590  case 0x0038:
1591  return 0x98; // DIGIT EIGHT
1592  case 0x0039:
1593  return 0x99; // DIGIT NINE
1594  case 0x003A:
1595  return 0x9A; // COLON
1596  case 0x003B:
1597  return 0x9B; // SEMICOLON
1598  case 0x003C:
1599  return 0x9C; // LESS-THAN SIGN
1600  case 0x003D:
1601  return 0x9D; // EQUALS SIGN
1602  case 0x003E:
1603  return 0x9E; // GREATER-THAN SIGN
1604  case 0x003F:
1605  return 0x9F; // QUESTION MARK
1606  case 0x0040:
1607  return 0xA0; // COMMERCIAL AT
1608  case 0x0041:
1609  return 0xA1; // LATIN CAPITAL LETTER A
1610  case 0x0042:
1611  return 0xA2; // LATIN CAPITAL LETTER B
1612  case 0x0043:
1613  return 0xA3; // LATIN CAPITAL LETTER C
1614  case 0x0044:
1615  return 0xA4; // LATIN CAPITAL LETTER D
1616  case 0x0045:
1617  return 0xA5; // LATIN CAPITAL LETTER E
1618  case 0x0046:
1619  return 0xA6; // LATIN CAPITAL LETTER F
1620  case 0x0047:
1621  return 0xA7; // LATIN CAPITAL LETTER G
1622  case 0x0048:
1623  return 0xA8; // LATIN CAPITAL LETTER H
1624  case 0x0049:
1625  return 0xA9; // LATIN CAPITAL LETTER I
1626  case 0x004A:
1627  return 0xAA; // LATIN CAPITAL LETTER J
1628  case 0x004B:
1629  return 0xAB; // LATIN CAPITAL LETTER K
1630  case 0x004C:
1631  return 0xAC; // LATIN CAPITAL LETTER L
1632  case 0x004D:
1633  return 0xAD; // LATIN CAPITAL LETTER M
1634  case 0x004E:
1635  return 0xAE; // LATIN CAPITAL LETTER N
1636  case 0x004F:
1637  return 0xAF; // LATIN CAPITAL LETTER O
1638  case 0x0050:
1639  return 0xB0; // LATIN CAPITAL LETTER P
1640  case 0x0051:
1641  return 0xB1; // LATIN CAPITAL LETTER Q
1642  case 0x0052:
1643  return 0xB2; // LATIN CAPITAL LETTER R
1644  case 0x0053:
1645  return 0xB3; // LATIN CAPITAL LETTER S
1646  case 0x0054:
1647  return 0xB4; // LATIN CAPITAL LETTER T
1648  case 0x0055:
1649  return 0xB5; // LATIN CAPITAL LETTER U
1650  case 0x0056:
1651  return 0xB6; // LATIN CAPITAL LETTER V
1652  case 0x0057:
1653  return 0xB7; // LATIN CAPITAL LETTER W
1654  case 0x0058:
1655  return 0xB8; // LATIN CAPITAL LETTER X
1656  case 0x0059:
1657  return 0xB9; // LATIN CAPITAL LETTER Y
1658  case 0x005A:
1659  return 0xBA; // LATIN CAPITAL LETTER Z
1660  case 0x005B:
1661  return 0xBB; // LEFT SQUARE BRACKET
1662  case 0x005C:
1663  return 0xBC; // REVERSE SOLIDUS
1664  case 0x005D:
1665  return 0xBD; // RIGHT SQUARE BRACKET
1666  case 0x005E:
1667  return 0xBE; // CIRCUMFLEX ACCENT
1668  case 0x005F:
1669  return 0xBF; // LOW LINE
1670  case 0x00E1:
1671  return 0xC0; // LATIN SMALL LETTER A WITH ACUTE
1672  case 0x00F9:
1673  return 0xC1; // LATIN SMALL LETTER U WITH GRAVE
1674  case 0x00D1:
1675  return 0xC2; // LATIN CAPITAL LETTER N WITH TILDE
1676  case 0x00C9:
1677  return 0xC3; // LATIN CAPITAL LETTER E WITH ACUTE
1678  case 0x00E7:
1679  return 0xC4; // LATIN SMALL LETTER C WITH CEDILLA
1680  case 0x00F4:
1681  return 0xC5; // LATIN SMALL LETTER O WITH CIRCUMFLEX
1682  case 0x00F2:
1683  return 0xC6; // LATIN SMALL LETTER O WITH GRAVE
1684  case 0x00EC:
1685  return 0xC7; // LATIN SMALL LETTER I WITH GRAVE
1686  case 0x00A3:
1687  return 0xC8; // POUND SIGN
1688  case 0x00EF:
1689  return 0xC9; // LATIN SMALL LETTER I WITH DIAERESIS
1690  case 0x00FC:
1691  return 0xCA; // LATIN SMALL LETTER U WITH DIAERESIS
1692  case 0x00E4:
1693  return 0xCB; // LATIN SMALL LETTER A WITH DIAERESIS
1694  case 0x00D6:
1695  return 0xCC; // LATIN CAPITAL LETTER O WITH DIAERESIS
1696  case 0x00FA:
1697  return 0xCD; // LATIN SMALL LETTER U WITH ACUTE
1698  case 0x00F3:
1699  return 0xCE; // LATIN SMALL LETTER O WITH ACUTE
1700  case 0x00F6:
1701  return 0xCF; // LATIN SMALL LETTER O WITH DIAERESIS
1702  case 0x00DC:
1703  return 0xD0; // LATIN CAPITAL LETTER U WITH DIAERESIS
1704  case 0x00E2:
1705  return 0xD1; // LATIN SMALL LETTER A WITH CIRCUMFLEX
1706  case 0x00FB:
1707  return 0xD2; // LATIN SMALL LETTER U WITH CIRCUMFLEX
1708  case 0x00EE:
1709  return 0xD3; // LATIN SMALL LETTER I WITH CIRCUMFLEX
1710  case 0x00E9:
1711  return 0xD4; // LATIN SMALL LETTER E WITH ACUTE
1712  case 0x00E8:
1713  return 0xD5; // LATIN SMALL LETTER E WITH GRAVE
1714  case 0x00F1:
1715  return 0xD6; // LATIN SMALL LETTER N WITH TILDE
1716  case 0x00EA:
1717  return 0xD7; // LATIN SMALL LETTER E WITH CIRCUMFLEX
1718  case 0x00E5:
1719  return 0xD8; // LATIN SMALL LETTER A WITH RING ABOVE
1720  case 0x00E0:
1721  return 0xD9; // LATIN SMALL LETTER A WITH GRAVE
1722  case 0x00C5:
1723  return 0xDA; // LATIN CAPITAL LETTER A WITH RING ABOVE
1724  case 0x241B:
1725  return 0xDB; // SYMBOL FOR ESCAPE
1726  case 0x2191:
1727  return 0xDC; // UPWARDS ARROW
1728  case 0x2193:
1729  return 0xDD; // DOWNWARDS ARROW
1730  case 0x2190:
1731  return 0xDE; // LEFTWARDS ARROW
1732  case 0x2192:
1733  return 0xDF; // RIGHTWARDS ARROW
1734  case 0x00A1:
1735  return 0xE0; // INVERTED EXCLAMATION MARK
1736  case 0x0061:
1737  return 0xE1; // LATIN SMALL LETTER A
1738  case 0x0062:
1739  return 0xE2; // LATIN SMALL LETTER B
1740  case 0x0063:
1741  return 0xE3; // LATIN SMALL LETTER C
1742  case 0x0064:
1743  return 0xE4; // LATIN SMALL LETTER D
1744  case 0x0065:
1745  return 0xE5; // LATIN SMALL LETTER E
1746  case 0x0066:
1747  return 0xE6; // LATIN SMALL LETTER F
1748  case 0x0067:
1749  return 0xE7; // LATIN SMALL LETTER G
1750  case 0x0068:
1751  return 0xE8; // LATIN SMALL LETTER H
1752  case 0x0069:
1753  return 0xE9; // LATIN SMALL LETTER I
1754  case 0x006A:
1755  return 0xEA; // LATIN SMALL LETTER J
1756  case 0x006B:
1757  return 0xEB; // LATIN SMALL LETTER K
1758  case 0x006C:
1759  return 0xEC; // LATIN SMALL LETTER L
1760  case 0x006D:
1761  return 0xED; // LATIN SMALL LETTER M
1762  case 0x006E:
1763  return 0xEE; // LATIN SMALL LETTER N
1764  case 0x006F:
1765  return 0xEF; // LATIN SMALL LETTER O
1766  case 0x0070:
1767  return 0xF0; // LATIN SMALL LETTER P
1768  case 0x0071:
1769  return 0xF1; // LATIN SMALL LETTER Q
1770  case 0x0072:
1771  return 0xF2; // LATIN SMALL LETTER R
1772  case 0x0073:
1773  return 0xF3; // LATIN SMALL LETTER S
1774  case 0x0074:
1775  return 0xF4; // LATIN SMALL LETTER T
1776  case 0x0075:
1777  return 0xF5; // LATIN SMALL LETTER U
1778  case 0x0076:
1779  return 0xF6; // LATIN SMALL LETTER V
1780  case 0x0077:
1781  return 0xF7; // LATIN SMALL LETTER W
1782  case 0x0078:
1783  return 0xF8; // LATIN SMALL LETTER X
1784  case 0x0079:
1785  return 0xF9; // LATIN SMALL LETTER Y
1786  case 0x007A:
1787  return 0xFA; // LATIN SMALL LETTER Z
1788  case 0x00C4:
1789  return 0xFB; // LATIN CAPITAL LETTER A WITH DIAERESIS
1790  case 0x007C:
1791  return 0xFC; // VERTICAL LINE
1792  case 0x1F8B0:
1793  return 0xFD; // ARROW POINTING UPWARDS THEN NORTH WEST
1794  case 0x25C0:
1795  return 0xFE; // BLACK LEFT-POINTING TRIANGLE
1796  case 0x25B6:
1797  return 0xFF; // BLACK RIGHT-POINTING TRIANGLE
1798  }
1799  }
1800 };
1801 
1802 } // namespace charset_impl
1803 
1804 template <charset_impl::AtasciiString S> constexpr auto operator""_a() {
1805  return S.Str;
1806 }
1807 template <charset_impl::AtasciiInternationalString S> constexpr auto operator""_i() {
1808  return S.Str;
1809 }
1810 
1811 template <charset_impl::AtasciiVideoString S> constexpr auto operator""_av() {
1812  return S.Str;
1813 }
1814 
1815 template <charset_impl::AtasciiReverseVideoString S>
1816 constexpr auto operator""_arv() {
1817  return S.Str;
1818 }
1819 
1820 template <charset_impl::AtasciiInternationalVideoString S> constexpr auto operator""_iv() {
1821  return S.Str;
1822 }
1823 
1824 template <charset_impl::AtasciiInternationalReverseVideoString S>
1825 constexpr auto operator""_irv() {
1826  return S.Str;
1827 }
1828 
1829 #endif // not _CHARSET_H
1830 #endif // __cplusplus >= 202002L
cstddef