1 // =================================
 2 // Copyright (c) 2025 Seppo Laakko
 3 // Distributed under the MIT license
 4 // =================================
 5 
 6 using System;
 7 using System.Collections;
 8 
 9 namespace System.Ascii
10 {
11     public enum CharClass : ushort
12     {
13         none = 0u, 
14         lower = 1u << 0u, 
15         upper = 1u << 1u, 
16         alpha = lower | upper, 
17         digit = 1u << 2u, 
18         alnum = alpha | digit, 
19         xdigit = 1u << 3u, 
20         cntrl = 1u << 4u, 
21         graph = 1u << 5u, 
22         print = 1u << 6u, 
23         punct = 1u << 7u, 
24         space = 1u << 8u
25     }
26 
27     public class CharClassTable
28     {
29         static CharClassTable() : instance(new CharClassTable())
30         {
31         }
32         public static CharClassTable& Instance()
33         {
34             return *instance;
35         }
36         public inline CharClass GetCharacterClass(char c)
37         {
38             return table[cast<byte>(c)];
39         }
40         private CharClassTable()
41         {
42             SetCharacterClass(cast<byte>('a'), cast<byte>('z'), CharClass.lower);
43             SetCharacterClass(cast<byte>('A'), cast<byte>('Z'), CharClass.upper);
44             SetCharacterClass(cast<byte>('0'), cast<byte>('9'), CharClass.digit);
45             SetCharacterClass(cast<byte>('0'), cast<byte>('9'), CharClass.xdigit);
46             SetCharacterClass(cast<byte>('a'), cast<byte>('f'), CharClass.xdigit);
47             SetCharacterClass(cast<byte>('A'), cast<byte>('F'), CharClass.xdigit);
48             SetCharacterClass(0u, 31u, CharClass.cntrl);
49             SetCharacterClass(127u, 127u, CharClass.cntrl);
50             SetCharacterClass(33u, 126u, CharClass.graph);
51             SetCharacterClass(32u, 126u, CharClass.print);
52             SetCharacterClass(33u, 47u, CharClass.punct);
53             SetCharacterClass(58u, 64u, CharClass.punct);
54             SetCharacterClass(91u, 96u, CharClass.punct);
55             SetCharacterClass(123u, 126u, CharClass.punct);
56             SetCharacterClass(9u, 13u, CharClass.space);
57             SetCharacterClass(32u, 32u, CharClass.space);
58         }
59         private void SetCharacterClass(byte first, byte last, CharClass c)
60         {
61             for (byte i = first; i <= last; ++i;)
62             {
63                 table[i] = cast<CharClass>(table[i] | c);
64             }
65         }
66         private static UniquePtr<CharClassTable> instance;
67         private CharClass[256] table;
68     }