Bug 1531915 [wpt PR 15578] - Fix flakiness of external/wpt/css/css-position/z-index...
[gecko.git] / mfbt / TextUtils.h
blobca71472a49de93f2650080b28a1e20bedbdfde2f
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"
15 namespace mozilla {
17 namespace detail {
19 template <typename Char>
20 class MakeUnsignedChar : public MakeUnsigned<Char> {};
22 template <>
23 class MakeUnsignedChar<char16_t> {
24 public:
25 using Type = char16_t;
28 template <>
29 class MakeUnsignedChar<char32_t> {
30 public:
31 using Type = char32_t;
34 } // namespace detail
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);
41 return uc < 0x80;
44 /**
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++) {
51 if (!IsAscii(c)) {
52 return false;
55 return true;
58 /**
59 * Returns true iff |aChar| is Latin-1 but not ASCII, i.e. in the range
60 * [0x80, 0xFF].
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;
69 /**
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;
82 /**
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';
95 /**
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') {
166 return uc - '0';
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 */