1*6777b538SAndroid Build Coastguard Worker // Copyright 2024 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_STRINGS_CSTRING_VIEW_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_STRINGS_CSTRING_VIEW_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <algorithm> 9*6777b538SAndroid Build Coastguard Worker #include <concepts> 10*6777b538SAndroid Build Coastguard Worker #include <cstddef> 11*6777b538SAndroid Build Coastguard Worker #include <iosfwd> 12*6777b538SAndroid Build Coastguard Worker #include <string> 13*6777b538SAndroid Build Coastguard Worker #include <string_view> 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard Worker #include "base/check.h" 16*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h" 17*6777b538SAndroid Build Coastguard Worker #include "base/containers/checked_iterators.h" 18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr_exclusion.h" 19*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h" 20*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h" 21*6777b538SAndroid Build Coastguard Worker 22*6777b538SAndroid Build Coastguard Worker namespace base { 23*6777b538SAndroid Build Coastguard Worker 24*6777b538SAndroid Build Coastguard Worker // A CString is a NUL-terminated character array, which is the C programming 25*6777b538SAndroid Build Coastguard Worker // language representation of a string. This class (and its aliases below) 26*6777b538SAndroid Build Coastguard Worker // provides a non-owning and bounds-safe view of a CString, and can replace all 27*6777b538SAndroid Build Coastguard Worker // use of native pointers (such as `const char*`) for this purpose in C++ code. 28*6777b538SAndroid Build Coastguard Worker // 29*6777b538SAndroid Build Coastguard Worker // The basic_cstring_view class is followed by aliases for the various char 30*6777b538SAndroid Build Coastguard Worker // types: 31*6777b538SAndroid Build Coastguard Worker // * cstring_view provides a view of a `const char*`. 32*6777b538SAndroid Build Coastguard Worker // * u16cstring_view provides a view of a `const char16_t*`. 33*6777b538SAndroid Build Coastguard Worker // * u32cstring_view provides a view of a `const char32_t*`. 34*6777b538SAndroid Build Coastguard Worker // * wcstring_view provides a view of a `const wchar_t*`. 35*6777b538SAndroid Build Coastguard Worker template <class Char> 36*6777b538SAndroid Build Coastguard Worker class basic_cstring_view final { 37*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_const_v<Char>); 38*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_reference_v<Char>); 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Worker public: 41*6777b538SAndroid Build Coastguard Worker using value_type = Char; 42*6777b538SAndroid Build Coastguard Worker using pointer = Char*; 43*6777b538SAndroid Build Coastguard Worker using const_pointer = const Char*; 44*6777b538SAndroid Build Coastguard Worker using reference = Char&; 45*6777b538SAndroid Build Coastguard Worker using const_reference = const Char&; 46*6777b538SAndroid Build Coastguard Worker using iterator = CheckedContiguousIterator<const Char>; 47*6777b538SAndroid Build Coastguard Worker using const_iterator = CheckedContiguousIterator<const Char>; 48*6777b538SAndroid Build Coastguard Worker using reverse_iterator = std::reverse_iterator<iterator>; 49*6777b538SAndroid Build Coastguard Worker using const_reverse_iterator = std::reverse_iterator<iterator>; 50*6777b538SAndroid Build Coastguard Worker using size_type = size_t; 51*6777b538SAndroid Build Coastguard Worker using difference_type = ptrdiff_t; 52*6777b538SAndroid Build Coastguard Worker 53*6777b538SAndroid Build Coastguard Worker // The `npos` constant represents a non-existent position in the cstring view. 54*6777b538SAndroid Build Coastguard Worker constexpr static auto npos = static_cast<size_t>(-1); 55*6777b538SAndroid Build Coastguard Worker 56*6777b538SAndroid Build Coastguard Worker // Constructs an empty cstring view, which points to an empty string with a 57*6777b538SAndroid Build Coastguard Worker // terminating NUL. basic_cstring_view()58*6777b538SAndroid Build Coastguard Worker constexpr basic_cstring_view() noexcept : ptr_(kEmpty), len_(0u) {} 59*6777b538SAndroid Build Coastguard Worker 60*6777b538SAndroid Build Coastguard Worker // cstring views are trivially copyable, moveable, and destructible. 61*6777b538SAndroid Build Coastguard Worker 62*6777b538SAndroid Build Coastguard Worker // Constructs a cstring view that points at the contents of a string literal. 63*6777b538SAndroid Build Coastguard Worker // 64*6777b538SAndroid Build Coastguard Worker // Example: 65*6777b538SAndroid Build Coastguard Worker // ``` 66*6777b538SAndroid Build Coastguard Worker // const char kLiteral[] = "hello world"; 67*6777b538SAndroid Build Coastguard Worker // auto s = base::cstring_view(kLiteral); 68*6777b538SAndroid Build Coastguard Worker // CHECK(s == "hello world"); 69*6777b538SAndroid Build Coastguard Worker // auto s2 = base::cstring_view("this works too"); 70*6777b538SAndroid Build Coastguard Worker // CHECK(s == "this works too"); 71*6777b538SAndroid Build Coastguard Worker // ``` 72*6777b538SAndroid Build Coastguard Worker template <int&..., size_t M> 73*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-explicit-constructor) basic_cstring_view(const Char (& lit LIFETIME_BOUND)[M])74*6777b538SAndroid Build Coastguard Worker constexpr basic_cstring_view(const Char (&lit LIFETIME_BOUND)[M]) noexcept 75*6777b538SAndroid Build Coastguard Worker ENABLE_IF_ATTR(lit[M - 1u] == Char{0}, "requires string literal as input") 76*6777b538SAndroid Build Coastguard Worker : ptr_(lit), len_(M - 1u) { 77*6777b538SAndroid Build Coastguard Worker // For non-clang compilers. On clang, the function is not even callable 78*6777b538SAndroid Build Coastguard Worker // without this being known to pass at compile time. 79*6777b538SAndroid Build Coastguard Worker // 80*6777b538SAndroid Build Coastguard Worker // SAFETY: lit is an array of size M, so M-1 is in bounds. 81*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(UNSAFE_BUFFERS(lit[M - 1u]), Char{0}); 82*6777b538SAndroid Build Coastguard Worker } 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker // Constructs a cstring view from a std::string (or other std::basic_string 85*6777b538SAndroid Build Coastguard Worker // type). The string parameter must outlive the cstring view, including that 86*6777b538SAndroid Build Coastguard Worker // it must not be moved-from or destroyed. 87*6777b538SAndroid Build Coastguard Worker // 88*6777b538SAndroid Build Coastguard Worker // This conversion is implicit, which matches the conversion from std::string 89*6777b538SAndroid Build Coastguard Worker // to std::string_view (through string's `operator string_view()`). 90*6777b538SAndroid Build Coastguard Worker // 91*6777b538SAndroid Build Coastguard Worker // # Interaction with SSO 92*6777b538SAndroid Build Coastguard Worker // std::string stores its contents inline when they fit (which is an 93*6777b538SAndroid Build Coastguard Worker // implementation defined length), instead of in a heap-allocated buffer. This 94*6777b538SAndroid Build Coastguard Worker // is referred to as the Small String Optimization. This means that moving or 95*6777b538SAndroid Build Coastguard Worker // destring a std::string will invalidate a cstring view and leave it with 96*6777b538SAndroid Build Coastguard Worker // dangling pointers. This differs from the behaviour of std::vector and span, 97*6777b538SAndroid Build Coastguard Worker // since pointers into a std::vector remain valid after moving the std::vector 98*6777b538SAndroid Build Coastguard Worker // and destroying the original. 99*6777b538SAndroid Build Coastguard Worker // 100*6777b538SAndroid Build Coastguard Worker // # Preventing implicit temporaries 101*6777b538SAndroid Build Coastguard Worker // Because std::string can be implicitly constructed, the string constructor 102*6777b538SAndroid Build Coastguard Worker // may unintentionally be called with a temporary `std::string` when called 103*6777b538SAndroid Build Coastguard Worker // with values that convert to `std::string`. We prevent this templating this 104*6777b538SAndroid Build Coastguard Worker // constructor and requiring the incoming type to actually be a `std::string` 105*6777b538SAndroid Build Coastguard Worker // (or other `std::basic_string`). This also improves compiler errors, 106*6777b538SAndroid Build Coastguard Worker // compared to deleting a string&& overload, when passed an array that does 107*6777b538SAndroid Build Coastguard Worker // not match the `ENABLE_IF_ATTR` constructor condition by not sending it to a 108*6777b538SAndroid Build Coastguard Worker // deleted overload receiving `std::string`. 109*6777b538SAndroid Build Coastguard Worker template <std::same_as<std::basic_string<Char>> String> 110*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-explicit-constructor) basic_cstring_view(const String & s LIFETIME_BOUND)111*6777b538SAndroid Build Coastguard Worker constexpr basic_cstring_view(const String& s LIFETIME_BOUND) noexcept 112*6777b538SAndroid Build Coastguard Worker : ptr_(s.c_str()), len_(s.size()) {} 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker // Unsafe construction from a pointer and length. Prefer to construct cstring 115*6777b538SAndroid Build Coastguard Worker // view from a string literal, std::string, or another cstring view. 116*6777b538SAndroid Build Coastguard Worker // 117*6777b538SAndroid Build Coastguard Worker // # Safety 118*6777b538SAndroid Build Coastguard Worker // The `ptr` and `len` pair indicate a valid NUL-terminated string: 119*6777b538SAndroid Build Coastguard Worker // * The `ptr` must not be null, and must point to a NUL-terminated string. 120*6777b538SAndroid Build Coastguard Worker // * The `len` must be valid such that `ptr + len` gives a pointer to the 121*6777b538SAndroid Build Coastguard Worker // terminating NUL and is in the same allocation as `ptr`. basic_cstring_view(const Char * ptr LIFETIME_BOUND,size_t len)122*6777b538SAndroid Build Coastguard Worker UNSAFE_BUFFER_USAGE explicit constexpr basic_cstring_view(const Char* ptr 123*6777b538SAndroid Build Coastguard Worker LIFETIME_BOUND, 124*6777b538SAndroid Build Coastguard Worker size_t len) 125*6777b538SAndroid Build Coastguard Worker : ptr_(ptr), len_(len) { 126*6777b538SAndroid Build Coastguard Worker // This method is marked UNSAFE_BUFFER_USAGE so we are trusting the caller 127*6777b538SAndroid Build Coastguard Worker // to do things right, and expecting strong scrutiny at the call site, but 128*6777b538SAndroid Build Coastguard Worker // we perform a debug check to help catch mistakes regardless. 129*6777b538SAndroid Build Coastguard Worker // 130*6777b538SAndroid Build Coastguard Worker // SAFETY: `ptr` points to `len` many chars and then a NUL, according to the 131*6777b538SAndroid Build Coastguard Worker // caller of this method. So then `len` index will be in bounds and return 132*6777b538SAndroid Build Coastguard Worker // the NUL. 133*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(UNSAFE_BUFFERS(ptr[len]), Char{0}); 134*6777b538SAndroid Build Coastguard Worker } 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Worker // Returns a pointer to the NUL-terminated string, for passing to C-style APIs 137*6777b538SAndroid Build Coastguard Worker // that require `const char*` (or whatever the `Char` type is). 138*6777b538SAndroid Build Coastguard Worker // 139*6777b538SAndroid Build Coastguard Worker // This is never null. c_str()140*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const Char* c_str() const noexcept { return ptr_; } 141*6777b538SAndroid Build Coastguard Worker 142*6777b538SAndroid Build Coastguard Worker // Returns a pointer to underlying buffer. To get a string pointer, use 143*6777b538SAndroid Build Coastguard Worker // `c_str()`. 144*6777b538SAndroid Build Coastguard Worker // 145*6777b538SAndroid Build Coastguard Worker // Pair with `size()` to construct a bounded non-NUL-terminated view, such as 146*6777b538SAndroid Build Coastguard Worker // by `base::span`. This is never null. data()147*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const Char* data() const noexcept { return ptr_; } 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker // Returns the number of characters in the string, not including the 150*6777b538SAndroid Build Coastguard Worker // terminating NUL. size()151*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr size_t size() const noexcept { return len_; } 152*6777b538SAndroid Build Coastguard Worker // An alias for `size()`, returning the number of characters in the string. length()153*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr size_t length() const noexcept { return len_; } 154*6777b538SAndroid Build Coastguard Worker 155*6777b538SAndroid Build Coastguard Worker // Returns whether the cstring view is for an empty string. When empty, it is 156*6777b538SAndroid Build Coastguard Worker // pointing to a cstring that contains only a NUL character. empty()157*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr bool empty() const noexcept { return len_ == 0u; } 158*6777b538SAndroid Build Coastguard Worker 159*6777b538SAndroid Build Coastguard Worker // Returns the maximum number of characters that can be represented inside the 160*6777b538SAndroid Build Coastguard Worker // cstring view for character type `Char`. 161*6777b538SAndroid Build Coastguard Worker // 162*6777b538SAndroid Build Coastguard Worker // This is the number of `Char` objects that can fit inside an addressable 163*6777b538SAndroid Build Coastguard Worker // byte array. Since the number of bytes allowed is fixed, the number returned 164*6777b538SAndroid Build Coastguard Worker // is smaller when the `Char` is a larger type. max_size()165*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr size_t max_size() const noexcept { 166*6777b538SAndroid Build Coastguard Worker return static_cast<size_t>(-1) / sizeof(Char); 167*6777b538SAndroid Build Coastguard Worker } 168*6777b538SAndroid Build Coastguard Worker 169*6777b538SAndroid Build Coastguard Worker // Returns the number of bytes in the string, not including the terminating 170*6777b538SAndroid Build Coastguard Worker // NUL. To include the NUL, add `sizeof(Char)` where `Char` is the character 171*6777b538SAndroid Build Coastguard Worker // type of the cstring view (accessible as the `value_type` alias). size_bytes()172*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr size_t size_bytes() const noexcept { 173*6777b538SAndroid Build Coastguard Worker return len_ * sizeof(Char); 174*6777b538SAndroid Build Coastguard Worker } 175*6777b538SAndroid Build Coastguard Worker 176*6777b538SAndroid Build Coastguard Worker // Produces an iterator over the cstring view, excluding the terminating NUL. begin()177*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const iterator begin() const noexcept { 178*6777b538SAndroid Build Coastguard Worker // SAFETY: `ptr_ + len_` for a cstring view always gives a pointer in 179*6777b538SAndroid Build Coastguard Worker // the same allocation as `ptr_` based on the precondition of 180*6777b538SAndroid Build Coastguard Worker // the type. 181*6777b538SAndroid Build Coastguard Worker return UNSAFE_BUFFERS(iterator(ptr_, ptr_ + len_)); 182*6777b538SAndroid Build Coastguard Worker } 183*6777b538SAndroid Build Coastguard Worker // Produces an iterator over the cstring view, excluding the terminating NUL. end()184*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const iterator end() const noexcept { 185*6777b538SAndroid Build Coastguard Worker // SAFETY: `ptr_ + len_` for a cstring view always gives a pointer in 186*6777b538SAndroid Build Coastguard Worker // the same allocation as `ptr_` based on the precondition of 187*6777b538SAndroid Build Coastguard Worker // the type. 188*6777b538SAndroid Build Coastguard Worker return UNSAFE_BUFFERS(iterator(ptr_, ptr_ + len_, ptr_ + len_)); 189*6777b538SAndroid Build Coastguard Worker } 190*6777b538SAndroid Build Coastguard Worker // Produces an iterator over the cstring view, excluding the terminating NUL. cbegin()191*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const const_iterator cbegin() const noexcept { 192*6777b538SAndroid Build Coastguard Worker return begin(); 193*6777b538SAndroid Build Coastguard Worker } 194*6777b538SAndroid Build Coastguard Worker // Produces an iterator over the cstring view, excluding the terminating NUL. cend()195*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const const_iterator cend() const noexcept { 196*6777b538SAndroid Build Coastguard Worker return end(); 197*6777b538SAndroid Build Coastguard Worker } 198*6777b538SAndroid Build Coastguard Worker 199*6777b538SAndroid Build Coastguard Worker // Produces a reverse iterator over the cstring view, excluding the 200*6777b538SAndroid Build Coastguard Worker // terminating NUL. rbegin()201*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const reverse_iterator rbegin() const noexcept { 202*6777b538SAndroid Build Coastguard Worker return std::reverse_iterator(end()); 203*6777b538SAndroid Build Coastguard Worker } 204*6777b538SAndroid Build Coastguard Worker // Produces a reverse iterator over the cstring view, excluding the 205*6777b538SAndroid Build Coastguard Worker // terminating NUL. rend()206*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const reverse_iterator rend() const noexcept { 207*6777b538SAndroid Build Coastguard Worker return std::reverse_iterator(begin()); 208*6777b538SAndroid Build Coastguard Worker } 209*6777b538SAndroid Build Coastguard Worker // Produces a reverse iterator over the cstring view, excluding the 210*6777b538SAndroid Build Coastguard Worker // terminating NUL. rcbegin()211*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const const_reverse_iterator rcbegin() 212*6777b538SAndroid Build Coastguard Worker const noexcept { 213*6777b538SAndroid Build Coastguard Worker return std::reverse_iterator(cend()); 214*6777b538SAndroid Build Coastguard Worker } 215*6777b538SAndroid Build Coastguard Worker // Produces a reverse iterator over the cstring view, excluding the 216*6777b538SAndroid Build Coastguard Worker // terminating NUL. rcend()217*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const const_reverse_iterator rcend() const noexcept { 218*6777b538SAndroid Build Coastguard Worker return std::reverse_iterator(cbegin()); 219*6777b538SAndroid Build Coastguard Worker } 220*6777b538SAndroid Build Coastguard Worker 221*6777b538SAndroid Build Coastguard Worker // Returns the character at offset `idx`. 222*6777b538SAndroid Build Coastguard Worker // 223*6777b538SAndroid Build Coastguard Worker // This can be used to access any character in the ctring, as well as the NUL 224*6777b538SAndroid Build Coastguard Worker // terminator. 225*6777b538SAndroid Build Coastguard Worker // 226*6777b538SAndroid Build Coastguard Worker // # Checks 227*6777b538SAndroid Build Coastguard Worker // The function CHECKs that the `idx` is inside the cstring (including at its 228*6777b538SAndroid Build Coastguard Worker // NUL terminator) and will terminate otherwise. 229*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const Char& operator[](size_t idx) const noexcept { 230*6777b538SAndroid Build Coastguard Worker CHECK_LE(idx, len_); 231*6777b538SAndroid Build Coastguard Worker // SAFETY: `ptr_` points `len_` many elements plus a NUL terminator, and 232*6777b538SAndroid Build Coastguard Worker // `idx <= len_`, so `idx` is in range for `ptr_`. 233*6777b538SAndroid Build Coastguard Worker return UNSAFE_BUFFERS(ptr_[idx]); 234*6777b538SAndroid Build Coastguard Worker } 235*6777b538SAndroid Build Coastguard Worker 236*6777b538SAndroid Build Coastguard Worker // A named function that performs the same as `operator[]`. at(size_t idx)237*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const Char& at(size_t idx) const noexcept { 238*6777b538SAndroid Build Coastguard Worker return (*this)[idx]; 239*6777b538SAndroid Build Coastguard Worker } 240*6777b538SAndroid Build Coastguard Worker 241*6777b538SAndroid Build Coastguard Worker // Returns the first character in the cstring view. 242*6777b538SAndroid Build Coastguard Worker // 243*6777b538SAndroid Build Coastguard Worker // # Checks 244*6777b538SAndroid Build Coastguard Worker // The function CHECKs that the string is non-empty, and will terminate 245*6777b538SAndroid Build Coastguard Worker // otherwise. front()246*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const Char& front() const noexcept { 247*6777b538SAndroid Build Coastguard Worker CHECK(len_); 248*6777b538SAndroid Build Coastguard Worker // Since `len_ > 0`, 0 is a valid offset into the string contents. 249*6777b538SAndroid Build Coastguard Worker return UNSAFE_BUFFERS(ptr_[0u]); 250*6777b538SAndroid Build Coastguard Worker } 251*6777b538SAndroid Build Coastguard Worker 252*6777b538SAndroid Build Coastguard Worker // Returns the last (non-NUL) character in the cstring view. 253*6777b538SAndroid Build Coastguard Worker // 254*6777b538SAndroid Build Coastguard Worker // # Checks 255*6777b538SAndroid Build Coastguard Worker // The function CHECKs that the string is non-empty, and will terminate 256*6777b538SAndroid Build Coastguard Worker // otherwise. back()257*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr const Char& back() const noexcept { 258*6777b538SAndroid Build Coastguard Worker CHECK(len_); 259*6777b538SAndroid Build Coastguard Worker // Since `len_ > 0`, `len - 1` will not underflow. There are `len_` many 260*6777b538SAndroid Build Coastguard Worker // chars in the string before a NUL, so `len_ - 1` is in range of the string 261*6777b538SAndroid Build Coastguard Worker // contents. 262*6777b538SAndroid Build Coastguard Worker return UNSAFE_BUFFERS(ptr_[len_ - 1u]); 263*6777b538SAndroid Build Coastguard Worker } 264*6777b538SAndroid Build Coastguard Worker 265*6777b538SAndroid Build Coastguard Worker // Modifies the cstring view in place, moving the front ahead by `n` 266*6777b538SAndroid Build Coastguard Worker // characters. 267*6777b538SAndroid Build Coastguard Worker // 268*6777b538SAndroid Build Coastguard Worker // # Checks 269*6777b538SAndroid Build Coastguard Worker // The function CHECKs that `n <= size()`, and will terminate otherwise. remove_prefix(size_t n)270*6777b538SAndroid Build Coastguard Worker constexpr void remove_prefix(size_t n) noexcept { 271*6777b538SAndroid Build Coastguard Worker CHECK_LE(n, len_); 272*6777b538SAndroid Build Coastguard Worker // SAFETY: Since `n <= len_`, the pointer at offset `n` is inside the string 273*6777b538SAndroid Build Coastguard Worker // (or at the terminating NUL) and the `len_ - n` value will not underflow. 274*6777b538SAndroid Build Coastguard Worker // Thus the resulting pointer is still a NUL- terminated string of length 275*6777b538SAndroid Build Coastguard Worker // `len_ - n`. 276*6777b538SAndroid Build Coastguard Worker ptr_ = UNSAFE_BUFFERS(ptr_ + n); 277*6777b538SAndroid Build Coastguard Worker len_ = len_ - n; 278*6777b538SAndroid Build Coastguard Worker } 279*6777b538SAndroid Build Coastguard Worker 280*6777b538SAndroid Build Coastguard Worker // No `remove_suffix()` method exists as it would remove the terminating NUL 281*6777b538SAndroid Build Coastguard Worker // character. Convert to a `std::string_view` (either by construction or with 282*6777b538SAndroid Build Coastguard Worker // a `substr(0u)` call) to construct arbitrary substrings that are not 283*6777b538SAndroid Build Coastguard Worker // NUL-terminated. 284*6777b538SAndroid Build Coastguard Worker void remove_suffix(size_t n) = delete; 285*6777b538SAndroid Build Coastguard Worker 286*6777b538SAndroid Build Coastguard Worker // Modifies the cstring view in place, swapping its contents with another view 287*6777b538SAndroid Build Coastguard Worker // of the same type. swap(basic_cstring_view & other)288*6777b538SAndroid Build Coastguard Worker constexpr void swap(basic_cstring_view& other) noexcept { 289*6777b538SAndroid Build Coastguard Worker std::swap(ptr_, other.ptr_); 290*6777b538SAndroid Build Coastguard Worker std::swap(len_, other.len_); 291*6777b538SAndroid Build Coastguard Worker } 292*6777b538SAndroid Build Coastguard Worker 293*6777b538SAndroid Build Coastguard Worker // Returns a string view of the subrange starting as `pos` and including 294*6777b538SAndroid Build Coastguard Worker // `count` characters. If `count` is not specified, or exceeds the length of 295*6777b538SAndroid Build Coastguard Worker // the string after `pos`, the subrange returned will include all characters 296*6777b538SAndroid Build Coastguard Worker // up to the terminating NUL. 297*6777b538SAndroid Build Coastguard Worker // 298*6777b538SAndroid Build Coastguard Worker // # Checks 299*6777b538SAndroid Build Coastguard Worker // The function CHECKs that `pos` is in range for the string (or at the 300*6777b538SAndroid Build Coastguard Worker // terminating NULL), and will terminate otherwise. 301*6777b538SAndroid Build Coastguard Worker PURE_FUNCTION constexpr std::basic_string_view<Char> substr( 302*6777b538SAndroid Build Coastguard Worker size_t pos, 303*6777b538SAndroid Build Coastguard Worker size_t count = npos) const noexcept { 304*6777b538SAndroid Build Coastguard Worker // Ensure `ptr_ + pos` is valid. and `len_ - pos` does not underflow. 305*6777b538SAndroid Build Coastguard Worker CHECK_LE(pos, len_); 306*6777b538SAndroid Build Coastguard Worker // SAFETY: We require that: 307*6777b538SAndroid Build Coastguard Worker // * `ptr_ + pos` is a pointer in the string. 308*6777b538SAndroid Build Coastguard Worker // * `pos + count <= len_` so that resulting substring's end is in range. 309*6777b538SAndroid Build Coastguard Worker // 310*6777b538SAndroid Build Coastguard Worker // The first follows directly from the CHECK above that `pos <= len_`. The 311*6777b538SAndroid Build Coastguard Worker // second follows from clamping `count` to at most `len_ - pos`. 312*6777b538SAndroid Build Coastguard Worker return UNSAFE_BUFFERS( 313*6777b538SAndroid Build Coastguard Worker std::basic_string_view<Char>(ptr_ + pos, std::min(count, len_ - pos))); 314*6777b538SAndroid Build Coastguard Worker } 315*6777b538SAndroid Build Coastguard Worker 316*6777b538SAndroid Build Coastguard Worker // Returns whether the cstring view starts with the given `prefix`. Will 317*6777b538SAndroid Build Coastguard Worker // always return false if `prefix` is larger than the current cstring view. starts_with(std::basic_string_view<Char> prefix)318*6777b538SAndroid Build Coastguard Worker constexpr bool starts_with( 319*6777b538SAndroid Build Coastguard Worker std::basic_string_view<Char> prefix) const noexcept { 320*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).starts_with(prefix); 321*6777b538SAndroid Build Coastguard Worker } 322*6777b538SAndroid Build Coastguard Worker 323*6777b538SAndroid Build Coastguard Worker // Returns whether the cstring view starts with the given `character`. starts_with(Char character)324*6777b538SAndroid Build Coastguard Worker constexpr bool starts_with(Char character) const noexcept { 325*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).starts_with(character); 326*6777b538SAndroid Build Coastguard Worker } 327*6777b538SAndroid Build Coastguard Worker 328*6777b538SAndroid Build Coastguard Worker // Returns whether the cstring view ends with the given `suffix`. Will 329*6777b538SAndroid Build Coastguard Worker // always return false if `suffix` is larger than the current cstring view. ends_with(std::basic_string_view<Char> suffix)330*6777b538SAndroid Build Coastguard Worker constexpr bool ends_with(std::basic_string_view<Char> suffix) const noexcept { 331*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).ends_with(suffix); 332*6777b538SAndroid Build Coastguard Worker } 333*6777b538SAndroid Build Coastguard Worker 334*6777b538SAndroid Build Coastguard Worker // Returns whether the cstring view starts with the given `character`. ends_with(Char character)335*6777b538SAndroid Build Coastguard Worker constexpr bool ends_with(Char character) const noexcept { 336*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).ends_with(character); 337*6777b538SAndroid Build Coastguard Worker } 338*6777b538SAndroid Build Coastguard Worker 339*6777b538SAndroid Build Coastguard Worker // Returns the first position in the cstring view at which `search` is found, 340*6777b538SAndroid Build Coastguard Worker // starting from the offset `pos`. If `pos` is not specified, the entire 341*6777b538SAndroid Build Coastguard Worker // cstring view is searched. Returns `npos` if `search` is not found or if 342*6777b538SAndroid Build Coastguard Worker // `pos` is out of range. 343*6777b538SAndroid Build Coastguard Worker constexpr size_t find(std::basic_string_view<Char> search, 344*6777b538SAndroid Build Coastguard Worker size_t pos = 0u) const noexcept { 345*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find(search, pos); 346*6777b538SAndroid Build Coastguard Worker } 347*6777b538SAndroid Build Coastguard Worker constexpr size_t find(Char search, size_t pos = 0u) const noexcept { 348*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find(search, pos); 349*6777b538SAndroid Build Coastguard Worker } 350*6777b538SAndroid Build Coastguard Worker 351*6777b538SAndroid Build Coastguard Worker // Returns the last position in the cstring view at which `search` is found, 352*6777b538SAndroid Build Coastguard Worker // starting from the offset `pos`. If `pos` is not specified or is out of 353*6777b538SAndroid Build Coastguard Worker // range, the entire cstring view is searched. Returns `npos` if `search` is 354*6777b538SAndroid Build Coastguard Worker // not found. 355*6777b538SAndroid Build Coastguard Worker constexpr size_t rfind(std::basic_string_view<Char> search, 356*6777b538SAndroid Build Coastguard Worker size_t pos = npos) const noexcept { 357*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).rfind(search, pos); 358*6777b538SAndroid Build Coastguard Worker } 359*6777b538SAndroid Build Coastguard Worker constexpr size_t rfind(Char search, size_t pos = npos) const noexcept { 360*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).rfind(search, pos); 361*6777b538SAndroid Build Coastguard Worker } 362*6777b538SAndroid Build Coastguard Worker 363*6777b538SAndroid Build Coastguard Worker // Returns the first position in the cstring view at any character in the 364*6777b538SAndroid Build Coastguard Worker // `search` is found, starting from the offset `pos`. If `pos` is not 365*6777b538SAndroid Build Coastguard Worker // specified, the entire cstring view is searched. Returns `npos` if `search` 366*6777b538SAndroid Build Coastguard Worker // is not found or if `pos` is out of range. 367*6777b538SAndroid Build Coastguard Worker constexpr size_t find_first_of(std::basic_string_view<Char> search, 368*6777b538SAndroid Build Coastguard Worker size_t pos = 0u) const noexcept { 369*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find_first_of(search, pos); 370*6777b538SAndroid Build Coastguard Worker } 371*6777b538SAndroid Build Coastguard Worker constexpr size_t find_first_of(Char search, size_t pos = 0u) const noexcept { 372*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find_first_of(search, pos); 373*6777b538SAndroid Build Coastguard Worker } 374*6777b538SAndroid Build Coastguard Worker 375*6777b538SAndroid Build Coastguard Worker // Returns the last position in the cstring view at any character in the 376*6777b538SAndroid Build Coastguard Worker // `search` is found, starting from the offset `pos`. If `pos` is not 377*6777b538SAndroid Build Coastguard Worker // specified or is out of range, the entire cstring view is searched. Returns 378*6777b538SAndroid Build Coastguard Worker // `npos` if `search` is not found. 379*6777b538SAndroid Build Coastguard Worker constexpr size_t find_last_of(std::basic_string_view<Char> search, 380*6777b538SAndroid Build Coastguard Worker size_t pos = npos) const noexcept { 381*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find_last_of(search, pos); 382*6777b538SAndroid Build Coastguard Worker } 383*6777b538SAndroid Build Coastguard Worker constexpr size_t find_last_of(Char search, size_t pos = npos) const noexcept { 384*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find_last_of(search, pos); 385*6777b538SAndroid Build Coastguard Worker } 386*6777b538SAndroid Build Coastguard Worker 387*6777b538SAndroid Build Coastguard Worker // Returns the first position in the cstring view that is not equal to any 388*6777b538SAndroid Build Coastguard Worker // character in the `search`, starting from the offset `pos`. If `pos` is not 389*6777b538SAndroid Build Coastguard Worker // specified, the entire cstring view is searched. Returns `npos` if every 390*6777b538SAndroid Build Coastguard Worker // character is part of `search` or if `pos` is out of range. 391*6777b538SAndroid Build Coastguard Worker constexpr size_t find_first_not_of(std::basic_string_view<Char> search, 392*6777b538SAndroid Build Coastguard Worker size_t pos = 0u) const noexcept { 393*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find_first_not_of(search, pos); 394*6777b538SAndroid Build Coastguard Worker } 395*6777b538SAndroid Build Coastguard Worker constexpr size_t find_first_not_of(Char search, 396*6777b538SAndroid Build Coastguard Worker size_t pos = 0u) const noexcept { 397*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find_first_not_of(search, pos); 398*6777b538SAndroid Build Coastguard Worker } 399*6777b538SAndroid Build Coastguard Worker 400*6777b538SAndroid Build Coastguard Worker // Returns the last position in the cstring view that is not equal to any 401*6777b538SAndroid Build Coastguard Worker // character in the `search`, starting from the offset `pos`. If `pos` is not 402*6777b538SAndroid Build Coastguard Worker // specified or is out of range, the entire cstring view is searched. Returns 403*6777b538SAndroid Build Coastguard Worker // `npos` if every character is part of `search`. 404*6777b538SAndroid Build Coastguard Worker constexpr size_t find_last_not_of(std::basic_string_view<Char> search, 405*6777b538SAndroid Build Coastguard Worker size_t pos = npos) const noexcept { 406*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find_last_not_of(search, pos); 407*6777b538SAndroid Build Coastguard Worker } 408*6777b538SAndroid Build Coastguard Worker constexpr size_t find_last_not_of(Char search, 409*6777b538SAndroid Build Coastguard Worker size_t pos = npos) const noexcept { 410*6777b538SAndroid Build Coastguard Worker return std::basic_string_view<Char>(*this).find_last_not_of(search, pos); 411*6777b538SAndroid Build Coastguard Worker } 412*6777b538SAndroid Build Coastguard Worker 413*6777b538SAndroid Build Coastguard Worker // Compare two cstring views for equality, comparing the string contents. 414*6777b538SAndroid Build Coastguard Worker friend constexpr bool operator==(basic_cstring_view l, basic_cstring_view r) { 415*6777b538SAndroid Build Coastguard Worker return std::ranges::equal(l, r); 416*6777b538SAndroid Build Coastguard Worker } 417*6777b538SAndroid Build Coastguard Worker 418*6777b538SAndroid Build Coastguard Worker // Return an ordering between two cstring views, comparing the string 419*6777b538SAndroid Build Coastguard Worker // contents. 420*6777b538SAndroid Build Coastguard Worker // 421*6777b538SAndroid Build Coastguard Worker // cstring views are weakly ordered, since string views pointing into 422*6777b538SAndroid Build Coastguard Worker // different strings can compare as equal. 423*6777b538SAndroid Build Coastguard Worker friend constexpr std::weak_ordering operator<=>(basic_cstring_view l, 424*6777b538SAndroid Build Coastguard Worker basic_cstring_view r) { 425*6777b538SAndroid Build Coastguard Worker return std::lexicographical_compare_three_way(l.begin(), l.end(), r.begin(), 426*6777b538SAndroid Build Coastguard Worker r.end()); 427*6777b538SAndroid Build Coastguard Worker } 428*6777b538SAndroid Build Coastguard Worker 429*6777b538SAndroid Build Coastguard Worker // Implicitly converts from cstring_view to a non-NUL-terminated 430*6777b538SAndroid Build Coastguard Worker // std::string_view. The std::string_view type implicitly constructs from 431*6777b538SAndroid Build Coastguard Worker // `const char*` and cstring view is meant to replace the latter, so this acts 432*6777b538SAndroid Build Coastguard Worker // like an implicit constructor on `std::string_view` for cstring views. 433*6777b538SAndroid Build Coastguard Worker // 434*6777b538SAndroid Build Coastguard Worker // This operator also avoids a requirement on having overloads for both 435*6777b538SAndroid Build Coastguard Worker // std::string_view and cstring_view. Such overloads are ambiguous because 436*6777b538SAndroid Build Coastguard Worker // both can construct from a character array. 437*6777b538SAndroid Build Coastguard Worker // 438*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-explicit-constructor) 439*6777b538SAndroid Build Coastguard Worker constexpr operator std::basic_string_view<Char>() const noexcept { 440*6777b538SAndroid Build Coastguard Worker // SAFETY: The cstring view provides that `ptr_ + len_` to be valid. 441*6777b538SAndroid Build Coastguard Worker return UNSAFE_BUFFERS(std::basic_string_view<Char>(ptr_, len_)); 442*6777b538SAndroid Build Coastguard Worker } 443*6777b538SAndroid Build Coastguard Worker 444*6777b538SAndroid Build Coastguard Worker // Converts from cstring_view to std::string. This allocates a new string 445*6777b538SAndroid Build Coastguard Worker // backing and copies into it. 446*6777b538SAndroid Build Coastguard Worker // 447*6777b538SAndroid Build Coastguard Worker // The std::string type implicitly constructs from `const char*` however it 448*6777b538SAndroid Build Coastguard Worker // does not implicitly construct from std::string_view. This type sits between 449*6777b538SAndroid Build Coastguard Worker // these two, and opts towards making heap allocations explicit by requiring 450*6777b538SAndroid Build Coastguard Worker // an explicit conversion. 451*6777b538SAndroid Build Coastguard Worker constexpr explicit operator std::basic_string<Char>() const noexcept { 452*6777b538SAndroid Build Coastguard Worker // SAFETY: The cstring view provides that `ptr_ + len_` to be valid. 453*6777b538SAndroid Build Coastguard Worker return UNSAFE_BUFFERS(std::basic_string<Char>(ptr_, len_)); 454*6777b538SAndroid Build Coastguard Worker } 455*6777b538SAndroid Build Coastguard Worker 456*6777b538SAndroid Build Coastguard Worker // Concatenate a std::string with a cstring_view to produce another 457*6777b538SAndroid Build Coastguard Worker // std::string. 458*6777b538SAndroid Build Coastguard Worker // 459*6777b538SAndroid Build Coastguard Worker // These act like overloads on `std::string` that work for concatenating 460*6777b538SAndroid Build Coastguard Worker // `std::string` and `const char*`. 461*6777b538SAndroid Build Coastguard Worker // 462*6777b538SAndroid Build Coastguard Worker // The rvalue overloads allow `std::string` to reuse existing capacity, by 463*6777b538SAndroid Build Coastguard Worker // calling through to the rvalue overloads on `std::string`. 464*6777b538SAndroid Build Coastguard Worker template <class Traits, class Alloc> 465*6777b538SAndroid Build Coastguard Worker friend constexpr std::basic_string<Char, Traits, Alloc> operator+( 466*6777b538SAndroid Build Coastguard Worker basic_cstring_view lhs, 467*6777b538SAndroid Build Coastguard Worker const std::basic_string<Char, Traits, Alloc>& rhs) { 468*6777b538SAndroid Build Coastguard Worker return lhs.c_str() + rhs; 469*6777b538SAndroid Build Coastguard Worker } 470*6777b538SAndroid Build Coastguard Worker template <class Traits, class Alloc> 471*6777b538SAndroid Build Coastguard Worker friend constexpr std::basic_string<Char, Traits, Alloc> operator+( 472*6777b538SAndroid Build Coastguard Worker basic_cstring_view lhs, 473*6777b538SAndroid Build Coastguard Worker std::basic_string<Char, Traits, Alloc>&& rhs) { 474*6777b538SAndroid Build Coastguard Worker return lhs.c_str() + std::move(rhs); 475*6777b538SAndroid Build Coastguard Worker } 476*6777b538SAndroid Build Coastguard Worker template <class Traits, class Alloc> 477*6777b538SAndroid Build Coastguard Worker friend constexpr std::basic_string<Char, Traits, Alloc> operator+( 478*6777b538SAndroid Build Coastguard Worker const std::basic_string<Char, Traits, Alloc>& lhs, 479*6777b538SAndroid Build Coastguard Worker basic_cstring_view rhs) { 480*6777b538SAndroid Build Coastguard Worker return lhs + rhs.c_str(); 481*6777b538SAndroid Build Coastguard Worker } 482*6777b538SAndroid Build Coastguard Worker template <class Traits, class Alloc> 483*6777b538SAndroid Build Coastguard Worker friend constexpr std::basic_string<Char, Traits, Alloc> operator+( 484*6777b538SAndroid Build Coastguard Worker std::basic_string<Char, Traits, Alloc>&& lhs, 485*6777b538SAndroid Build Coastguard Worker basic_cstring_view rhs) { 486*6777b538SAndroid Build Coastguard Worker return std::move(lhs) + rhs.c_str(); 487*6777b538SAndroid Build Coastguard Worker } 488*6777b538SAndroid Build Coastguard Worker 489*6777b538SAndroid Build Coastguard Worker private: 490*6777b538SAndroid Build Coastguard Worker // An empty string literal for the `Char` type. 491*6777b538SAndroid Build Coastguard Worker static constexpr Char kEmpty[] = {Char{0}}; 492*6777b538SAndroid Build Coastguard Worker 493*6777b538SAndroid Build Coastguard Worker // An always-valid pointer (never null) to a NUL-terminated string. 494*6777b538SAndroid Build Coastguard Worker // 495*6777b538SAndroid Build Coastguard Worker // RAW_PTR_EXCLUSION: cstring_view is typically used on the stack as a local 496*6777b538SAndroid Build Coastguard Worker // variable/function parameter, so no raw_ptr is used here. 497*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION const Char* ptr_; 498*6777b538SAndroid Build Coastguard Worker // The number of characters between `ptr_` and the NUL terminator. 499*6777b538SAndroid Build Coastguard Worker // 500*6777b538SAndroid Build Coastguard Worker // SAFETY: `ptr_ + len_` is always valid since `len_` must not exceed the 501*6777b538SAndroid Build Coastguard Worker // number of characters in the allocation, or it would no longer indicate the 502*6777b538SAndroid Build Coastguard Worker // position of the NUL terminator in the string allocation. 503*6777b538SAndroid Build Coastguard Worker size_t len_; 504*6777b538SAndroid Build Coastguard Worker }; 505*6777b538SAndroid Build Coastguard Worker 506*6777b538SAndroid Build Coastguard Worker // cstring_view provides a view of a NUL-terminated string. It is a replacement 507*6777b538SAndroid Build Coastguard Worker // for all use of `const char*`, in order to provide bounds checks and prevent 508*6777b538SAndroid Build Coastguard Worker // unsafe pointer usage (otherwise prevented by `-Wunsafe-buffer-usage`). 509*6777b538SAndroid Build Coastguard Worker // 510*6777b538SAndroid Build Coastguard Worker // See basic_cstring_view for more. 511*6777b538SAndroid Build Coastguard Worker using cstring_view = basic_cstring_view<char>; 512*6777b538SAndroid Build Coastguard Worker 513*6777b538SAndroid Build Coastguard Worker // u16cstring_view provides a view of a NUL-terminated string. It is a 514*6777b538SAndroid Build Coastguard Worker // replacement for all use of `const char16_t*`, in order to provide bounds 515*6777b538SAndroid Build Coastguard Worker // checks and prevent unsafe pointer usage (otherwise prevented by 516*6777b538SAndroid Build Coastguard Worker // `-Wunsafe-buffer-usage`). 517*6777b538SAndroid Build Coastguard Worker // 518*6777b538SAndroid Build Coastguard Worker // See basic_cstring_view for more. 519*6777b538SAndroid Build Coastguard Worker using u16cstring_view = basic_cstring_view<char16_t>; 520*6777b538SAndroid Build Coastguard Worker 521*6777b538SAndroid Build Coastguard Worker // u32cstring_view provides a view of a NUL-terminated string. It is a 522*6777b538SAndroid Build Coastguard Worker // replacement for all use of `const char32_t*`, in order to provide bounds 523*6777b538SAndroid Build Coastguard Worker // checks and prevent unsafe pointer usage (otherwise prevented by 524*6777b538SAndroid Build Coastguard Worker // `-Wunsafe-buffer-usage`). 525*6777b538SAndroid Build Coastguard Worker // 526*6777b538SAndroid Build Coastguard Worker // See basic_cstring_view for more. 527*6777b538SAndroid Build Coastguard Worker using u32cstring_view = basic_cstring_view<char32_t>; 528*6777b538SAndroid Build Coastguard Worker 529*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) 530*6777b538SAndroid Build Coastguard Worker // wcstring_view provides a view of a NUL-terminated string. It is a 531*6777b538SAndroid Build Coastguard Worker // replacement for all use of `const wchar_t*`, in order to provide bounds 532*6777b538SAndroid Build Coastguard Worker // checks and prevent unsafe pointer usage (otherwise prevented by 533*6777b538SAndroid Build Coastguard Worker // `-Wunsafe-buffer-usage`). 534*6777b538SAndroid Build Coastguard Worker // 535*6777b538SAndroid Build Coastguard Worker // See basic_cstring_view for more. 536*6777b538SAndroid Build Coastguard Worker using wcstring_view = basic_cstring_view<wchar_t>; 537*6777b538SAndroid Build Coastguard Worker #endif 538*6777b538SAndroid Build Coastguard Worker 539*6777b538SAndroid Build Coastguard Worker // Writes the contents of the cstring view to the stream. 540*6777b538SAndroid Build Coastguard Worker template <class Char, class Traits> 541*6777b538SAndroid Build Coastguard Worker std::basic_ostream<Char, Traits>& operator<<( 542*6777b538SAndroid Build Coastguard Worker std::basic_ostream<Char, Traits>& os, 543*6777b538SAndroid Build Coastguard Worker basic_cstring_view<Char> view) { 544*6777b538SAndroid Build Coastguard Worker return os << std::basic_string_view<Char>(view); 545*6777b538SAndroid Build Coastguard Worker } 546*6777b538SAndroid Build Coastguard Worker 547*6777b538SAndroid Build Coastguard Worker } // namespace base 548*6777b538SAndroid Build Coastguard Worker 549*6777b538SAndroid Build Coastguard Worker template <class Char> 550*6777b538SAndroid Build Coastguard Worker struct std::hash<base::basic_cstring_view<Char>> { 551*6777b538SAndroid Build Coastguard Worker size_t operator()(const base::basic_cstring_view<Char>& t) const noexcept { 552*6777b538SAndroid Build Coastguard Worker return std::hash<std::basic_string_view<Char>>()(t); 553*6777b538SAndroid Build Coastguard Worker } 554*6777b538SAndroid Build Coastguard Worker }; 555*6777b538SAndroid Build Coastguard Worker 556*6777b538SAndroid Build Coastguard Worker template <class Char> 557*6777b538SAndroid Build Coastguard Worker inline constexpr bool 558*6777b538SAndroid Build Coastguard Worker std::ranges::enable_borrowed_range<base::basic_cstring_view<Char>> = true; 559*6777b538SAndroid Build Coastguard Worker 560*6777b538SAndroid Build Coastguard Worker template <class Char> 561*6777b538SAndroid Build Coastguard Worker inline constexpr bool std::ranges::enable_view<base::basic_cstring_view<Char>> = 562*6777b538SAndroid Build Coastguard Worker true; 563*6777b538SAndroid Build Coastguard Worker 564*6777b538SAndroid Build Coastguard Worker #endif // BASE_STRINGS_CSTRING_VIEW_H_ 565