libgccjit: Add ability to get the alignment of a type
[official-gcc.git] / libstdc++-v3 / include / std / string_view
blob740aa9344f0147594559c74d90879a689e45c854
1 // Components for manipulating non-owning sequences of characters -*- C++ -*-
3 // Copyright (C) 2013-2024 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file include/string_view
26  *  This is a Standard C++ Library header.
27  */
30 // N3762 basic_string_view library
33 #ifndef _GLIBCXX_STRING_VIEW
34 #define _GLIBCXX_STRING_VIEW 1
36 #pragma GCC system_header
38 #define __glibcxx_want_constexpr_char_traits
39 #define __glibcxx_want_constexpr_string_view
40 #define __glibcxx_want_freestanding_string_view
41 #define __glibcxx_want_string_view
42 #define __glibcxx_want_starts_ends_with
43 #define __glibcxx_want_string_contains
44 #include <bits/version.h>
46 #if __cplusplus >= 201703L
48 #include <bits/char_traits.h>
49 #include <bits/functexcept.h>
50 #include <bits/functional_hash.h>
51 #include <bits/range_access.h>
52 #include <bits/stl_algobase.h>
53 #include <ext/numeric_traits.h>
55 #if __cplusplus >= 202002L
56 # include <bits/ranges_base.h>
57 #endif
59 #if _GLIBCXX_HOSTED
60 # include <iosfwd>
61 # include <bits/ostream_insert.h>
62 #endif
64 namespace std _GLIBCXX_VISIBILITY(default)
66 _GLIBCXX_BEGIN_NAMESPACE_VERSION
68   // Helper for basic_string and basic_string_view members.
69   constexpr size_t
70   __sv_check(size_t __size, size_t __pos, const char* __s)
71   {
72     if (__pos > __size)
73       __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > __size "
74                                    "(which is %zu)"), __s, __pos, __size);
75     return __pos;
76   }
78   // Helper for basic_string members.
79   // NB: __sv_limit doesn't check for a bad __pos value.
80   constexpr size_t
81   __sv_limit(size_t __size, size_t __pos, size_t __off) noexcept
82   {
83    const bool __testoff =  __off < __size - __pos;
84    return __testoff ? __off : __size - __pos;
85   }
87   /**
88    *  @class basic_string_view <string_view>
89    *  @brief  A non-owning reference to a string.
90    *
91    *  @ingroup strings
92    *  @ingroup sequences
93    *
94    *  @tparam _CharT  Type of character
95    *  @tparam _Traits  Traits for character type, defaults to
96    *                   char_traits<_CharT>.
97    *
98    *  A basic_string_view looks like this:
99    *
100    *  @code
101    *    _CharT*    _M_str
102    *    size_t     _M_len
103    *  @endcode
104    */
105   template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
106     class basic_string_view
107     {
108       static_assert(!is_array_v<_CharT>);
109       static_assert(is_trivial_v<_CharT> && is_standard_layout_v<_CharT>);
110       static_assert(is_same_v<_CharT, typename _Traits::char_type>);
112     public:
114       // types
115       using traits_type         = _Traits;
116       using value_type          = _CharT;
117       using pointer             = value_type*;
118       using const_pointer       = const value_type*;
119       using reference           = value_type&;
120       using const_reference     = const value_type&;
121       using const_iterator      = const value_type*;
122       using iterator            = const_iterator;
123       using const_reverse_iterator = std::reverse_iterator<const_iterator>;
124       using reverse_iterator    = const_reverse_iterator;
125       using size_type           = size_t;
126       using difference_type     = ptrdiff_t;
127       static constexpr size_type npos = size_type(-1);
129       // [string.view.cons], construction and assignment
131       constexpr
132       basic_string_view() noexcept
133       : _M_len{0}, _M_str{nullptr}
134       { }
136       constexpr basic_string_view(const basic_string_view&) noexcept = default;
138       [[__gnu__::__nonnull__]]
139       constexpr
140       basic_string_view(const _CharT* __str) noexcept
141       : _M_len{traits_type::length(__str)},
142         _M_str{__str}
143       { }
145       constexpr
146       basic_string_view(const _CharT* __str, size_type __len) noexcept
147       : _M_len{__len}, _M_str{__str}
148       { }
150 #if __cplusplus >= 202002L && __cpp_lib_concepts
151       template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
152         requires same_as<iter_value_t<_It>, _CharT>
153           && (!convertible_to<_End, size_type>)
154         constexpr
155         basic_string_view(_It __first, _End __last)
156         noexcept(noexcept(__last - __first))
157         : _M_len(__last - __first), _M_str(std::to_address(__first))
158         { }
160 #if __cplusplus > 202002L
161       template<typename _Range, typename _DRange = remove_cvref_t<_Range>>
162         requires (!is_same_v<_DRange, basic_string_view>)
163           && ranges::contiguous_range<_Range>
164           && ranges::sized_range<_Range>
165           && is_same_v<ranges::range_value_t<_Range>, _CharT>
166           && (!is_convertible_v<_Range, const _CharT*>)
167           && (!requires (_DRange& __d) {
168                 __d.operator ::std::basic_string_view<_CharT, _Traits>();
169               })
170         constexpr explicit
171         basic_string_view(_Range&& __r)
172         noexcept(noexcept(ranges::size(__r)) && noexcept(ranges::data(__r)))
173         : _M_len(ranges::size(__r)), _M_str(ranges::data(__r))
174         { }
176       basic_string_view(nullptr_t) = delete;
177 #endif // C++23
178 #endif // C++20
180       constexpr basic_string_view&
181       operator=(const basic_string_view&) noexcept = default;
183       // [string.view.iterators], iterator support
185       [[nodiscard]]
186       constexpr const_iterator
187       begin() const noexcept
188       { return this->_M_str; }
190       [[nodiscard]]
191       constexpr const_iterator
192       end() const noexcept
193       { return this->_M_str + this->_M_len; }
195       [[nodiscard]]
196       constexpr const_iterator
197       cbegin() const noexcept
198       { return this->_M_str; }
200       [[nodiscard]]
201       constexpr const_iterator
202       cend() const noexcept
203       { return this->_M_str + this->_M_len; }
205       [[nodiscard]]
206       constexpr const_reverse_iterator
207       rbegin() const noexcept
208       { return const_reverse_iterator(this->end()); }
210       [[nodiscard]]
211       constexpr const_reverse_iterator
212       rend() const noexcept
213       { return const_reverse_iterator(this->begin()); }
215       [[nodiscard]]
216       constexpr const_reverse_iterator
217       crbegin() const noexcept
218       { return const_reverse_iterator(this->end()); }
220       [[nodiscard]]
221       constexpr const_reverse_iterator
222       crend() const noexcept
223       { return const_reverse_iterator(this->begin()); }
225       // [string.view.capacity], capacity
227       [[nodiscard]]
228       constexpr size_type
229       size() const noexcept
230       { return this->_M_len; }
232       [[nodiscard]]
233       constexpr size_type
234       length() const noexcept
235       { return _M_len; }
237       [[nodiscard]]
238       constexpr size_type
239       max_size() const noexcept
240       {
241         return (npos - sizeof(size_type) - sizeof(void*))
242                 / sizeof(value_type) / 4;
243       }
245       [[nodiscard]]
246       constexpr bool
247       empty() const noexcept
248       { return this->_M_len == 0; }
250       // [string.view.access], element access
252       [[nodiscard]]
253       constexpr const_reference
254       operator[](size_type __pos) const noexcept
255       {
256         __glibcxx_assert(__pos < this->_M_len);
257         return *(this->_M_str + __pos);
258       }
260       [[nodiscard]]
261       constexpr const_reference
262       at(size_type __pos) const
263       {
264         if (__pos >= _M_len)
265           __throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
266                                        "(which is %zu) >= this->size() "
267                                        "(which is %zu)"), __pos, this->size());
268         return *(this->_M_str + __pos);
269       }
271       [[nodiscard]]
272       constexpr const_reference
273       front() const noexcept
274       {
275         __glibcxx_assert(this->_M_len > 0);
276         return *this->_M_str;
277       }
279       [[nodiscard]]
280       constexpr const_reference
281       back() const noexcept
282       {
283         __glibcxx_assert(this->_M_len > 0);
284         return *(this->_M_str + this->_M_len - 1);
285       }
287       [[nodiscard]]
288       constexpr const_pointer
289       data() const noexcept
290       { return this->_M_str; }
292       // [string.view.modifiers], modifiers:
294       constexpr void
295       remove_prefix(size_type __n) noexcept
296       {
297         __glibcxx_assert(this->_M_len >= __n);
298         this->_M_str += __n;
299         this->_M_len -= __n;
300       }
302       constexpr void
303       remove_suffix(size_type __n) noexcept
304       {
305         __glibcxx_assert(this->_M_len >= __n);
306         this->_M_len -= __n;
307       }
309       constexpr void
310       swap(basic_string_view& __sv) noexcept
311       {
312         auto __tmp = *this;
313         *this = __sv;
314         __sv = __tmp;
315       }
317       // [string.view.ops], string operations:
319       _GLIBCXX20_CONSTEXPR
320       size_type
321       copy(_CharT* __str, size_type __n, size_type __pos = 0) const
322       {
323         __glibcxx_requires_string_len(__str, __n);
324         __pos = std::__sv_check(size(), __pos, "basic_string_view::copy");
325         const size_type __rlen = std::min<size_t>(__n, _M_len - __pos);
326         // _GLIBCXX_RESOLVE_LIB_DEFECTS
327         // 2777. basic_string_view::copy should use char_traits::copy
328         traits_type::copy(__str, data() + __pos, __rlen);
329         return __rlen;
330       }
332       [[nodiscard]]
333       constexpr basic_string_view
334       substr(size_type __pos = 0, size_type __n = npos) const noexcept(false)
335       {
336         __pos = std::__sv_check(size(), __pos, "basic_string_view::substr");
337         const size_type __rlen = std::min<size_t>(__n, _M_len - __pos);
338         return basic_string_view{_M_str + __pos, __rlen};
339       }
341       [[nodiscard]]
342       constexpr int
343       compare(basic_string_view __str) const noexcept
344       {
345         const size_type __rlen = std::min(this->_M_len, __str._M_len);
346         int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen);
347         if (__ret == 0)
348           __ret = _S_compare(this->_M_len, __str._M_len);
349         return __ret;
350       }
352       [[nodiscard]]
353       constexpr int
354       compare(size_type __pos1, size_type __n1, basic_string_view __str) const
355       { return this->substr(__pos1, __n1).compare(__str); }
357       [[nodiscard]]
358       constexpr int
359       compare(size_type __pos1, size_type __n1,
360               basic_string_view __str, size_type __pos2, size_type __n2) const
361       {
362         return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
363       }
365       [[nodiscard, __gnu__::__nonnull__]]
366       constexpr int
367       compare(const _CharT* __str) const noexcept
368       { return this->compare(basic_string_view{__str}); }
370       [[nodiscard, __gnu__::__nonnull__]]
371       constexpr int
372       compare(size_type __pos1, size_type __n1, const _CharT* __str) const
373       { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
375       [[nodiscard]]
376       constexpr int
377       compare(size_type __pos1, size_type __n1,
378               const _CharT* __str, size_type __n2) const noexcept(false)
379       {
380         return this->substr(__pos1, __n1)
381                    .compare(basic_string_view(__str, __n2));
382       }
384 #ifdef __cpp_lib_starts_ends_with // C++ >= 20
385       [[nodiscard]]
386       constexpr bool
387       starts_with(basic_string_view __x) const noexcept
388       {
389         return _M_len >= __x._M_len
390           && traits_type::compare(_M_str, __x._M_str, __x._M_len) == 0;
391       }
393       [[nodiscard]]
394       constexpr bool
395       starts_with(_CharT __x) const noexcept
396       { return !this->empty() && traits_type::eq(this->front(), __x); }
398       [[nodiscard, __gnu__::__nonnull__]]
399       constexpr bool
400       starts_with(const _CharT* __x) const noexcept
401       { return this->starts_with(basic_string_view(__x)); }
403       [[nodiscard]]
404       constexpr bool
405       ends_with(basic_string_view __x) const noexcept
406       {
407         const auto __len = this->size();
408         const auto __xlen = __x.size();
409         return __len >= __xlen
410           && traits_type::compare(end() - __xlen, __x.data(), __xlen) == 0;
411       }
413       [[nodiscard]]
414       constexpr bool
415       ends_with(_CharT __x) const noexcept
416       { return !this->empty() && traits_type::eq(this->back(), __x); }
418       [[nodiscard, __gnu__::__nonnull__]]
419       constexpr bool
420       ends_with(const _CharT* __x) const noexcept
421       { return this->ends_with(basic_string_view(__x)); }
422 #endif // __cpp_lib_starts_ends_with
424 #if __cplusplus > 202002L
425 #if _GLIBCXX_HOSTED && !defined(__cpp_lib_string_contains)
426       // This FTM is not freestanding as it also implies matching <string>
427       // support, and <string> is omitted from the freestanding subset.
428 # error "libstdc++ bug: string_contains not defined when it should be"
429 #endif // HOSTED
430       [[nodiscard]]
431       constexpr bool
432       contains(basic_string_view __x) const noexcept
433       { return this->find(__x) != npos; }
435       [[nodiscard]]
436       constexpr bool
437       contains(_CharT __x) const noexcept
438       { return this->find(__x) != npos; }
440       [[nodiscard, __gnu__::__nonnull__]]
441       constexpr bool
442       contains(const _CharT* __x) const noexcept
443       { return this->find(__x) != npos; }
444 #endif // C++23
446       // [string.view.find], searching
448       [[nodiscard]]
449       constexpr size_type
450       find(basic_string_view __str, size_type __pos = 0) const noexcept
451       { return this->find(__str._M_str, __pos, __str._M_len); }
453       [[nodiscard]]
454       constexpr size_type
455       find(_CharT __c, size_type __pos = 0) const noexcept;
457       [[nodiscard]]
458       constexpr size_type
459       find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
461       [[nodiscard, __gnu__::__nonnull__]]
462       constexpr size_type
463       find(const _CharT* __str, size_type __pos = 0) const noexcept
464       { return this->find(__str, __pos, traits_type::length(__str)); }
466       [[nodiscard]]
467       constexpr size_type
468       rfind(basic_string_view __str, size_type __pos = npos) const noexcept
469       { return this->rfind(__str._M_str, __pos, __str._M_len); }
471       [[nodiscard]]
472       constexpr size_type
473       rfind(_CharT __c, size_type __pos = npos) const noexcept;
475       [[nodiscard]]
476       constexpr size_type
477       rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
479       [[nodiscard, __gnu__::__nonnull__]]
480       constexpr size_type
481       rfind(const _CharT* __str, size_type __pos = npos) const noexcept
482       { return this->rfind(__str, __pos, traits_type::length(__str)); }
484       [[nodiscard]]
485       constexpr size_type
486       find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
487       { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
489       [[nodiscard]]
490       constexpr size_type
491       find_first_of(_CharT __c, size_type __pos = 0) const noexcept
492       { return this->find(__c, __pos); }
494       [[nodiscard]]
495       constexpr size_type
496       find_first_of(const _CharT* __str, size_type __pos,
497                     size_type __n) const noexcept;
499       [[nodiscard, __gnu__::__nonnull__]]
500       constexpr size_type
501       find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
502       { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
504       [[nodiscard]]
505       constexpr size_type
506       find_last_of(basic_string_view __str,
507                    size_type __pos = npos) const noexcept
508       { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
510       [[nodiscard]]
511       constexpr size_type
512       find_last_of(_CharT __c, size_type __pos=npos) const noexcept
513       { return this->rfind(__c, __pos); }
515       [[nodiscard]]
516       constexpr size_type
517       find_last_of(const _CharT* __str, size_type __pos,
518                    size_type __n) const noexcept;
520       [[nodiscard, __gnu__::__nonnull__]]
521       constexpr size_type
522       find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
523       { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
525       [[nodiscard]]
526       constexpr size_type
527       find_first_not_of(basic_string_view __str,
528                         size_type __pos = 0) const noexcept
529       { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
531       [[nodiscard]]
532       constexpr size_type
533       find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
535       [[nodiscard]]
536       constexpr size_type
537       find_first_not_of(const _CharT* __str,
538                         size_type __pos, size_type __n) const noexcept;
540       [[nodiscard, __gnu__::__nonnull__]]
541       constexpr size_type
542       find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
543       {
544         return this->find_first_not_of(__str, __pos,
545                                        traits_type::length(__str));
546       }
548       [[nodiscard]]
549       constexpr size_type
550       find_last_not_of(basic_string_view __str,
551                        size_type __pos = npos) const noexcept
552       { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
554       [[nodiscard]]
555       constexpr size_type
556       find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
558       [[nodiscard]]
559       constexpr size_type
560       find_last_not_of(const _CharT* __str,
561                        size_type __pos, size_type __n) const noexcept;
563       [[nodiscard, __gnu__::__nonnull__]]
564       constexpr size_type
565       find_last_not_of(const _CharT* __str,
566                        size_type __pos = npos) const noexcept
567       {
568         return this->find_last_not_of(__str, __pos,
569                                       traits_type::length(__str));
570       }
572     private:
574       static constexpr int
575       _S_compare(size_type __n1, size_type __n2) noexcept
576       {
577         using __limits = __gnu_cxx::__int_traits<int>;
578         const difference_type __diff = __n1 - __n2;
579         if (__diff > __limits::__max)
580           return __limits::__max;
581         if (__diff < __limits::__min)
582           return __limits::__min;
583         return static_cast<int>(__diff);
584       }
586       size_t        _M_len;
587       const _CharT* _M_str;
588     };
590 #if __cplusplus > 201703L && __cpp_lib_concepts && __cpp_deduction_guides
591   template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
592     basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
594 #if __cplusplus > 202002L
595   template<ranges::contiguous_range _Range>
596     basic_string_view(_Range&&)
597       -> basic_string_view<ranges::range_value_t<_Range>>;
598 #endif
599 #endif
601   // [string.view.comparison], non-member basic_string_view comparison function
603   // Several of these functions use type_identity_t to create a non-deduced
604   // context, so that only one argument participates in template argument
605   // deduction and the other argument gets implicitly converted to the deduced
606   // type (see N3766).
608 #if __cpp_lib_three_way_comparison
609   template<typename _CharT, typename _Traits>
610     [[nodiscard]]
611     constexpr bool
612     operator==(basic_string_view<_CharT, _Traits> __x,
613                type_identity_t<basic_string_view<_CharT, _Traits>> __y)
614     noexcept
615     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
617   template<typename _CharT, typename _Traits>
618     [[nodiscard]]
619     constexpr auto
620     operator<=>(basic_string_view<_CharT, _Traits> __x,
621                 __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
622     noexcept
623     -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
624     { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
625 #else
626   template<typename _CharT, typename _Traits>
627     [[nodiscard]]
628     constexpr bool
629     operator==(basic_string_view<_CharT, _Traits> __x,
630                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
631     noexcept
632     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
634   template<typename _CharT, typename _Traits>
635     [[nodiscard]]
636     constexpr bool
637     operator==(basic_string_view<_CharT, _Traits> __x,
638                basic_string_view<_CharT, _Traits> __y) noexcept
639     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
641   template<typename _CharT, typename _Traits>
642     [[nodiscard]]
643     constexpr bool
644     operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
645                basic_string_view<_CharT, _Traits> __y) noexcept
646     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
648   template<typename _CharT, typename _Traits>
649     [[nodiscard]]
650     constexpr bool
651     operator!=(basic_string_view<_CharT, _Traits> __x,
652                basic_string_view<_CharT, _Traits> __y) noexcept
653     { return !(__x == __y); }
655   template<typename _CharT, typename _Traits>
656     [[nodiscard]]
657     constexpr bool
658     operator!=(basic_string_view<_CharT, _Traits> __x,
659                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
660     noexcept
661     { return !(__x == __y); }
663   template<typename _CharT, typename _Traits>
664     [[nodiscard]]
665     constexpr bool
666     operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
667                basic_string_view<_CharT, _Traits> __y) noexcept
668     { return !(__x == __y); }
670   template<typename _CharT, typename _Traits>
671     [[nodiscard]]
672     constexpr bool
673     operator< (basic_string_view<_CharT, _Traits> __x,
674                basic_string_view<_CharT, _Traits> __y) noexcept
675     { return __x.compare(__y) < 0; }
677   template<typename _CharT, typename _Traits>
678     [[nodiscard]]
679     constexpr bool
680     operator< (basic_string_view<_CharT, _Traits> __x,
681                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
682     noexcept
683     { return __x.compare(__y) < 0; }
685   template<typename _CharT, typename _Traits>
686     [[nodiscard]]
687     constexpr bool
688     operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
689                basic_string_view<_CharT, _Traits> __y) noexcept
690     { return __x.compare(__y) < 0; }
692   template<typename _CharT, typename _Traits>
693     [[nodiscard]]
694     constexpr bool
695     operator> (basic_string_view<_CharT, _Traits> __x,
696                basic_string_view<_CharT, _Traits> __y) noexcept
697     { return __x.compare(__y) > 0; }
699   template<typename _CharT, typename _Traits>
700     [[nodiscard]]
701     constexpr bool
702     operator> (basic_string_view<_CharT, _Traits> __x,
703                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
704     noexcept
705     { return __x.compare(__y) > 0; }
707   template<typename _CharT, typename _Traits>
708     [[nodiscard]]
709     constexpr bool
710     operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
711                basic_string_view<_CharT, _Traits> __y) noexcept
712     { return __x.compare(__y) > 0; }
714   template<typename _CharT, typename _Traits>
715     [[nodiscard]]
716     constexpr bool
717     operator<=(basic_string_view<_CharT, _Traits> __x,
718                basic_string_view<_CharT, _Traits> __y) noexcept
719     { return __x.compare(__y) <= 0; }
721   template<typename _CharT, typename _Traits>
722     [[nodiscard]]
723     constexpr bool
724     operator<=(basic_string_view<_CharT, _Traits> __x,
725                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
726     noexcept
727     { return __x.compare(__y) <= 0; }
729   template<typename _CharT, typename _Traits>
730     [[nodiscard]]
731     constexpr bool
732     operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
733                basic_string_view<_CharT, _Traits> __y) noexcept
734     { return __x.compare(__y) <= 0; }
736   template<typename _CharT, typename _Traits>
737     [[nodiscard]]
738     constexpr bool
739     operator>=(basic_string_view<_CharT, _Traits> __x,
740                basic_string_view<_CharT, _Traits> __y) noexcept
741     { return __x.compare(__y) >= 0; }
743   template<typename _CharT, typename _Traits>
744     [[nodiscard]]
745     constexpr bool
746     operator>=(basic_string_view<_CharT, _Traits> __x,
747                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
748     noexcept
749     { return __x.compare(__y) >= 0; }
751   template<typename _CharT, typename _Traits>
752     [[nodiscard]]
753     constexpr bool
754     operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
755                basic_string_view<_CharT, _Traits> __y) noexcept
756     { return __x.compare(__y) >= 0; }
757 #endif // three-way comparison
759 #if _GLIBCXX_HOSTED
760   // [string.view.io], Inserters and extractors
761   template<typename _CharT, typename _Traits>
762     inline basic_ostream<_CharT, _Traits>&
763     operator<<(basic_ostream<_CharT, _Traits>& __os,
764                basic_string_view<_CharT,_Traits> __str)
765     { return __ostream_insert(__os, __str.data(), __str.size()); }
766 #endif // HOSTED
768   // basic_string_view typedef names
770   using string_view = basic_string_view<char>;
771   using wstring_view = basic_string_view<wchar_t>;
772 #ifdef _GLIBCXX_USE_CHAR8_T
773   using u8string_view = basic_string_view<char8_t>;
774 #endif
775   using u16string_view = basic_string_view<char16_t>;
776   using u32string_view = basic_string_view<char32_t>;
778   // [string.view.hash], hash support:
780   template<typename _Tp>
781     struct hash;
783   template<>
784     struct hash<string_view>
785     : public __hash_base<size_t, string_view>
786     {
787       [[nodiscard]]
788       size_t
789       operator()(const string_view& __str) const noexcept
790       { return std::_Hash_impl::hash(__str.data(), __str.length()); }
791     };
793   template<>
794     struct __is_fast_hash<hash<string_view>> : std::false_type
795     { };
797   template<>
798     struct hash<wstring_view>
799     : public __hash_base<size_t, wstring_view>
800     {
801       [[nodiscard]]
802       size_t
803       operator()(const wstring_view& __s) const noexcept
804       { return std::_Hash_impl::hash(__s.data(),
805                                      __s.length() * sizeof(wchar_t)); }
806     };
808   template<>
809     struct __is_fast_hash<hash<wstring_view>> : std::false_type
810     { };
812 #ifdef _GLIBCXX_USE_CHAR8_T
813   template<>
814     struct hash<u8string_view>
815     : public __hash_base<size_t, u8string_view>
816     {
817       [[nodiscard]]
818       size_t
819       operator()(const u8string_view& __str) const noexcept
820       { return std::_Hash_impl::hash(__str.data(), __str.length()); }
821     };
823   template<>
824     struct __is_fast_hash<hash<u8string_view>> : std::false_type
825     { };
826 #endif
828   template<>
829     struct hash<u16string_view>
830     : public __hash_base<size_t, u16string_view>
831     {
832       [[nodiscard]]
833       size_t
834       operator()(const u16string_view& __s) const noexcept
835       { return std::_Hash_impl::hash(__s.data(),
836                                      __s.length() * sizeof(char16_t)); }
837     };
839   template<>
840     struct __is_fast_hash<hash<u16string_view>> : std::false_type
841     { };
843   template<>
844     struct hash<u32string_view>
845     : public __hash_base<size_t, u32string_view>
846     {
847       [[nodiscard]]
848       size_t
849       operator()(const u32string_view& __s) const noexcept
850       { return std::_Hash_impl::hash(__s.data(),
851                                      __s.length() * sizeof(char32_t)); }
852     };
854   template<>
855     struct __is_fast_hash<hash<u32string_view>> : std::false_type
856     { };
858   inline namespace literals
859   {
860   inline namespace string_view_literals
861   {
862 #pragma GCC diagnostic push
863 #pragma GCC diagnostic ignored "-Wliteral-suffix"
864     inline constexpr basic_string_view<char>
865     operator""sv(const char* __str, size_t __len) noexcept
866     { return basic_string_view<char>{__str, __len}; }
868     inline constexpr basic_string_view<wchar_t>
869     operator""sv(const wchar_t* __str, size_t __len) noexcept
870     { return basic_string_view<wchar_t>{__str, __len}; }
872 #ifdef _GLIBCXX_USE_CHAR8_T
873     inline constexpr basic_string_view<char8_t>
874     operator""sv(const char8_t* __str, size_t __len) noexcept
875     { return basic_string_view<char8_t>{__str, __len}; }
876 #endif
878     inline constexpr basic_string_view<char16_t>
879     operator""sv(const char16_t* __str, size_t __len) noexcept
880     { return basic_string_view<char16_t>{__str, __len}; }
882     inline constexpr basic_string_view<char32_t>
883     operator""sv(const char32_t* __str, size_t __len) noexcept
884     { return basic_string_view<char32_t>{__str, __len}; }
886 #pragma GCC diagnostic pop
887   } // namespace string_literals
888   } // namespace literals
890 #if __cpp_lib_concepts
891   namespace ranges
892   {
893     // Opt-in to borrowed_range concept
894     template<typename _CharT, typename _Traits>
895       inline constexpr bool
896         enable_borrowed_range<basic_string_view<_CharT, _Traits>> = true;
898     // Opt-in to view concept
899     template<typename _CharT, typename _Traits>
900       inline constexpr bool
901         enable_view<basic_string_view<_CharT, _Traits>> = true;
902   }
903 #endif
904 _GLIBCXX_END_NAMESPACE_VERSION
905 } // namespace std
907 #include <bits/string_view.tcc>
909 #endif // __cplusplus <= 201402L
911 #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW