xref: /aosp_15_r20/external/pytorch/c10/util/string_view.h (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker #pragma once
2*da0073e9SAndroid Build Coastguard Worker 
3*da0073e9SAndroid Build Coastguard Worker #include <algorithm>
4*da0073e9SAndroid Build Coastguard Worker #include <cstddef>
5*da0073e9SAndroid Build Coastguard Worker #include <cstring>
6*da0073e9SAndroid Build Coastguard Worker #include <functional>
7*da0073e9SAndroid Build Coastguard Worker #include <iterator>
8*da0073e9SAndroid Build Coastguard Worker #include <limits>
9*da0073e9SAndroid Build Coastguard Worker #include <ostream>
10*da0073e9SAndroid Build Coastguard Worker #include <stdexcept>
11*da0073e9SAndroid Build Coastguard Worker #include <string>
12*da0073e9SAndroid Build Coastguard Worker #include <string_view>
13*da0073e9SAndroid Build Coastguard Worker 
14*da0073e9SAndroid Build Coastguard Worker #include <c10/macros/Macros.h>
15*da0073e9SAndroid Build Coastguard Worker 
16*da0073e9SAndroid Build Coastguard Worker namespace c10 {
17*da0073e9SAndroid Build Coastguard Worker 
18*da0073e9SAndroid Build Coastguard Worker /**
19*da0073e9SAndroid Build Coastguard Worker  * Port of std::string_view with methods from C++20.
20*da0073e9SAndroid Build Coastguard Worker  * Implemented following the interface definition in
21*da0073e9SAndroid Build Coastguard Worker  * https://en.cppreference.com/w/cpp/string/basic_string_view
22*da0073e9SAndroid Build Coastguard Worker  * See there for the API documentation.
23*da0073e9SAndroid Build Coastguard Worker  *
24*da0073e9SAndroid Build Coastguard Worker  * Difference: We don't have a Traits template parameter because
25*da0073e9SAndroid Build Coastguard Worker  * std::char_traits isn't constexpr and we'd have to reimplement
26*da0073e9SAndroid Build Coastguard Worker  * std::char_traits if we wanted to use it with our constexpr basic_string_view.
27*da0073e9SAndroid Build Coastguard Worker  */
28*da0073e9SAndroid Build Coastguard Worker template <class CharT>
29*da0073e9SAndroid Build Coastguard Worker class basic_string_view final {
30*da0073e9SAndroid Build Coastguard Worker  public:
31*da0073e9SAndroid Build Coastguard Worker   using value_type = CharT;
32*da0073e9SAndroid Build Coastguard Worker   using pointer = CharT*;
33*da0073e9SAndroid Build Coastguard Worker   using const_pointer = const CharT*;
34*da0073e9SAndroid Build Coastguard Worker   using reference = CharT&;
35*da0073e9SAndroid Build Coastguard Worker   using const_reference = const CharT&;
36*da0073e9SAndroid Build Coastguard Worker   using const_iterator = const CharT*;
37*da0073e9SAndroid Build Coastguard Worker   using iterator = const_iterator;
38*da0073e9SAndroid Build Coastguard Worker   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
39*da0073e9SAndroid Build Coastguard Worker   using reverse_iterator = const_reverse_iterator;
40*da0073e9SAndroid Build Coastguard Worker   using size_type = std::size_t;
41*da0073e9SAndroid Build Coastguard Worker   using difference_type = std::ptrdiff_t;
42*da0073e9SAndroid Build Coastguard Worker 
43*da0073e9SAndroid Build Coastguard Worker   static constexpr size_type npos = size_type(-1);
44*da0073e9SAndroid Build Coastguard Worker 
basic_string_view()45*da0073e9SAndroid Build Coastguard Worker   constexpr basic_string_view() noexcept : begin_(nullptr) {}
46*da0073e9SAndroid Build Coastguard Worker 
basic_string_view(const_pointer str,size_type count)47*da0073e9SAndroid Build Coastguard Worker   explicit constexpr basic_string_view(const_pointer str, size_type count)
48*da0073e9SAndroid Build Coastguard Worker       : begin_(str), size_(count) {}
49*da0073e9SAndroid Build Coastguard Worker 
basic_string_view(const_pointer str)50*da0073e9SAndroid Build Coastguard Worker   /* implicit */ constexpr basic_string_view(const_pointer str)
51*da0073e9SAndroid Build Coastguard Worker       : basic_string_view(str, strlen_(str)) {}
52*da0073e9SAndroid Build Coastguard Worker 
basic_string_view(const::std::basic_string<CharT> & str)53*da0073e9SAndroid Build Coastguard Worker   /* implicit */ basic_string_view(const ::std::basic_string<CharT>& str)
54*da0073e9SAndroid Build Coastguard Worker       : basic_string_view(str.data(), str.size()) {}
55*da0073e9SAndroid Build Coastguard Worker 
56*da0073e9SAndroid Build Coastguard Worker   constexpr basic_string_view(const basic_string_view&) noexcept = default;
57*da0073e9SAndroid Build Coastguard Worker 
58*da0073e9SAndroid Build Coastguard Worker   constexpr basic_string_view& operator=(
59*da0073e9SAndroid Build Coastguard Worker       const basic_string_view& rhs) noexcept {
60*da0073e9SAndroid Build Coastguard Worker     begin_ = rhs.begin_;
61*da0073e9SAndroid Build Coastguard Worker     size_ = rhs.size_;
62*da0073e9SAndroid Build Coastguard Worker     return *this;
63*da0073e9SAndroid Build Coastguard Worker   }
64*da0073e9SAndroid Build Coastguard Worker 
65*da0073e9SAndroid Build Coastguard Worker   explicit operator ::std::basic_string<CharT>() const {
66*da0073e9SAndroid Build Coastguard Worker     return ::std::basic_string<CharT>(data(), size());
67*da0073e9SAndroid Build Coastguard Worker   }
68*da0073e9SAndroid Build Coastguard Worker 
begin()69*da0073e9SAndroid Build Coastguard Worker   constexpr const_iterator begin() const noexcept {
70*da0073e9SAndroid Build Coastguard Worker     return cbegin();
71*da0073e9SAndroid Build Coastguard Worker   }
72*da0073e9SAndroid Build Coastguard Worker 
cbegin()73*da0073e9SAndroid Build Coastguard Worker   constexpr const_iterator cbegin() const noexcept {
74*da0073e9SAndroid Build Coastguard Worker     return begin_;
75*da0073e9SAndroid Build Coastguard Worker   }
76*da0073e9SAndroid Build Coastguard Worker 
end()77*da0073e9SAndroid Build Coastguard Worker   constexpr const_iterator end() const noexcept {
78*da0073e9SAndroid Build Coastguard Worker     return cend();
79*da0073e9SAndroid Build Coastguard Worker   }
80*da0073e9SAndroid Build Coastguard Worker 
cend()81*da0073e9SAndroid Build Coastguard Worker   constexpr const_iterator cend() const noexcept {
82*da0073e9SAndroid Build Coastguard Worker     return begin_ + size_;
83*da0073e9SAndroid Build Coastguard Worker   }
84*da0073e9SAndroid Build Coastguard Worker 
rbegin()85*da0073e9SAndroid Build Coastguard Worker   constexpr const_reverse_iterator rbegin() const noexcept {
86*da0073e9SAndroid Build Coastguard Worker     return crbegin();
87*da0073e9SAndroid Build Coastguard Worker   }
88*da0073e9SAndroid Build Coastguard Worker 
crbegin()89*da0073e9SAndroid Build Coastguard Worker   constexpr const_reverse_iterator crbegin() const noexcept {
90*da0073e9SAndroid Build Coastguard Worker     return const_reverse_iterator(this->end());
91*da0073e9SAndroid Build Coastguard Worker   }
92*da0073e9SAndroid Build Coastguard Worker 
rend()93*da0073e9SAndroid Build Coastguard Worker   constexpr const_reverse_iterator rend() const noexcept {
94*da0073e9SAndroid Build Coastguard Worker     return crend();
95*da0073e9SAndroid Build Coastguard Worker   }
96*da0073e9SAndroid Build Coastguard Worker 
crend()97*da0073e9SAndroid Build Coastguard Worker   constexpr const_reverse_iterator crend() const noexcept {
98*da0073e9SAndroid Build Coastguard Worker     return const_reverse_iterator(this->begin());
99*da0073e9SAndroid Build Coastguard Worker   }
100*da0073e9SAndroid Build Coastguard Worker 
begin(basic_string_view sv)101*da0073e9SAndroid Build Coastguard Worker   friend constexpr const_iterator begin(basic_string_view sv) noexcept {
102*da0073e9SAndroid Build Coastguard Worker     return sv.begin();
103*da0073e9SAndroid Build Coastguard Worker   }
104*da0073e9SAndroid Build Coastguard Worker 
end(basic_string_view sv)105*da0073e9SAndroid Build Coastguard Worker   friend constexpr const_iterator end(basic_string_view sv) noexcept {
106*da0073e9SAndroid Build Coastguard Worker     return sv.end();
107*da0073e9SAndroid Build Coastguard Worker   }
108*da0073e9SAndroid Build Coastguard Worker 
109*da0073e9SAndroid Build Coastguard Worker   constexpr const_reference operator[](size_type pos) const {
110*da0073e9SAndroid Build Coastguard Worker     // TODO: split out
111*da0073e9SAndroid Build Coastguard Worker     return at_(pos);
112*da0073e9SAndroid Build Coastguard Worker   }
113*da0073e9SAndroid Build Coastguard Worker 
at(size_type pos)114*da0073e9SAndroid Build Coastguard Worker   constexpr const_reference at(size_type pos) const {
115*da0073e9SAndroid Build Coastguard Worker #if !defined( \
116*da0073e9SAndroid Build Coastguard Worker     __CUDA_ARCH__) // CUDA doesn't like std::out_of_range in device code
117*da0073e9SAndroid Build Coastguard Worker     return C10_UNLIKELY(pos >= size_)
118*da0073e9SAndroid Build Coastguard Worker         ? (throw std::out_of_range(
119*da0073e9SAndroid Build Coastguard Worker                "string_view::operator[] or string_view::at() out of range. Index: " +
120*da0073e9SAndroid Build Coastguard Worker                std::to_string(pos) + ", size: " + std::to_string(size())),
121*da0073e9SAndroid Build Coastguard Worker            at_(0))
122*da0073e9SAndroid Build Coastguard Worker         : at_(pos);
123*da0073e9SAndroid Build Coastguard Worker #else
124*da0073e9SAndroid Build Coastguard Worker     return at_(pos);
125*da0073e9SAndroid Build Coastguard Worker #endif
126*da0073e9SAndroid Build Coastguard Worker   }
127*da0073e9SAndroid Build Coastguard Worker 
front()128*da0073e9SAndroid Build Coastguard Worker   constexpr const_reference front() const {
129*da0073e9SAndroid Build Coastguard Worker     return *begin_;
130*da0073e9SAndroid Build Coastguard Worker   }
131*da0073e9SAndroid Build Coastguard Worker 
back()132*da0073e9SAndroid Build Coastguard Worker   constexpr const_reference back() const {
133*da0073e9SAndroid Build Coastguard Worker     return *(begin_ + size_ - 1);
134*da0073e9SAndroid Build Coastguard Worker   }
135*da0073e9SAndroid Build Coastguard Worker 
data()136*da0073e9SAndroid Build Coastguard Worker   constexpr const_pointer data() const noexcept {
137*da0073e9SAndroid Build Coastguard Worker     return begin_;
138*da0073e9SAndroid Build Coastguard Worker   }
139*da0073e9SAndroid Build Coastguard Worker 
size()140*da0073e9SAndroid Build Coastguard Worker   constexpr size_type size() const noexcept {
141*da0073e9SAndroid Build Coastguard Worker     return size_;
142*da0073e9SAndroid Build Coastguard Worker   }
143*da0073e9SAndroid Build Coastguard Worker 
length()144*da0073e9SAndroid Build Coastguard Worker   constexpr size_type length() const noexcept {
145*da0073e9SAndroid Build Coastguard Worker     return size();
146*da0073e9SAndroid Build Coastguard Worker   }
147*da0073e9SAndroid Build Coastguard Worker 
max_size()148*da0073e9SAndroid Build Coastguard Worker   constexpr size_type max_size() const noexcept {
149*da0073e9SAndroid Build Coastguard Worker     return std::numeric_limits<difference_type>::max();
150*da0073e9SAndroid Build Coastguard Worker   }
151*da0073e9SAndroid Build Coastguard Worker 
empty()152*da0073e9SAndroid Build Coastguard Worker   C10_NODISCARD constexpr bool empty() const noexcept {
153*da0073e9SAndroid Build Coastguard Worker     return size() == 0;
154*da0073e9SAndroid Build Coastguard Worker   }
155*da0073e9SAndroid Build Coastguard Worker 
remove_prefix(size_type n)156*da0073e9SAndroid Build Coastguard Worker   constexpr void remove_prefix(size_type n) {
157*da0073e9SAndroid Build Coastguard Worker     if (n > size()) {
158*da0073e9SAndroid Build Coastguard Worker       throw std::out_of_range(
159*da0073e9SAndroid Build Coastguard Worker           "basic_string_view::remove_prefix: out of range. PrefixLength: " +
160*da0073e9SAndroid Build Coastguard Worker           std::to_string(n) + ", size: " + std::to_string(size()));
161*da0073e9SAndroid Build Coastguard Worker     }
162*da0073e9SAndroid Build Coastguard Worker     begin_ += n;
163*da0073e9SAndroid Build Coastguard Worker     size_ -= n;
164*da0073e9SAndroid Build Coastguard Worker   }
165*da0073e9SAndroid Build Coastguard Worker 
remove_suffix(size_type n)166*da0073e9SAndroid Build Coastguard Worker   constexpr void remove_suffix(size_type n) {
167*da0073e9SAndroid Build Coastguard Worker     if (n > size()) {
168*da0073e9SAndroid Build Coastguard Worker       throw std::out_of_range(
169*da0073e9SAndroid Build Coastguard Worker           "basic_string_view::remove_suffix: out of range. SuffixLength: " +
170*da0073e9SAndroid Build Coastguard Worker           std::to_string(n) + ", size: " + std::to_string(size()));
171*da0073e9SAndroid Build Coastguard Worker     }
172*da0073e9SAndroid Build Coastguard Worker     size_ -= n;
173*da0073e9SAndroid Build Coastguard Worker   }
174*da0073e9SAndroid Build Coastguard Worker 
swap(basic_string_view & sv)175*da0073e9SAndroid Build Coastguard Worker   constexpr void swap(basic_string_view& sv) noexcept {
176*da0073e9SAndroid Build Coastguard Worker     auto tmp = *this;
177*da0073e9SAndroid Build Coastguard Worker     *this = sv;
178*da0073e9SAndroid Build Coastguard Worker     sv = tmp;
179*da0073e9SAndroid Build Coastguard Worker   }
180*da0073e9SAndroid Build Coastguard Worker 
181*da0073e9SAndroid Build Coastguard Worker   size_type copy(pointer dest, size_type count, size_type pos = 0) const {
182*da0073e9SAndroid Build Coastguard Worker     if (pos > size_) {
183*da0073e9SAndroid Build Coastguard Worker       throw std::out_of_range(
184*da0073e9SAndroid Build Coastguard Worker           "basic_string_view::copy: out of range. Index: " +
185*da0073e9SAndroid Build Coastguard Worker           std::to_string(pos) + ", size: " + std::to_string(size()));
186*da0073e9SAndroid Build Coastguard Worker     }
187*da0073e9SAndroid Build Coastguard Worker     size_type copy_length = std::min(count, size_ - pos);
188*da0073e9SAndroid Build Coastguard Worker     for (auto iter = begin() + pos, end = iter + copy_length; iter != end;) {
189*da0073e9SAndroid Build Coastguard Worker       *(dest++) = *(iter++);
190*da0073e9SAndroid Build Coastguard Worker     }
191*da0073e9SAndroid Build Coastguard Worker     return copy_length;
192*da0073e9SAndroid Build Coastguard Worker   }
193*da0073e9SAndroid Build Coastguard Worker 
194*da0073e9SAndroid Build Coastguard Worker   constexpr basic_string_view substr(size_type pos = 0, size_type count = npos)
195*da0073e9SAndroid Build Coastguard Worker       const {
196*da0073e9SAndroid Build Coastguard Worker #if !defined( \
197*da0073e9SAndroid Build Coastguard Worker     __CUDA_ARCH__) // CUDA doesn't like std::out_of_range in device code
198*da0073e9SAndroid Build Coastguard Worker     return (pos > size_)
199*da0073e9SAndroid Build Coastguard Worker         ? (throw std::out_of_range(
200*da0073e9SAndroid Build Coastguard Worker                "basic_string_view::substr parameter out of bounds. Index: " +
201*da0073e9SAndroid Build Coastguard Worker                std::to_string(pos) + ", size: " + std::to_string(size())),
202*da0073e9SAndroid Build Coastguard Worker            substr_())
203*da0073e9SAndroid Build Coastguard Worker         : substr_(pos, count);
204*da0073e9SAndroid Build Coastguard Worker #else
205*da0073e9SAndroid Build Coastguard Worker     return substr_(pos, count);
206*da0073e9SAndroid Build Coastguard Worker #endif
207*da0073e9SAndroid Build Coastguard Worker   }
208*da0073e9SAndroid Build Coastguard Worker 
compare(basic_string_view rhs)209*da0073e9SAndroid Build Coastguard Worker   constexpr int compare(basic_string_view rhs) const noexcept {
210*da0073e9SAndroid Build Coastguard Worker     // Write it iteratively. This is faster.
211*da0073e9SAndroid Build Coastguard Worker     for (size_t i = 0, end = std::min(size(), rhs.size()); i < end; ++i) {
212*da0073e9SAndroid Build Coastguard Worker       if (at_(i) < rhs.at_(i)) {
213*da0073e9SAndroid Build Coastguard Worker         return -1;
214*da0073e9SAndroid Build Coastguard Worker       } else if (at_(i) > rhs.at_(i)) {
215*da0073e9SAndroid Build Coastguard Worker         return 1;
216*da0073e9SAndroid Build Coastguard Worker       }
217*da0073e9SAndroid Build Coastguard Worker     }
218*da0073e9SAndroid Build Coastguard Worker     if (size() < rhs.size()) {
219*da0073e9SAndroid Build Coastguard Worker       return -1;
220*da0073e9SAndroid Build Coastguard Worker     } else if (size() > rhs.size()) {
221*da0073e9SAndroid Build Coastguard Worker       return 1;
222*da0073e9SAndroid Build Coastguard Worker     }
223*da0073e9SAndroid Build Coastguard Worker     return 0;
224*da0073e9SAndroid Build Coastguard Worker   }
225*da0073e9SAndroid Build Coastguard Worker 
compare(size_type pos1,size_type count1,basic_string_view v)226*da0073e9SAndroid Build Coastguard Worker   constexpr int compare(size_type pos1, size_type count1, basic_string_view v)
227*da0073e9SAndroid Build Coastguard Worker       const {
228*da0073e9SAndroid Build Coastguard Worker     return substr(pos1, count1).compare(v);
229*da0073e9SAndroid Build Coastguard Worker   }
230*da0073e9SAndroid Build Coastguard Worker 
compare(size_type pos1,size_type count1,basic_string_view v,size_type pos2,size_type count2)231*da0073e9SAndroid Build Coastguard Worker   constexpr int compare(
232*da0073e9SAndroid Build Coastguard Worker       size_type pos1,
233*da0073e9SAndroid Build Coastguard Worker       size_type count1,
234*da0073e9SAndroid Build Coastguard Worker       basic_string_view v,
235*da0073e9SAndroid Build Coastguard Worker       size_type pos2,
236*da0073e9SAndroid Build Coastguard Worker       size_type count2) const {
237*da0073e9SAndroid Build Coastguard Worker     return substr(pos1, count1).compare(v.substr(pos2, count2));
238*da0073e9SAndroid Build Coastguard Worker   }
239*da0073e9SAndroid Build Coastguard Worker 
compare(const_pointer s)240*da0073e9SAndroid Build Coastguard Worker   constexpr int compare(const_pointer s) const {
241*da0073e9SAndroid Build Coastguard Worker     return compare(basic_string_view(s));
242*da0073e9SAndroid Build Coastguard Worker   }
243*da0073e9SAndroid Build Coastguard Worker 
compare(size_type pos1,size_type count1,const_pointer s)244*da0073e9SAndroid Build Coastguard Worker   constexpr int compare(size_type pos1, size_type count1, const_pointer s)
245*da0073e9SAndroid Build Coastguard Worker       const {
246*da0073e9SAndroid Build Coastguard Worker     return substr(pos1, count1).compare(basic_string_view(s));
247*da0073e9SAndroid Build Coastguard Worker   }
248*da0073e9SAndroid Build Coastguard Worker 
compare(size_type pos1,size_type count1,const_pointer s,size_type count2)249*da0073e9SAndroid Build Coastguard Worker   constexpr int compare(
250*da0073e9SAndroid Build Coastguard Worker       size_type pos1,
251*da0073e9SAndroid Build Coastguard Worker       size_type count1,
252*da0073e9SAndroid Build Coastguard Worker       const_pointer s,
253*da0073e9SAndroid Build Coastguard Worker       size_type count2) const {
254*da0073e9SAndroid Build Coastguard Worker     return substr(pos1, count1).compare(basic_string_view(s, count2));
255*da0073e9SAndroid Build Coastguard Worker   }
256*da0073e9SAndroid Build Coastguard Worker 
257*da0073e9SAndroid Build Coastguard Worker   friend constexpr bool operator==(
258*da0073e9SAndroid Build Coastguard Worker       basic_string_view lhs,
259*da0073e9SAndroid Build Coastguard Worker       basic_string_view rhs) noexcept {
260*da0073e9SAndroid Build Coastguard Worker     return lhs.equals_(rhs);
261*da0073e9SAndroid Build Coastguard Worker   }
262*da0073e9SAndroid Build Coastguard Worker 
263*da0073e9SAndroid Build Coastguard Worker   friend constexpr bool operator!=(
264*da0073e9SAndroid Build Coastguard Worker       basic_string_view lhs,
265*da0073e9SAndroid Build Coastguard Worker       basic_string_view rhs) noexcept {
266*da0073e9SAndroid Build Coastguard Worker     return !(lhs == rhs);
267*da0073e9SAndroid Build Coastguard Worker   }
268*da0073e9SAndroid Build Coastguard Worker 
269*da0073e9SAndroid Build Coastguard Worker   friend constexpr bool operator<(
270*da0073e9SAndroid Build Coastguard Worker       basic_string_view lhs,
271*da0073e9SAndroid Build Coastguard Worker       basic_string_view rhs) noexcept {
272*da0073e9SAndroid Build Coastguard Worker     return lhs.compare(rhs) < 0;
273*da0073e9SAndroid Build Coastguard Worker   }
274*da0073e9SAndroid Build Coastguard Worker 
275*da0073e9SAndroid Build Coastguard Worker   friend constexpr bool operator>=(
276*da0073e9SAndroid Build Coastguard Worker       basic_string_view lhs,
277*da0073e9SAndroid Build Coastguard Worker       basic_string_view rhs) noexcept {
278*da0073e9SAndroid Build Coastguard Worker     return !(lhs < rhs);
279*da0073e9SAndroid Build Coastguard Worker   }
280*da0073e9SAndroid Build Coastguard Worker 
281*da0073e9SAndroid Build Coastguard Worker   friend constexpr bool operator>(
282*da0073e9SAndroid Build Coastguard Worker       basic_string_view lhs,
283*da0073e9SAndroid Build Coastguard Worker       basic_string_view rhs) noexcept {
284*da0073e9SAndroid Build Coastguard Worker     return rhs < lhs;
285*da0073e9SAndroid Build Coastguard Worker   }
286*da0073e9SAndroid Build Coastguard Worker 
287*da0073e9SAndroid Build Coastguard Worker   friend constexpr bool operator<=(
288*da0073e9SAndroid Build Coastguard Worker       basic_string_view lhs,
289*da0073e9SAndroid Build Coastguard Worker       basic_string_view rhs) noexcept {
290*da0073e9SAndroid Build Coastguard Worker     return !(lhs > rhs);
291*da0073e9SAndroid Build Coastguard Worker   }
292*da0073e9SAndroid Build Coastguard Worker 
starts_with(basic_string_view prefix)293*da0073e9SAndroid Build Coastguard Worker   constexpr bool starts_with(basic_string_view prefix) const noexcept {
294*da0073e9SAndroid Build Coastguard Worker     return (prefix.size() > size()) ? false
295*da0073e9SAndroid Build Coastguard Worker                                     : prefix.equals_(substr_(0, prefix.size()));
296*da0073e9SAndroid Build Coastguard Worker   }
297*da0073e9SAndroid Build Coastguard Worker 
starts_with(CharT prefix)298*da0073e9SAndroid Build Coastguard Worker   constexpr bool starts_with(CharT prefix) const noexcept {
299*da0073e9SAndroid Build Coastguard Worker     return !empty() && prefix == front();
300*da0073e9SAndroid Build Coastguard Worker   }
301*da0073e9SAndroid Build Coastguard Worker 
starts_with(const_pointer prefix)302*da0073e9SAndroid Build Coastguard Worker   constexpr bool starts_with(const_pointer prefix) const {
303*da0073e9SAndroid Build Coastguard Worker     return starts_with(basic_string_view(prefix));
304*da0073e9SAndroid Build Coastguard Worker   }
305*da0073e9SAndroid Build Coastguard Worker 
ends_with(basic_string_view suffix)306*da0073e9SAndroid Build Coastguard Worker   constexpr bool ends_with(basic_string_view suffix) const noexcept {
307*da0073e9SAndroid Build Coastguard Worker     return (suffix.size() > size())
308*da0073e9SAndroid Build Coastguard Worker         ? false
309*da0073e9SAndroid Build Coastguard Worker         : suffix.equals_(substr_(size() - suffix.size(), suffix.size()));
310*da0073e9SAndroid Build Coastguard Worker   }
311*da0073e9SAndroid Build Coastguard Worker 
ends_with(CharT suffix)312*da0073e9SAndroid Build Coastguard Worker   constexpr bool ends_with(CharT suffix) const noexcept {
313*da0073e9SAndroid Build Coastguard Worker     return !empty() && suffix == back();
314*da0073e9SAndroid Build Coastguard Worker   }
315*da0073e9SAndroid Build Coastguard Worker 
ends_with(const_pointer suffix)316*da0073e9SAndroid Build Coastguard Worker   constexpr bool ends_with(const_pointer suffix) const {
317*da0073e9SAndroid Build Coastguard Worker     return ends_with(basic_string_view(suffix));
318*da0073e9SAndroid Build Coastguard Worker   }
319*da0073e9SAndroid Build Coastguard Worker 
320*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find(basic_string_view v, size_type pos = 0)
321*da0073e9SAndroid Build Coastguard Worker       const noexcept {
322*da0073e9SAndroid Build Coastguard Worker     if (v.size() == 0) {
323*da0073e9SAndroid Build Coastguard Worker       return pos <= size() ? pos : npos;
324*da0073e9SAndroid Build Coastguard Worker     }
325*da0073e9SAndroid Build Coastguard Worker 
326*da0073e9SAndroid Build Coastguard Worker     if (pos + v.size() <= size()) {
327*da0073e9SAndroid Build Coastguard Worker       for (size_type cur = pos, end = size() - v.size(); cur <= end; ++cur) {
328*da0073e9SAndroid Build Coastguard Worker         if (v.at_(0) == at_(cur) &&
329*da0073e9SAndroid Build Coastguard Worker             v.substr_(1).equals_(substr_(cur + 1, v.size() - 1))) {
330*da0073e9SAndroid Build Coastguard Worker           return cur;
331*da0073e9SAndroid Build Coastguard Worker         }
332*da0073e9SAndroid Build Coastguard Worker       }
333*da0073e9SAndroid Build Coastguard Worker     }
334*da0073e9SAndroid Build Coastguard Worker     return npos;
335*da0073e9SAndroid Build Coastguard Worker   }
336*da0073e9SAndroid Build Coastguard Worker 
337*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find(CharT ch, size_type pos = 0) const noexcept {
338*da0073e9SAndroid Build Coastguard Worker     return find_first_if_(pos, charIsEqual_{ch});
339*da0073e9SAndroid Build Coastguard Worker   }
340*da0073e9SAndroid Build Coastguard Worker 
find(const_pointer s,size_type pos,size_type count)341*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find(const_pointer s, size_type pos, size_type count)
342*da0073e9SAndroid Build Coastguard Worker       const {
343*da0073e9SAndroid Build Coastguard Worker     return find(basic_string_view(s, count), pos);
344*da0073e9SAndroid Build Coastguard Worker   }
345*da0073e9SAndroid Build Coastguard Worker 
346*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find(const_pointer s, size_type pos = 0) const {
347*da0073e9SAndroid Build Coastguard Worker     return find(basic_string_view(s), pos);
348*da0073e9SAndroid Build Coastguard Worker   }
349*da0073e9SAndroid Build Coastguard Worker 
350*da0073e9SAndroid Build Coastguard Worker   constexpr size_type rfind(basic_string_view v, size_type pos = npos)
351*da0073e9SAndroid Build Coastguard Worker       const noexcept {
352*da0073e9SAndroid Build Coastguard Worker     // Write it iteratively. This is faster.
353*da0073e9SAndroid Build Coastguard Worker     if (v.size() == 0) {
354*da0073e9SAndroid Build Coastguard Worker       return pos <= size() ? pos : size();
355*da0073e9SAndroid Build Coastguard Worker     }
356*da0073e9SAndroid Build Coastguard Worker 
357*da0073e9SAndroid Build Coastguard Worker     if (v.size() <= size()) {
358*da0073e9SAndroid Build Coastguard Worker       pos = std::min(size() - v.size(), pos);
359*da0073e9SAndroid Build Coastguard Worker       do {
360*da0073e9SAndroid Build Coastguard Worker         if (v.at_(0) == at_(pos) &&
361*da0073e9SAndroid Build Coastguard Worker             v.substr_(1).equals_(substr_(pos + 1, v.size() - 1))) {
362*da0073e9SAndroid Build Coastguard Worker           return pos;
363*da0073e9SAndroid Build Coastguard Worker         }
364*da0073e9SAndroid Build Coastguard Worker       } while (pos-- > 0);
365*da0073e9SAndroid Build Coastguard Worker     }
366*da0073e9SAndroid Build Coastguard Worker     return npos;
367*da0073e9SAndroid Build Coastguard Worker   }
368*da0073e9SAndroid Build Coastguard Worker 
369*da0073e9SAndroid Build Coastguard Worker   constexpr size_type rfind(CharT ch, size_type pos = npos) const noexcept {
370*da0073e9SAndroid Build Coastguard Worker     return find_last_if_(pos, charIsEqual_{ch});
371*da0073e9SAndroid Build Coastguard Worker   }
372*da0073e9SAndroid Build Coastguard Worker 
rfind(const_pointer s,size_type pos,size_type count)373*da0073e9SAndroid Build Coastguard Worker   constexpr size_type rfind(const_pointer s, size_type pos, size_type count)
374*da0073e9SAndroid Build Coastguard Worker       const {
375*da0073e9SAndroid Build Coastguard Worker     return rfind(basic_string_view(s, count), pos);
376*da0073e9SAndroid Build Coastguard Worker   }
377*da0073e9SAndroid Build Coastguard Worker 
378*da0073e9SAndroid Build Coastguard Worker   constexpr size_type rfind(const_pointer s, size_type pos = npos) const {
379*da0073e9SAndroid Build Coastguard Worker     return rfind(basic_string_view(s), pos);
380*da0073e9SAndroid Build Coastguard Worker   }
381*da0073e9SAndroid Build Coastguard Worker 
382*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_first_of(basic_string_view v, size_type pos = 0)
383*da0073e9SAndroid Build Coastguard Worker       const noexcept {
384*da0073e9SAndroid Build Coastguard Worker     return find_first_if_(pos, stringViewContainsChar_{v});
385*da0073e9SAndroid Build Coastguard Worker   }
386*da0073e9SAndroid Build Coastguard Worker 
387*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_first_of(CharT ch, size_type pos = 0)
388*da0073e9SAndroid Build Coastguard Worker       const noexcept {
389*da0073e9SAndroid Build Coastguard Worker     return find_first_if_(pos, charIsEqual_{ch});
390*da0073e9SAndroid Build Coastguard Worker   }
391*da0073e9SAndroid Build Coastguard Worker 
find_first_of(const_pointer s,size_type pos,size_type count)392*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_first_of(
393*da0073e9SAndroid Build Coastguard Worker       const_pointer s,
394*da0073e9SAndroid Build Coastguard Worker       size_type pos,
395*da0073e9SAndroid Build Coastguard Worker       size_type count) const {
396*da0073e9SAndroid Build Coastguard Worker     return find_first_of(basic_string_view(s, count), pos);
397*da0073e9SAndroid Build Coastguard Worker   }
398*da0073e9SAndroid Build Coastguard Worker 
399*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_first_of(const_pointer s, size_type pos = 0) const {
400*da0073e9SAndroid Build Coastguard Worker     return find_first_of(basic_string_view(s), pos);
401*da0073e9SAndroid Build Coastguard Worker   }
402*da0073e9SAndroid Build Coastguard Worker 
403*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_last_of(basic_string_view v, size_type pos = npos)
404*da0073e9SAndroid Build Coastguard Worker       const noexcept {
405*da0073e9SAndroid Build Coastguard Worker     return find_last_if_(pos, stringViewContainsChar_{v});
406*da0073e9SAndroid Build Coastguard Worker   }
407*da0073e9SAndroid Build Coastguard Worker 
408*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_last_of(CharT ch, size_type pos = npos)
409*da0073e9SAndroid Build Coastguard Worker       const noexcept {
410*da0073e9SAndroid Build Coastguard Worker     return find_last_if_(pos, charIsEqual_{ch});
411*da0073e9SAndroid Build Coastguard Worker   }
412*da0073e9SAndroid Build Coastguard Worker 
find_last_of(const_pointer s,size_type pos,size_type count)413*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_last_of(
414*da0073e9SAndroid Build Coastguard Worker       const_pointer s,
415*da0073e9SAndroid Build Coastguard Worker       size_type pos,
416*da0073e9SAndroid Build Coastguard Worker       size_type count) const {
417*da0073e9SAndroid Build Coastguard Worker     return find_last_of(basic_string_view(s, count), pos);
418*da0073e9SAndroid Build Coastguard Worker   }
419*da0073e9SAndroid Build Coastguard Worker 
420*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_last_of(const_pointer s, size_type pos = npos)
421*da0073e9SAndroid Build Coastguard Worker       const {
422*da0073e9SAndroid Build Coastguard Worker     return find_last_of(basic_string_view(s), pos);
423*da0073e9SAndroid Build Coastguard Worker   }
424*da0073e9SAndroid Build Coastguard Worker 
425*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_first_not_of(basic_string_view v, size_type pos = 0)
426*da0073e9SAndroid Build Coastguard Worker       const noexcept {
427*da0073e9SAndroid Build Coastguard Worker     return find_first_if_(pos, stringViewDoesNotContainChar_{v});
428*da0073e9SAndroid Build Coastguard Worker   }
429*da0073e9SAndroid Build Coastguard Worker 
430*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_first_not_of(CharT ch, size_type pos = 0)
431*da0073e9SAndroid Build Coastguard Worker       const noexcept {
432*da0073e9SAndroid Build Coastguard Worker     return find_first_if_(pos, charIsNotEqual_{ch});
433*da0073e9SAndroid Build Coastguard Worker   }
434*da0073e9SAndroid Build Coastguard Worker 
find_first_not_of(const_pointer s,size_type pos,size_type count)435*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_first_not_of(
436*da0073e9SAndroid Build Coastguard Worker       const_pointer s,
437*da0073e9SAndroid Build Coastguard Worker       size_type pos,
438*da0073e9SAndroid Build Coastguard Worker       size_type count) const {
439*da0073e9SAndroid Build Coastguard Worker     return find_first_not_of(basic_string_view(s, count), pos);
440*da0073e9SAndroid Build Coastguard Worker   }
441*da0073e9SAndroid Build Coastguard Worker 
442*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_first_not_of(const_pointer s, size_type pos = 0)
443*da0073e9SAndroid Build Coastguard Worker       const {
444*da0073e9SAndroid Build Coastguard Worker     return find_first_not_of(basic_string_view(s), pos);
445*da0073e9SAndroid Build Coastguard Worker   }
446*da0073e9SAndroid Build Coastguard Worker 
447*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_last_not_of(
448*da0073e9SAndroid Build Coastguard Worker       basic_string_view v,
449*da0073e9SAndroid Build Coastguard Worker       size_type pos = npos) const noexcept {
450*da0073e9SAndroid Build Coastguard Worker     return find_last_if_(pos, stringViewDoesNotContainChar_{v});
451*da0073e9SAndroid Build Coastguard Worker   }
452*da0073e9SAndroid Build Coastguard Worker 
453*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_last_not_of(CharT ch, size_type pos = npos)
454*da0073e9SAndroid Build Coastguard Worker       const noexcept {
455*da0073e9SAndroid Build Coastguard Worker     return find_last_if_(pos, charIsNotEqual_{ch});
456*da0073e9SAndroid Build Coastguard Worker   }
457*da0073e9SAndroid Build Coastguard Worker 
find_last_not_of(const_pointer s,size_type pos,size_type count)458*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_last_not_of(
459*da0073e9SAndroid Build Coastguard Worker       const_pointer s,
460*da0073e9SAndroid Build Coastguard Worker       size_type pos,
461*da0073e9SAndroid Build Coastguard Worker       size_type count) const {
462*da0073e9SAndroid Build Coastguard Worker     return find_last_not_of(basic_string_view(s, count), pos);
463*da0073e9SAndroid Build Coastguard Worker   }
464*da0073e9SAndroid Build Coastguard Worker 
465*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_last_not_of(const_pointer s, size_type pos = npos)
466*da0073e9SAndroid Build Coastguard Worker       const {
467*da0073e9SAndroid Build Coastguard Worker     return find_last_not_of(basic_string_view(s), pos);
468*da0073e9SAndroid Build Coastguard Worker   }
469*da0073e9SAndroid Build Coastguard Worker 
470*da0073e9SAndroid Build Coastguard Worker  private:
strlen_(const_pointer str)471*da0073e9SAndroid Build Coastguard Worker   static constexpr size_type strlen_(const_pointer str) noexcept {
472*da0073e9SAndroid Build Coastguard Worker     const_pointer current = str;
473*da0073e9SAndroid Build Coastguard Worker     while (*current != '\0') {
474*da0073e9SAndroid Build Coastguard Worker       ++current;
475*da0073e9SAndroid Build Coastguard Worker     }
476*da0073e9SAndroid Build Coastguard Worker     return current - str;
477*da0073e9SAndroid Build Coastguard Worker   }
478*da0073e9SAndroid Build Coastguard Worker 
at_(size_type pos)479*da0073e9SAndroid Build Coastguard Worker   constexpr const_reference at_(size_type pos) const noexcept {
480*da0073e9SAndroid Build Coastguard Worker     return *(begin_ + pos);
481*da0073e9SAndroid Build Coastguard Worker   }
482*da0073e9SAndroid Build Coastguard Worker 
483*da0073e9SAndroid Build Coastguard Worker   constexpr basic_string_view substr_(size_type pos = 0, size_type count = npos)
484*da0073e9SAndroid Build Coastguard Worker       const {
485*da0073e9SAndroid Build Coastguard Worker     return basic_string_view{begin_ + pos, std::min(count, size() - pos)};
486*da0073e9SAndroid Build Coastguard Worker   }
487*da0073e9SAndroid Build Coastguard Worker 
488*da0073e9SAndroid Build Coastguard Worker   template <class Condition>
489*da0073e9SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
find_first_if_(size_type pos,Condition && condition)490*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_first_if_(size_type pos, Condition&& condition)
491*da0073e9SAndroid Build Coastguard Worker       const noexcept {
492*da0073e9SAndroid Build Coastguard Worker     if (pos + 1 <= size()) {
493*da0073e9SAndroid Build Coastguard Worker       for (size_type cur = pos; cur < size(); ++cur) {
494*da0073e9SAndroid Build Coastguard Worker         if (condition(at_(cur))) {
495*da0073e9SAndroid Build Coastguard Worker           return cur;
496*da0073e9SAndroid Build Coastguard Worker         }
497*da0073e9SAndroid Build Coastguard Worker       }
498*da0073e9SAndroid Build Coastguard Worker     }
499*da0073e9SAndroid Build Coastguard Worker     return npos;
500*da0073e9SAndroid Build Coastguard Worker   }
501*da0073e9SAndroid Build Coastguard Worker 
502*da0073e9SAndroid Build Coastguard Worker   template <class Condition>
503*da0073e9SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
find_last_if_(size_type pos,Condition && condition)504*da0073e9SAndroid Build Coastguard Worker   constexpr size_type find_last_if_(size_type pos, Condition&& condition)
505*da0073e9SAndroid Build Coastguard Worker       const noexcept {
506*da0073e9SAndroid Build Coastguard Worker     // Write it iteratively. This is faster.
507*da0073e9SAndroid Build Coastguard Worker     if (size() > 0) {
508*da0073e9SAndroid Build Coastguard Worker       pos = std::min(size() - 1, pos);
509*da0073e9SAndroid Build Coastguard Worker       do {
510*da0073e9SAndroid Build Coastguard Worker         if (condition(at_(pos))) {
511*da0073e9SAndroid Build Coastguard Worker           return pos;
512*da0073e9SAndroid Build Coastguard Worker         }
513*da0073e9SAndroid Build Coastguard Worker       } while (pos-- > 0);
514*da0073e9SAndroid Build Coastguard Worker     }
515*da0073e9SAndroid Build Coastguard Worker     return npos;
516*da0073e9SAndroid Build Coastguard Worker   }
517*da0073e9SAndroid Build Coastguard Worker 
equals_(basic_string_view rhs)518*da0073e9SAndroid Build Coastguard Worker   constexpr bool equals_(basic_string_view rhs) const {
519*da0073e9SAndroid Build Coastguard Worker     // We don't use string_view::compare() here but implement it manually
520*da0073e9SAndroid Build Coastguard Worker     // because only looking at equality allows for more optimized code.
521*da0073e9SAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__CUDACC__)
522*da0073e9SAndroid Build Coastguard Worker     return size() == rhs.size() &&
523*da0073e9SAndroid Build Coastguard Worker         0 == __builtin_memcmp(data(), rhs.data(), size());
524*da0073e9SAndroid Build Coastguard Worker #else
525*da0073e9SAndroid Build Coastguard Worker     if (size() != rhs.size()) {
526*da0073e9SAndroid Build Coastguard Worker       return false;
527*da0073e9SAndroid Build Coastguard Worker     }
528*da0073e9SAndroid Build Coastguard Worker     // Yes, memcmp would be laster than this loop, but memcmp isn't constexpr
529*da0073e9SAndroid Build Coastguard Worker     // and I didn't feel like implementing a constexpr memcmp variant.
530*da0073e9SAndroid Build Coastguard Worker     // TODO At some point this should probably be done, including tricks
531*da0073e9SAndroid Build Coastguard Worker     // like comparing one machine word instead of a byte per iteration.
532*da0073e9SAndroid Build Coastguard Worker     for (typename basic_string_view<CharT>::size_type pos = 0; pos < size();
533*da0073e9SAndroid Build Coastguard Worker          ++pos) {
534*da0073e9SAndroid Build Coastguard Worker       if (at_(pos) != rhs.at_(pos)) {
535*da0073e9SAndroid Build Coastguard Worker         return false;
536*da0073e9SAndroid Build Coastguard Worker       }
537*da0073e9SAndroid Build Coastguard Worker     }
538*da0073e9SAndroid Build Coastguard Worker     return true;
539*da0073e9SAndroid Build Coastguard Worker #endif
540*da0073e9SAndroid Build Coastguard Worker   }
541*da0073e9SAndroid Build Coastguard Worker 
542*da0073e9SAndroid Build Coastguard Worker   struct charIsEqual_ final {
543*da0073e9SAndroid Build Coastguard Worker     CharT expected;
operatorfinal544*da0073e9SAndroid Build Coastguard Worker     constexpr bool operator()(CharT actual) const noexcept {
545*da0073e9SAndroid Build Coastguard Worker       return expected == actual;
546*da0073e9SAndroid Build Coastguard Worker     }
547*da0073e9SAndroid Build Coastguard Worker   };
548*da0073e9SAndroid Build Coastguard Worker 
549*da0073e9SAndroid Build Coastguard Worker   struct charIsNotEqual_ final {
550*da0073e9SAndroid Build Coastguard Worker     CharT expected;
operatorfinal551*da0073e9SAndroid Build Coastguard Worker     constexpr bool operator()(CharT actual) const noexcept {
552*da0073e9SAndroid Build Coastguard Worker       return expected != actual;
553*da0073e9SAndroid Build Coastguard Worker     }
554*da0073e9SAndroid Build Coastguard Worker   };
555*da0073e9SAndroid Build Coastguard Worker 
556*da0073e9SAndroid Build Coastguard Worker   struct stringViewContainsChar_ final {
557*da0073e9SAndroid Build Coastguard Worker     basic_string_view expected;
operatorfinal558*da0073e9SAndroid Build Coastguard Worker     constexpr bool operator()(CharT ch) const noexcept {
559*da0073e9SAndroid Build Coastguard Worker       return npos != expected.find(ch);
560*da0073e9SAndroid Build Coastguard Worker     }
561*da0073e9SAndroid Build Coastguard Worker   };
562*da0073e9SAndroid Build Coastguard Worker 
563*da0073e9SAndroid Build Coastguard Worker   struct stringViewDoesNotContainChar_ final {
564*da0073e9SAndroid Build Coastguard Worker     basic_string_view expected;
operatorfinal565*da0073e9SAndroid Build Coastguard Worker     constexpr bool operator()(CharT ch) const noexcept {
566*da0073e9SAndroid Build Coastguard Worker       return npos == expected.find(ch);
567*da0073e9SAndroid Build Coastguard Worker     }
568*da0073e9SAndroid Build Coastguard Worker   };
569*da0073e9SAndroid Build Coastguard Worker 
570*da0073e9SAndroid Build Coastguard Worker   const_pointer begin_;
571*da0073e9SAndroid Build Coastguard Worker   size_type size_{};
572*da0073e9SAndroid Build Coastguard Worker };
573*da0073e9SAndroid Build Coastguard Worker 
574*da0073e9SAndroid Build Coastguard Worker template <class CharT>
575*da0073e9SAndroid Build Coastguard Worker inline std::basic_ostream<CharT>& operator<<(
576*da0073e9SAndroid Build Coastguard Worker     std::basic_ostream<CharT>& stream,
577*da0073e9SAndroid Build Coastguard Worker     basic_string_view<CharT> sv) {
578*da0073e9SAndroid Build Coastguard Worker   // The rules for operator<< are quite complex, so lets defer to the
579*da0073e9SAndroid Build Coastguard Worker   // STL implementation.
580*da0073e9SAndroid Build Coastguard Worker   using std_string_type = ::std::basic_string_view<CharT>;
581*da0073e9SAndroid Build Coastguard Worker   return stream << std_string_type(sv.data(), sv.size());
582*da0073e9SAndroid Build Coastguard Worker }
583*da0073e9SAndroid Build Coastguard Worker 
584*da0073e9SAndroid Build Coastguard Worker template <class CharT>
swap(basic_string_view<CharT> & lhs,basic_string_view<CharT> & rhs)585*da0073e9SAndroid Build Coastguard Worker constexpr inline void swap(
586*da0073e9SAndroid Build Coastguard Worker     basic_string_view<CharT>& lhs,
587*da0073e9SAndroid Build Coastguard Worker     basic_string_view<CharT>& rhs) noexcept {
588*da0073e9SAndroid Build Coastguard Worker   lhs.swap(rhs);
589*da0073e9SAndroid Build Coastguard Worker }
590*da0073e9SAndroid Build Coastguard Worker 
591*da0073e9SAndroid Build Coastguard Worker using string_view = basic_string_view<char>;
592*da0073e9SAndroid Build Coastguard Worker 
593*da0073e9SAndroid Build Coastguard Worker } // namespace c10
594*da0073e9SAndroid Build Coastguard Worker 
595*da0073e9SAndroid Build Coastguard Worker namespace std {
596*da0073e9SAndroid Build Coastguard Worker template <class CharT>
597*da0073e9SAndroid Build Coastguard Worker struct hash<::c10::basic_string_view<CharT>> {
598*da0073e9SAndroid Build Coastguard Worker   size_t operator()(::c10::basic_string_view<CharT> x) const {
599*da0073e9SAndroid Build Coastguard Worker     // The standard says that std::string_view hashing must do the same as
600*da0073e9SAndroid Build Coastguard Worker     // std::string hashing but leaves the details of std::string hashing
601*da0073e9SAndroid Build Coastguard Worker     // up to the implementer. So, to be conformant, we need to re-use and
602*da0073e9SAndroid Build Coastguard Worker     // existing STL type's hash function. The std::string fallback is probably
603*da0073e9SAndroid Build Coastguard Worker     // slow but the only way to be conformant.
604*da0073e9SAndroid Build Coastguard Worker 
605*da0073e9SAndroid Build Coastguard Worker     using std_string_type = ::std::basic_string_view<CharT>;
606*da0073e9SAndroid Build Coastguard Worker     return ::std::hash<std_string_type>{}(std_string_type(x.data(), x.size()));
607*da0073e9SAndroid Build Coastguard Worker   }
608*da0073e9SAndroid Build Coastguard Worker };
609*da0073e9SAndroid Build Coastguard Worker } // namespace std
610