1
0
mirror of https://github.com/roytam1/UXP.git synced 2026-05-26 05:46:58 +00:00
Files
UXP/mfbt/TextUtils.h

199 lines
5.5 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Character/text operations. */
#ifndef mozilla_TextUtils_h
#define mozilla_TextUtils_h
#include "mozilla/TypeTraits.h"
namespace mozilla {
namespace detail {
template<typename Char>
class MakeUnsignedChar
: public MakeUnsigned<Char>
{};
template<>
class MakeUnsignedChar<char16_t>
{
public:
using Type = char16_t;
};
template<>
class MakeUnsignedChar<char32_t>
{
public:
using Type = char32_t;
};
} // namespace detail
// The overloads below are not templated in order to make
// implicit conversions to span work as expected for the Span
// overloads.
/** Returns true iff |aChar| is ASCII, i.e. in the range [0, 0x80). */
inline constexpr bool IsAscii(unsigned char aChar) { return aChar < 0x80; }
/** Returns true iff |aChar| is ASCII, i.e. in the range [0, 0x80). */
inline constexpr bool IsAscii(signed char aChar) {
return IsAscii(static_cast<unsigned char>(aChar));
}
/** Returns true iff |aChar| is ASCII, i.e. in the range [0, 0x80). */
inline constexpr bool IsAscii(char aChar) {
return IsAscii(static_cast<unsigned char>(aChar));
}
/** Returns true iff |aChar| is ASCII, i.e. in the range [0, 0x80). */
inline constexpr bool IsAscii(char16_t aChar) { return aChar < 0x80; }
/** Returns true iff |aChar| is ASCII, i.e. in the range [0, 0x80). */
inline constexpr bool IsAscii(char32_t aChar) { return aChar < 0x80; }
/**
* Returns true iff every character in the null-terminated string pointed to by
* |aChar| is ASCII, i.e. in the range [0, 0x80).
*/
template <typename Char>
constexpr bool IsAsciiNullTerminated(const Char* aChar) {
while (Char c = *aChar++) {
if (!IsAscii(c)) {
return false;
}
}
return true;
}
/**
* Returns true iff |aChar| matches Ascii Whitespace.
*
* This function is intended to match the Infra standard
* (https://infra.spec.whatwg.org/#ascii-whitespace)
*/
template <typename Char>
constexpr bool IsAsciiWhitespace(Char aChar) {
using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type;
auto uc = static_cast<UnsignedChar>(aChar);
return uc == 0x9 || uc == 0xA || uc == 0xC || uc == 0xD || uc == 0x20;
}
/**
* Returns true iff |aChar| matches [a-z].
*
* This function is basically what you thought islower was, except its behavior
* doesn't depend on the user's current locale.
*/
template<typename Char>
constexpr bool
IsAsciiLowercaseAlpha(Char aChar)
{
using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type;
auto uc = static_cast<UnsignedChar>(aChar);
return 'a' <= uc && uc <= 'z';
}
/**
* Returns true iff |aChar| matches [A-Z].
*
* This function is basically what you thought isupper was, except its behavior
* doesn't depend on the user's current locale.
*/
template<typename Char>
constexpr bool
IsAsciiUppercaseAlpha(Char aChar)
{
using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type;
auto uc = static_cast<UnsignedChar>(aChar);
return 'A' <= uc && uc <= 'Z';
}
/**
* Returns true iff |aChar| matches [a-zA-Z].
*
* This function is basically what you thought isalpha was, except its behavior
* doesn't depend on the user's current locale.
*/
template<typename Char>
constexpr bool
IsAsciiAlpha(Char aChar)
{
return IsAsciiLowercaseAlpha(aChar) || IsAsciiUppercaseAlpha(aChar);
}
/**
* Returns true iff |aChar| matches [0-9].
*
* This function is basically what you thought isdigit was, except its behavior
* doesn't depend on the user's current locale.
*/
template<typename Char>
constexpr bool
IsAsciiDigit(Char aChar)
{
using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type;
auto uc = static_cast<UnsignedChar>(aChar);
return '0' <= uc && uc <= '9';
}
/**
* Returns true iff |aChar| matches [0-9a-fA-F].
*
* This function is basically isxdigit, but guaranteed to be only for ASCII.
*/
template <typename Char>
constexpr bool IsAsciiHexDigit(Char aChar) {
using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type;
auto uc = static_cast<UnsignedChar>(aChar);
return ('0' <= uc && uc <= '9') || ('a' <= uc && uc <= 'f') ||
('A' <= uc && uc <= 'F');
}
/**
* Returns true iff |aChar| matches [a-zA-Z0-9].
*
* This function is basically what you thought isalnum was, except its behavior
* doesn't depend on the user's current locale.
*/
template <typename Char>
constexpr bool IsAsciiAlphanumeric(Char aChar) {
return IsAsciiDigit(aChar) || IsAsciiAlpha(aChar);
}
/**
* Converts an ASCII alphanumeric digit [0-9a-zA-Z] to number as if in base-36.
* (This function therefore works for decimal, hexadecimal, etc.).
*/
template <typename Char>
uint8_t AsciiAlphanumericToNumber(Char aChar) {
using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type;
auto uc = static_cast<UnsignedChar>(aChar);
if ('0' <= uc && uc <= '9') {
return uc - '0';
}
if ('A' <= uc && uc <= 'Z') {
return uc - 'A' + 10;
}
// Ideally this function would be constexpr, but unfortunately gcc at least as
// of 6.4 forbids non-constexpr function calls in unevaluated constexpr
// function calls. See bug 1453456. So for now, just assert and leave the
// entire function non-constexpr.
MOZ_ASSERT('a' <= uc && uc <= 'z',
"non-ASCII alphanumeric character can't be converted to number");
return uc - 'a' + 10;
}
} // namespace mozilla
#endif /* mozilla_TextUtils_h */