1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Character/text operations. */
9 #ifndef mozilla_TextUtils_h
10 #define mozilla_TextUtils_h
12 #include "mozilla/Assertions.h"
13 #include "mozilla/TypeTraits.h"
19 template <typename Char
>
20 class MakeUnsignedChar
: public MakeUnsigned
<Char
> {};
23 class MakeUnsignedChar
<char16_t
> {
25 using Type
= char16_t
;
29 class MakeUnsignedChar
<char32_t
> {
31 using Type
= char32_t
;
36 /** Returns true iff |aChar| is ASCII, i.e. in the range [0, 0x80). */
37 template <typename Char
>
38 constexpr bool IsAscii(Char aChar
) {
39 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
40 auto uc
= static_cast<UnsignedChar
>(aChar
);
45 * Returns true iff every character in the null-terminated string pointed to by
46 * |aChar| is ASCII, i.e. in the range [0, 0x80).
48 template <typename Char
>
49 constexpr bool IsAsciiNullTerminated(const Char
* aChar
) {
50 while (Char c
= *aChar
++) {
59 * Returns true iff |aChar| is Latin-1 but not ASCII, i.e. in the range
62 template <typename Char
>
63 constexpr bool IsNonAsciiLatin1(Char aChar
) {
64 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
65 auto uc
= static_cast<UnsignedChar
>(aChar
);
66 return uc
>= 0x80 && uc
<= 0xFF;
70 * Returns true iff |aChar| matches Ascii Whitespace.
72 * This function is intended to match the Infra standard
73 * (https://infra.spec.whatwg.org/#ascii-whitespace)
75 template <typename Char
>
76 constexpr bool IsAsciiWhitespace(Char aChar
) {
77 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
78 auto uc
= static_cast<UnsignedChar
>(aChar
);
79 return uc
== 0x9 || uc
== 0xA || uc
== 0xC || uc
== 0xD || uc
== 0x20;
83 * Returns true iff |aChar| matches [a-z].
85 * This function is basically what you thought islower was, except its behavior
86 * doesn't depend on the user's current locale.
88 template <typename Char
>
89 constexpr bool IsAsciiLowercaseAlpha(Char aChar
) {
90 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
91 auto uc
= static_cast<UnsignedChar
>(aChar
);
92 return 'a' <= uc
&& uc
<= 'z';
96 * Returns true iff |aChar| matches [A-Z].
98 * This function is basically what you thought isupper was, except its behavior
99 * doesn't depend on the user's current locale.
101 template <typename Char
>
102 constexpr bool IsAsciiUppercaseAlpha(Char aChar
) {
103 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
104 auto uc
= static_cast<UnsignedChar
>(aChar
);
105 return 'A' <= uc
&& uc
<= 'Z';
109 * Returns true iff |aChar| matches [a-zA-Z].
111 * This function is basically what you thought isalpha was, except its behavior
112 * doesn't depend on the user's current locale.
114 template <typename Char
>
115 constexpr bool IsAsciiAlpha(Char aChar
) {
116 return IsAsciiLowercaseAlpha(aChar
) || IsAsciiUppercaseAlpha(aChar
);
120 * Returns true iff |aChar| matches [0-9].
122 * This function is basically what you thought isdigit was, except its behavior
123 * doesn't depend on the user's current locale.
125 template <typename Char
>
126 constexpr bool IsAsciiDigit(Char aChar
) {
127 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
128 auto uc
= static_cast<UnsignedChar
>(aChar
);
129 return '0' <= uc
&& uc
<= '9';
133 * Returns true iff |aChar| matches [0-9a-fA-F].
135 * This function is basically isxdigit, but guaranteed to be only for ASCII.
137 template <typename Char
>
138 constexpr bool IsAsciiHexDigit(Char aChar
) {
139 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
140 auto uc
= static_cast<UnsignedChar
>(aChar
);
141 return ('0' <= uc
&& uc
<= '9') || ('a' <= uc
&& uc
<= 'f') ||
142 ('A' <= uc
&& uc
<= 'F');
146 * Returns true iff |aChar| matches [a-zA-Z0-9].
148 * This function is basically what you thought isalnum was, except its behavior
149 * doesn't depend on the user's current locale.
151 template <typename Char
>
152 constexpr bool IsAsciiAlphanumeric(Char aChar
) {
153 return IsAsciiDigit(aChar
) || IsAsciiAlpha(aChar
);
157 * Converts an ASCII alphanumeric digit [0-9a-zA-Z] to number as if in base-36.
158 * (This function therefore works for decimal, hexadecimal, etc.).
160 template <typename Char
>
161 uint8_t AsciiAlphanumericToNumber(Char aChar
) {
162 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
163 auto uc
= static_cast<UnsignedChar
>(aChar
);
165 if ('0' <= uc
&& uc
<= '9') {
169 if ('A' <= uc
&& uc
<= 'Z') {
170 return uc
- 'A' + 10;
173 // Ideally this function would be constexpr, but unfortunately gcc at least as
174 // of 6.4 forbids non-constexpr function calls in unevaluated constexpr
175 // function calls. See bug 1453456. So for now, just assert and leave the
176 // entire function non-constexpr.
177 MOZ_ASSERT('a' <= uc
&& uc
<= 'z',
178 "non-ASCII alphanumeric character can't be converted to number");
179 return uc
- 'a' + 10;
182 } // namespace mozilla
184 #endif /* mozilla_TextUtils_h */