xref: /aosp_15_r20/external/libchrome/base/strings/char_traits.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2018 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_STRINGS_CHAR_TRAITS_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_STRINGS_CHAR_TRAITS_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
11*635a8641SAndroid Build Coastguard Worker 
12*635a8641SAndroid Build Coastguard Worker namespace base {
13*635a8641SAndroid Build Coastguard Worker 
14*635a8641SAndroid Build Coastguard Worker // constexpr version of http://en.cppreference.com/w/cpp/string/char_traits.
15*635a8641SAndroid Build Coastguard Worker // This currently just implements the bits needed to support a (mostly)
16*635a8641SAndroid Build Coastguard Worker // constexpr StringPiece.
17*635a8641SAndroid Build Coastguard Worker //
18*635a8641SAndroid Build Coastguard Worker // TODO(dcheng): Once we switch to C++17, most methods will become constexpr and
19*635a8641SAndroid Build Coastguard Worker // we can switch over to using the one in the standard library.
20*635a8641SAndroid Build Coastguard Worker template <typename T>
21*635a8641SAndroid Build Coastguard Worker struct CharTraits {
22*635a8641SAndroid Build Coastguard Worker   // Performs a lexographical comparison of the first N characters of |s1| and
23*635a8641SAndroid Build Coastguard Worker   // |s2|. Returns 0 if equal, -1 if |s1| is less than |s2|, and 1 if |s1| is
24*635a8641SAndroid Build Coastguard Worker   // greater than |s2|.
25*635a8641SAndroid Build Coastguard Worker   static constexpr int compare(const T* s1, const T* s2, size_t n) noexcept;
26*635a8641SAndroid Build Coastguard Worker 
27*635a8641SAndroid Build Coastguard Worker   // Returns the length of |s|, assuming null termination (and not including the
28*635a8641SAndroid Build Coastguard Worker   // terminating null).
29*635a8641SAndroid Build Coastguard Worker   static constexpr size_t length(const T* s) noexcept;
30*635a8641SAndroid Build Coastguard Worker };
31*635a8641SAndroid Build Coastguard Worker 
32*635a8641SAndroid Build Coastguard Worker template <typename T>
compare(const T * s1,const T * s2,size_t n)33*635a8641SAndroid Build Coastguard Worker constexpr int CharTraits<T>::compare(const T* s1,
34*635a8641SAndroid Build Coastguard Worker                                      const T* s2,
35*635a8641SAndroid Build Coastguard Worker                                      size_t n) noexcept {
36*635a8641SAndroid Build Coastguard Worker   for (; n; --n, ++s1, ++s2) {
37*635a8641SAndroid Build Coastguard Worker     if (*s1 < *s2)
38*635a8641SAndroid Build Coastguard Worker       return -1;
39*635a8641SAndroid Build Coastguard Worker     if (*s1 > *s2)
40*635a8641SAndroid Build Coastguard Worker       return 1;
41*635a8641SAndroid Build Coastguard Worker   }
42*635a8641SAndroid Build Coastguard Worker   return 0;
43*635a8641SAndroid Build Coastguard Worker }
44*635a8641SAndroid Build Coastguard Worker 
45*635a8641SAndroid Build Coastguard Worker template <typename T>
length(const T * s)46*635a8641SAndroid Build Coastguard Worker constexpr size_t CharTraits<T>::length(const T* s) noexcept {
47*635a8641SAndroid Build Coastguard Worker   size_t i = 0;
48*635a8641SAndroid Build Coastguard Worker   for (; *s; ++s)
49*635a8641SAndroid Build Coastguard Worker     ++i;
50*635a8641SAndroid Build Coastguard Worker   return i;
51*635a8641SAndroid Build Coastguard Worker }
52*635a8641SAndroid Build Coastguard Worker 
53*635a8641SAndroid Build Coastguard Worker // char specialization of CharTraits that can use clang's constexpr instrinsics,
54*635a8641SAndroid Build Coastguard Worker // where available.
55*635a8641SAndroid Build Coastguard Worker template <>
56*635a8641SAndroid Build Coastguard Worker struct CharTraits<char> {
57*635a8641SAndroid Build Coastguard Worker   static constexpr int compare(const char* s1,
58*635a8641SAndroid Build Coastguard Worker                                const char* s2,
59*635a8641SAndroid Build Coastguard Worker                                size_t n) noexcept;
60*635a8641SAndroid Build Coastguard Worker   static constexpr size_t length(const char* s) noexcept;
61*635a8641SAndroid Build Coastguard Worker };
62*635a8641SAndroid Build Coastguard Worker 
63*635a8641SAndroid Build Coastguard Worker constexpr int CharTraits<char>::compare(const char* s1,
64*635a8641SAndroid Build Coastguard Worker                                         const char* s2,
65*635a8641SAndroid Build Coastguard Worker                                         size_t n) noexcept {
66*635a8641SAndroid Build Coastguard Worker #if HAS_FEATURE(cxx_constexpr_string_builtins)
67*635a8641SAndroid Build Coastguard Worker   return __builtin_memcmp(s1, s2, n);
68*635a8641SAndroid Build Coastguard Worker #else
69*635a8641SAndroid Build Coastguard Worker   for (; n; --n, ++s1, ++s2) {
70*635a8641SAndroid Build Coastguard Worker     if (*s1 < *s2)
71*635a8641SAndroid Build Coastguard Worker       return -1;
72*635a8641SAndroid Build Coastguard Worker     if (*s1 > *s2)
73*635a8641SAndroid Build Coastguard Worker       return 1;
74*635a8641SAndroid Build Coastguard Worker   }
75*635a8641SAndroid Build Coastguard Worker   return 0;
76*635a8641SAndroid Build Coastguard Worker #endif
77*635a8641SAndroid Build Coastguard Worker }
78*635a8641SAndroid Build Coastguard Worker 
79*635a8641SAndroid Build Coastguard Worker constexpr size_t CharTraits<char>::length(const char* s) noexcept {
80*635a8641SAndroid Build Coastguard Worker #if defined(__clang__)
81*635a8641SAndroid Build Coastguard Worker   return __builtin_strlen(s);
82*635a8641SAndroid Build Coastguard Worker #else
83*635a8641SAndroid Build Coastguard Worker   size_t i = 0;
84*635a8641SAndroid Build Coastguard Worker   for (; *s; ++s)
85*635a8641SAndroid Build Coastguard Worker     ++i;
86*635a8641SAndroid Build Coastguard Worker   return i;
87*635a8641SAndroid Build Coastguard Worker #endif
88*635a8641SAndroid Build Coastguard Worker }
89*635a8641SAndroid Build Coastguard Worker 
90*635a8641SAndroid Build Coastguard Worker }  // namespace base
91*635a8641SAndroid Build Coastguard Worker 
92*635a8641SAndroid Build Coastguard Worker #endif  // BASE_STRINGS_CHAR_TRAITS_H_
93