1 /*
2 * Copyright 2011-2020 Max Kellermann <max.kellermann@gmail.com>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 * OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifndef CHAR_UTIL_HXX
31 #define CHAR_UTIL_HXX
32
33 #ifdef _UNICODE
34 #include "WCharUtil.hxx"
35 #endif
36
37 constexpr bool
IsASCII(const unsigned char ch)38 IsASCII(const unsigned char ch) noexcept
39 {
40 return ch < 0x80;
41 }
42
43 constexpr bool
IsASCII(const char ch)44 IsASCII(const char ch) noexcept
45 {
46 return IsASCII((unsigned char)ch);
47 }
48
49 constexpr bool
IsWhitespaceOrNull(const char ch)50 IsWhitespaceOrNull(const char ch) noexcept
51 {
52 return (unsigned char)ch <= 0x20;
53 }
54
55 constexpr bool
IsWhitespaceNotNull(const char ch)56 IsWhitespaceNotNull(const char ch) noexcept
57 {
58 return ch > 0 && ch <= 0x20;
59 }
60
61 /**
62 * Is the given character whitespace? This calls the faster one of
63 * IsWhitespaceOrNull() or IsWhitespaceNotNull(). Use this if you
64 * want the fastest implementation, and you don't care if a null byte
65 * matches.
66 */
67 constexpr bool
IsWhitespaceFast(const char ch)68 IsWhitespaceFast(const char ch) noexcept
69 {
70 return IsWhitespaceOrNull(ch);
71 }
72
73 /**
74 * Is this a non-printable ASCII character? Returns false for
75 * non-ASCII characters.
76 *
77 * Note that this is not the opposite of IsNonPrintableASCII().
78 */
79 constexpr bool
IsPrintableASCII(char ch)80 IsPrintableASCII(char ch) noexcept
81 {
82 return (signed char)ch >= 0x20;
83 }
84
85 /**
86 * Is this a non-printable character? Returns false for non-ASCII characters.
87 *
88 * Note that this is not the opposite of IsPrintableASCII()
89 */
90 constexpr bool
IsNonPrintableASCII(char ch)91 IsNonPrintableASCII(char ch) noexcept
92 {
93 return (unsigned char)ch < 0x20;
94 }
95
96 constexpr bool
IsDigitASCII(char ch)97 IsDigitASCII(char ch) noexcept
98 {
99 return ch >= '0' && ch <= '9';
100 }
101
102 constexpr bool
IsUpperAlphaASCII(char ch)103 IsUpperAlphaASCII(char ch) noexcept
104 {
105 return ch >= 'A' && ch <= 'Z';
106 }
107
108 constexpr bool
IsLowerAlphaASCII(char ch)109 IsLowerAlphaASCII(char ch) noexcept
110 {
111 return ch >= 'a' && ch <= 'z';
112 }
113
114 constexpr bool
IsAlphaASCII(char ch)115 IsAlphaASCII(char ch) noexcept
116 {
117 return IsUpperAlphaASCII(ch) || IsLowerAlphaASCII(ch);
118 }
119
120 constexpr bool
IsAlphaNumericASCII(char ch)121 IsAlphaNumericASCII(char ch) noexcept
122 {
123 return IsAlphaASCII(ch) || IsDigitASCII(ch);
124 }
125
126 /**
127 * Convert the specified ASCII character (0x00..0x7f) to upper case.
128 * Unlike toupper(), it ignores the system locale.
129 */
130 constexpr char
ToUpperASCII(char ch)131 ToUpperASCII(char ch) noexcept
132 {
133 return ch >= 'a' && ch <= 'z'
134 ? (ch - ('a' - 'A'))
135 : ch;
136 }
137
138 /**
139 * Convert the specified ASCII character (0x00..0x7f) to lower case.
140 * Unlike tolower(), it ignores the system locale.
141 */
142 constexpr char
ToLowerASCII(char ch)143 ToLowerASCII(char ch) noexcept
144 {
145 return ch >= 'A' && ch <= 'Z'
146 ? (ch + ('a' - 'A'))
147 : ch;
148 }
149
150 constexpr bool
IsHexDigit(char ch)151 IsHexDigit(char ch) noexcept
152 {
153 return IsDigitASCII(ch) ||
154 (ch >= 'a' && ch <= 'f') ||
155 (ch >= 'A' && ch <= 'F');
156 }
157
158 #endif
159