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
);
44 template <typename Char
>
45 constexpr bool IsNonAsciiLatin1(Char aChar
) {
46 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
47 auto uc
= static_cast<UnsignedChar
>(aChar
);
48 return uc
>= 0x80 && uc
<= 0xFF;
52 * Returns true iff |aChar| matches Ascii Whitespace.
54 * This function is intended to match the Infra standard
55 * (https://infra.spec.whatwg.org/#ascii-whitespace)
57 template <typename Char
>
58 constexpr bool IsAsciiWhitespace(Char aChar
) {
59 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
60 auto uc
= static_cast<UnsignedChar
>(aChar
);
61 return uc
== 0x9 || uc
== 0xA || uc
== 0xC || uc
== 0xD || uc
== 0x20;
65 * Returns true iff |aChar| matches [a-z].
67 * This function is basically what you thought islower was, except its behavior
68 * doesn't depend on the user's current locale.
70 template <typename Char
>
71 constexpr bool IsAsciiLowercaseAlpha(Char aChar
) {
72 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
73 auto uc
= static_cast<UnsignedChar
>(aChar
);
74 return 'a' <= uc
&& uc
<= 'z';
78 * Returns true iff |aChar| matches [A-Z].
80 * This function is basically what you thought isupper was, except its behavior
81 * doesn't depend on the user's current locale.
83 template <typename Char
>
84 constexpr bool IsAsciiUppercaseAlpha(Char aChar
) {
85 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
86 auto uc
= static_cast<UnsignedChar
>(aChar
);
87 return 'A' <= uc
&& uc
<= 'Z';
91 * Returns true iff |aChar| matches [a-zA-Z].
93 * This function is basically what you thought isalpha was, except its behavior
94 * doesn't depend on the user's current locale.
96 template <typename Char
>
97 constexpr bool IsAsciiAlpha(Char aChar
) {
98 return IsAsciiLowercaseAlpha(aChar
) || IsAsciiUppercaseAlpha(aChar
);
102 * Returns true iff |aChar| matches [0-9].
104 * This function is basically what you thought isdigit was, except its behavior
105 * doesn't depend on the user's current locale.
107 template <typename Char
>
108 constexpr bool IsAsciiDigit(Char aChar
) {
109 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
110 auto uc
= static_cast<UnsignedChar
>(aChar
);
111 return '0' <= uc
&& uc
<= '9';
115 * Returns true iff |aChar| matches [0-9a-fA-F].
117 * This function is basically isxdigit, but guaranteed to be only for ASCII.
119 template <typename Char
>
120 constexpr bool IsAsciiHexDigit(Char aChar
) {
121 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
122 auto uc
= static_cast<UnsignedChar
>(aChar
);
123 return ('0' <= uc
&& uc
<= '9') || ('a' <= uc
&& uc
<= 'f') ||
124 ('A' <= uc
&& uc
<= 'F');
128 * Returns true iff |aChar| matches [a-zA-Z0-9].
130 * This function is basically what you thought isalnum was, except its behavior
131 * doesn't depend on the user's current locale.
133 template <typename Char
>
134 constexpr bool IsAsciiAlphanumeric(Char aChar
) {
135 return IsAsciiDigit(aChar
) || IsAsciiAlpha(aChar
);
139 * Converts an ASCII alphanumeric digit [0-9a-zA-Z] to number as if in base-36.
140 * (This function therefore works for decimal, hexadecimal, etc.).
142 template <typename Char
>
143 uint8_t AsciiAlphanumericToNumber(Char aChar
) {
144 using UnsignedChar
= typename
detail::MakeUnsignedChar
<Char
>::Type
;
145 auto uc
= static_cast<UnsignedChar
>(aChar
);
147 if ('0' <= uc
&& uc
<= '9') {
151 if ('A' <= uc
&& uc
<= 'Z') {
152 return uc
- 'A' + 10;
155 // Ideally this function would be constexpr, but unfortunately gcc at least as
156 // of 6.4 forbids non-constexpr function calls in unevaluated constexpr
157 // function calls. See bug 1453456. So for now, just assert and leave the
158 // entire function non-constexpr.
159 MOZ_ASSERT('a' <= uc
&& uc
<= 'z',
160 "non-ASCII alphanumeric character can't be converted to number");
161 return uc
- 'a' + 10;
164 } // namespace mozilla
166 #endif /* mozilla_TextUtils_h */