tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

string_util_internal.h (2076B)


      1 // Copyright 2020 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_STRINGS_STRING_UTIL_INTERNAL_H_
      6 #define BASE_STRINGS_STRING_UTIL_INTERNAL_H_
      7 
      8 #include <type_traits>
      9 
     10 #include "base/ranges/algorithm.h"
     11 #include "base/strings/string_piece.h"
     12 
     13 namespace base::internal {
     14 
     15 // ASCII-specific tolower.  The standard library's tolower is locale sensitive,
     16 // so we don't want to use it here.
     17 template <typename CharT,
     18          typename = std::enable_if_t<std::is_integral_v<CharT>>>
     19 constexpr CharT ToLowerASCII(CharT c) {
     20  return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c;
     21 }
     22 
     23 template <typename T>
     24 constexpr int CompareCaseInsensitiveASCIIT(T a, T b) {
     25  // Find the first characters that aren't equal and compare them.  If the end
     26  // of one of the strings is found before a nonequal character, the lengths
     27  // of the strings are compared. Compare using the unsigned type so the sort
     28  // order is independent of the signedness of `char`.
     29  static_assert(std::is_integral_v<typename T::value_type>);
     30  using UCharT = std::make_unsigned_t<typename T::value_type>;
     31  size_t i = 0;
     32  while (i < a.length() && i < b.length()) {
     33    UCharT lower_a = static_cast<UCharT>(ToLowerASCII(a[i]));
     34    UCharT lower_b = static_cast<UCharT>(ToLowerASCII(b[i]));
     35    if (lower_a < lower_b)
     36      return -1;
     37    if (lower_a > lower_b)
     38      return 1;
     39    i++;
     40  }
     41 
     42  // End of one string hit before finding a different character. Expect the
     43  // common case to be "strings equal" at this point so check that first.
     44  if (a.length() == b.length())
     45    return 0;
     46 
     47  if (a.length() < b.length())
     48    return -1;
     49  return 1;
     50 }
     51 
     52 template <typename CharT, typename CharU>
     53 inline bool EqualsCaseInsensitiveASCIIT(BasicStringPiece<CharT> a,
     54                                        BasicStringPiece<CharU> b) {
     55  return ranges::equal(a, b, [](auto lhs, auto rhs) {
     56    return ToLowerASCII(lhs) == ToLowerASCII(rhs);
     57  });
     58 }
     59 
     60 }  // namespace base::internal
     61 
     62 #endif  // BASE_STRINGS_STRING_UTIL_INTERNAL_H_