146035553Spatrick// -*- C++ -*- 2*4bdff4beSrobert//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===----------------------------------------------------------------------===// 946035553Spatrick 1046035553Spatrick#ifndef _LIBCPP_STRING_VIEW 1146035553Spatrick#define _LIBCPP_STRING_VIEW 1246035553Spatrick 1346035553Spatrick/* 14*4bdff4beSrobert 1546035553Spatrick string_view synopsis 1646035553Spatrick 17*4bdff4beSrobert#include <compare> 18*4bdff4beSrobert 1946035553Spatricknamespace std { 2046035553Spatrick 2146035553Spatrick // 7.2, Class template basic_string_view 2246035553Spatrick template<class charT, class traits = char_traits<charT>> 2346035553Spatrick class basic_string_view; 2446035553Spatrick 2576d0caaeSpatrick template<class charT, class traits> 2676d0caaeSpatrick inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true; 2776d0caaeSpatrick 2876d0caaeSpatrick template<class charT, class traits> 2976d0caaeSpatrick inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20 3076d0caaeSpatrick 3146035553Spatrick // 7.9, basic_string_view non-member comparison functions 3246035553Spatrick template<class charT, class traits> 3346035553Spatrick constexpr bool operator==(basic_string_view<charT, traits> x, 3446035553Spatrick basic_string_view<charT, traits> y) noexcept; 35*4bdff4beSrobert template<class charT, class traits> // Removed in C++20 3646035553Spatrick constexpr bool operator!=(basic_string_view<charT, traits> x, 3746035553Spatrick basic_string_view<charT, traits> y) noexcept; 38*4bdff4beSrobert template<class charT, class traits> // Removed in C++20 3946035553Spatrick constexpr bool operator< (basic_string_view<charT, traits> x, 4046035553Spatrick basic_string_view<charT, traits> y) noexcept; 41*4bdff4beSrobert template<class charT, class traits> // Removed in C++20 4246035553Spatrick constexpr bool operator> (basic_string_view<charT, traits> x, 4346035553Spatrick basic_string_view<charT, traits> y) noexcept; 44*4bdff4beSrobert template<class charT, class traits> // Removed in C++20 4546035553Spatrick constexpr bool operator<=(basic_string_view<charT, traits> x, 4646035553Spatrick basic_string_view<charT, traits> y) noexcept; 47*4bdff4beSrobert template<class charT, class traits> // Removed in C++20 4846035553Spatrick constexpr bool operator>=(basic_string_view<charT, traits> x, 4946035553Spatrick basic_string_view<charT, traits> y) noexcept; 50*4bdff4beSrobert template<class charT, class traits> // Since C++20 51*4bdff4beSrobert constexpr see below operator<=>(basic_string_view<charT, traits> x, 52*4bdff4beSrobert basic_string_view<charT, traits> y) noexcept; 53*4bdff4beSrobert 5446035553Spatrick // see below, sufficient additional overloads of comparison functions 5546035553Spatrick 5646035553Spatrick // 7.10, Inserters and extractors 5746035553Spatrick template<class charT, class traits> 5846035553Spatrick basic_ostream<charT, traits>& 5946035553Spatrick operator<<(basic_ostream<charT, traits>& os, 6046035553Spatrick basic_string_view<charT, traits> str); 6146035553Spatrick 6246035553Spatrick // basic_string_view typedef names 6346035553Spatrick typedef basic_string_view<char> string_view; 6476d0caaeSpatrick typedef basic_string_view<char8_t> u8string_view; // C++20 6546035553Spatrick typedef basic_string_view<char16_t> u16string_view; 6646035553Spatrick typedef basic_string_view<char32_t> u32string_view; 6746035553Spatrick typedef basic_string_view<wchar_t> wstring_view; 6846035553Spatrick 6946035553Spatrick template<class charT, class traits = char_traits<charT>> 7046035553Spatrick class basic_string_view { 7146035553Spatrick public: 7246035553Spatrick // types 7346035553Spatrick typedef traits traits_type; 7446035553Spatrick typedef charT value_type; 7546035553Spatrick typedef charT* pointer; 7646035553Spatrick typedef const charT* const_pointer; 7746035553Spatrick typedef charT& reference; 7846035553Spatrick typedef const charT& const_reference; 7946035553Spatrick typedef implementation-defined const_iterator; 8046035553Spatrick typedef const_iterator iterator; 8146035553Spatrick typedef reverse_iterator<const_iterator> const_reverse_iterator; 8246035553Spatrick typedef const_reverse_iterator reverse_iterator; 8346035553Spatrick typedef size_t size_type; 8446035553Spatrick typedef ptrdiff_t difference_type; 8546035553Spatrick static constexpr size_type npos = size_type(-1); 8646035553Spatrick 8746035553Spatrick // 7.3, basic_string_view constructors and assignment operators 8846035553Spatrick constexpr basic_string_view() noexcept; 8946035553Spatrick constexpr basic_string_view(const basic_string_view&) noexcept = default; 9046035553Spatrick basic_string_view& operator=(const basic_string_view&) noexcept = default; 9146035553Spatrick template<class Allocator> 9246035553Spatrick constexpr basic_string_view(const charT* str); 9376d0caaeSpatrick basic_string_view(nullptr_t) = delete; // C++2b 9446035553Spatrick constexpr basic_string_view(const charT* str, size_type len); 95*4bdff4beSrobert template <class It, class End> 96*4bdff4beSrobert constexpr basic_string_view(It begin, End end); // C++20 97*4bdff4beSrobert template <class Range> 98*4bdff4beSrobert constexpr basic_string_view(Range&& r); // C++23 9946035553Spatrick 10046035553Spatrick // 7.4, basic_string_view iterator support 10146035553Spatrick constexpr const_iterator begin() const noexcept; 10246035553Spatrick constexpr const_iterator end() const noexcept; 10346035553Spatrick constexpr const_iterator cbegin() const noexcept; 10446035553Spatrick constexpr const_iterator cend() const noexcept; 10546035553Spatrick const_reverse_iterator rbegin() const noexcept; 10646035553Spatrick const_reverse_iterator rend() const noexcept; 10746035553Spatrick const_reverse_iterator crbegin() const noexcept; 10846035553Spatrick const_reverse_iterator crend() const noexcept; 10946035553Spatrick 11046035553Spatrick // 7.5, basic_string_view capacity 11146035553Spatrick constexpr size_type size() const noexcept; 11246035553Spatrick constexpr size_type length() const noexcept; 11346035553Spatrick constexpr size_type max_size() const noexcept; 11446035553Spatrick constexpr bool empty() const noexcept; 11546035553Spatrick 11646035553Spatrick // 7.6, basic_string_view element access 11746035553Spatrick constexpr const_reference operator[](size_type pos) const; 11846035553Spatrick constexpr const_reference at(size_type pos) const; 11946035553Spatrick constexpr const_reference front() const; 12046035553Spatrick constexpr const_reference back() const; 12146035553Spatrick constexpr const_pointer data() const noexcept; 12246035553Spatrick 12346035553Spatrick // 7.7, basic_string_view modifiers 12446035553Spatrick constexpr void remove_prefix(size_type n); 12546035553Spatrick constexpr void remove_suffix(size_type n); 12646035553Spatrick constexpr void swap(basic_string_view& s) noexcept; 12746035553Spatrick 12876d0caaeSpatrick size_type copy(charT* s, size_type n, size_type pos = 0) const; // constexpr in C++20 12946035553Spatrick 13046035553Spatrick constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; 13146035553Spatrick constexpr int compare(basic_string_view s) const noexcept; 13246035553Spatrick constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const; 13346035553Spatrick constexpr int compare(size_type pos1, size_type n1, 13446035553Spatrick basic_string_view s, size_type pos2, size_type n2) const; 13546035553Spatrick constexpr int compare(const charT* s) const; 13646035553Spatrick constexpr int compare(size_type pos1, size_type n1, const charT* s) const; 13746035553Spatrick constexpr int compare(size_type pos1, size_type n1, 13846035553Spatrick const charT* s, size_type n2) const; 13946035553Spatrick constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept; 14046035553Spatrick constexpr size_type find(charT c, size_type pos = 0) const noexcept; 14176d0caaeSpatrick constexpr size_type find(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 14276d0caaeSpatrick constexpr size_type find(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension 14346035553Spatrick constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept; 14446035553Spatrick constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; 14576d0caaeSpatrick constexpr size_type rfind(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 14676d0caaeSpatrick constexpr size_type rfind(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension 14746035553Spatrick constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept; 14846035553Spatrick constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; 14976d0caaeSpatrick constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 15076d0caaeSpatrick constexpr size_type find_first_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension 15146035553Spatrick constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept; 15246035553Spatrick constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; 15376d0caaeSpatrick constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 15476d0caaeSpatrick constexpr size_type find_last_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension 15546035553Spatrick constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept; 15646035553Spatrick constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; 15776d0caaeSpatrick constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 15876d0caaeSpatrick constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension 15946035553Spatrick constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept; 16046035553Spatrick constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; 16176d0caaeSpatrick constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 16276d0caaeSpatrick constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension 16346035553Spatrick 16476d0caaeSpatrick constexpr bool starts_with(basic_string_view s) const noexcept; // C++20 16576d0caaeSpatrick constexpr bool starts_with(charT c) const noexcept; // C++20 16676d0caaeSpatrick constexpr bool starts_with(const charT* s) const; // C++20 16776d0caaeSpatrick constexpr bool ends_with(basic_string_view s) const noexcept; // C++20 16876d0caaeSpatrick constexpr bool ends_with(charT c) const noexcept; // C++20 16976d0caaeSpatrick constexpr bool ends_with(const charT* s) const; // C++20 17076d0caaeSpatrick 17176d0caaeSpatrick constexpr bool contains(basic_string_view s) const noexcept; // C++2b 17276d0caaeSpatrick constexpr bool contains(charT c) const noexcept; // C++2b 17376d0caaeSpatrick constexpr bool contains(const charT* s) const; // C++2b 17446035553Spatrick 17546035553Spatrick private: 17646035553Spatrick const_pointer data_; // exposition only 17746035553Spatrick size_type size_; // exposition only 17846035553Spatrick }; 17946035553Spatrick 180*4bdff4beSrobert // basic_string_view deduction guides 181*4bdff4beSrobert template<class It, class End> 182*4bdff4beSrobert basic_string_view(It, End) -> basic_string_view<iter_value_t<It>>; // C++20 183*4bdff4beSrobert template<class Range> 184*4bdff4beSrobert basic_string_view(Range&&) -> basic_string_view<ranges::range_value_t<Range>>; // C++23 185*4bdff4beSrobert 18646035553Spatrick // 7.11, Hash support 18746035553Spatrick template <class T> struct hash; 18846035553Spatrick template <> struct hash<string_view>; 18976d0caaeSpatrick template <> struct hash<u8string_view>; // C++20 19046035553Spatrick template <> struct hash<u16string_view>; 19146035553Spatrick template <> struct hash<u32string_view>; 19246035553Spatrick template <> struct hash<wstring_view>; 19346035553Spatrick 19446035553Spatrick constexpr basic_string_view<char> operator "" sv(const char *str, size_t len) noexcept; 19546035553Spatrick constexpr basic_string_view<wchar_t> operator "" sv(const wchar_t *str, size_t len) noexcept; 19676d0caaeSpatrick constexpr basic_string_view<char8_t> operator "" sv(const char8_t *str, size_t len) noexcept; // C++20 19746035553Spatrick constexpr basic_string_view<char16_t> operator "" sv(const char16_t *str, size_t len) noexcept; 19846035553Spatrick constexpr basic_string_view<char32_t> operator "" sv(const char32_t *str, size_t len) noexcept; 19946035553Spatrick 20046035553Spatrick} // namespace std 20146035553Spatrick 20246035553Spatrick 20346035553Spatrick*/ 20446035553Spatrick 205*4bdff4beSrobert#include <__algorithm/min.h> 206*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler 20746035553Spatrick#include <__config> 208*4bdff4beSrobert#include <__functional/hash.h> 209*4bdff4beSrobert#include <__functional/unary_function.h> 210*4bdff4beSrobert#include <__fwd/string_view.h> 211*4bdff4beSrobert#include <__iterator/concepts.h> 212*4bdff4beSrobert#include <__iterator/readable_traits.h> 213*4bdff4beSrobert#include <__iterator/reverse_iterator.h> 214*4bdff4beSrobert#include <__memory/pointer_traits.h> 215*4bdff4beSrobert#include <__ranges/concepts.h> 216*4bdff4beSrobert#include <__ranges/data.h> 21776d0caaeSpatrick#include <__ranges/enable_borrowed_range.h> 21876d0caaeSpatrick#include <__ranges/enable_view.h> 219*4bdff4beSrobert#include <__ranges/size.h> 220*4bdff4beSrobert#include <__string/char_traits.h> 22176d0caaeSpatrick#include <iosfwd> 22246035553Spatrick#include <limits> 22346035553Spatrick#include <stdexcept> 224*4bdff4beSrobert#include <type_traits> 22546035553Spatrick#include <version> 22646035553Spatrick 227*4bdff4beSrobert// standard-mandated includes 228*4bdff4beSrobert 229*4bdff4beSrobert// [iterator.range] 230*4bdff4beSrobert#include <__iterator/access.h> 231*4bdff4beSrobert#include <__iterator/data.h> 232*4bdff4beSrobert#include <__iterator/empty.h> 233*4bdff4beSrobert#include <__iterator/reverse_access.h> 234*4bdff4beSrobert#include <__iterator/size.h> 235*4bdff4beSrobert 236*4bdff4beSrobert// [string.view.synop] 237*4bdff4beSrobert#include <compare> 238*4bdff4beSrobert 23946035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 24046035553Spatrick# pragma GCC system_header 24146035553Spatrick#endif 24246035553Spatrick 24346035553Spatrick_LIBCPP_PUSH_MACROS 24446035553Spatrick#include <__undef_macros> 24546035553Spatrick 24646035553Spatrick 24746035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD 24846035553Spatrick 249*4bdff4beSrobert// TODO: This is a workaround for some vendors to carry a downstream diff to accept `nullptr` in 250*4bdff4beSrobert// string_view constructors. This can be refactored when this exact form isn't needed anymore. 251*4bdff4beSroberttemplate <class _Traits> 252*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 253*4bdff4beSrobertinline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT { 254*4bdff4beSrobert // This needs to be a single statement for C++11 constexpr 255*4bdff4beSrobert return _LIBCPP_ASSERT(__s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"), _Traits::length(__s); 256*4bdff4beSrobert} 25776d0caaeSpatrick 25876d0caaeSpatricktemplate<class _CharT, class _Traits> 259*4bdff4beSrobertclass basic_string_view { 26046035553Spatrickpublic: 26146035553Spatrick // types 262*4bdff4beSrobert using traits_type = _Traits; 263*4bdff4beSrobert using value_type = _CharT; 264*4bdff4beSrobert using pointer = _CharT*; 265*4bdff4beSrobert using const_pointer = const _CharT*; 266*4bdff4beSrobert using reference = _CharT&; 267*4bdff4beSrobert using const_reference = const _CharT&; 268*4bdff4beSrobert using const_iterator = const_pointer; // See [string.view.iterators] 269*4bdff4beSrobert using iterator = const_iterator; 270*4bdff4beSrobert using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>; 271*4bdff4beSrobert using reverse_iterator = const_reverse_iterator; 272*4bdff4beSrobert using size_type = size_t; 273*4bdff4beSrobert using difference_type = ptrdiff_t; 27446035553Spatrick static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1); 27546035553Spatrick 27646035553Spatrick static_assert((!is_array<value_type>::value), "Character type of basic_string_view must not be an array"); 27746035553Spatrick static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string_view must be standard-layout"); 27846035553Spatrick static_assert(( is_trivial<value_type>::value), "Character type of basic_string_view must be trivial"); 27946035553Spatrick static_assert((is_same<_CharT, typename traits_type::char_type>::value), 28046035553Spatrick "traits_type::char_type must be the same type as CharT"); 28146035553Spatrick 28246035553Spatrick // [string.view.cons], construct/copy 28346035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 284*4bdff4beSrobert basic_string_view() _NOEXCEPT : __data_(nullptr), __size_(0) {} 28546035553Spatrick 286*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 28746035553Spatrick basic_string_view(const basic_string_view&) _NOEXCEPT = default; 28846035553Spatrick 289*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 29046035553Spatrick basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default; 29146035553Spatrick 29246035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 29346035553Spatrick basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT 294*4bdff4beSrobert : __data_(__s), __size_(__len) 29546035553Spatrick { 29646035553Spatrick#if _LIBCPP_STD_VER > 11 29746035553Spatrick _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr"); 29846035553Spatrick#endif 29946035553Spatrick } 30046035553Spatrick 301*4bdff4beSrobert#if _LIBCPP_STD_VER > 17 302*4bdff4beSrobert template <contiguous_iterator _It, sized_sentinel_for<_It> _End> 303*4bdff4beSrobert requires (is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>) 304*4bdff4beSrobert constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end) 305*4bdff4beSrobert : __data_(_VSTD::to_address(__begin)), __size_(__end - __begin) 306*4bdff4beSrobert { 307*4bdff4beSrobert _LIBCPP_ASSERT((__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range"); 308*4bdff4beSrobert } 309*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 17 310*4bdff4beSrobert 311*4bdff4beSrobert#if _LIBCPP_STD_VER > 20 312*4bdff4beSrobert template <class _Range> 313*4bdff4beSrobert requires ( 314*4bdff4beSrobert !is_same_v<remove_cvref_t<_Range>, basic_string_view> && 315*4bdff4beSrobert ranges::contiguous_range<_Range> && 316*4bdff4beSrobert ranges::sized_range<_Range> && 317*4bdff4beSrobert is_same_v<ranges::range_value_t<_Range>, _CharT> && 318*4bdff4beSrobert !is_convertible_v<_Range, const _CharT*> && 319*4bdff4beSrobert (!requires(remove_cvref_t<_Range>& __d) { 320*4bdff4beSrobert __d.operator _VSTD::basic_string_view<_CharT, _Traits>(); 321*4bdff4beSrobert }) && 322*4bdff4beSrobert (!requires { 323*4bdff4beSrobert typename remove_reference_t<_Range>::traits_type; 324*4bdff4beSrobert } || is_same_v<typename remove_reference_t<_Range>::traits_type, _Traits>) 325*4bdff4beSrobert ) 326*4bdff4beSrobert constexpr explicit _LIBCPP_HIDE_FROM_ABI 327*4bdff4beSrobert basic_string_view(_Range&& __r) : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {} 328*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 20 329*4bdff4beSrobert 33046035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 33146035553Spatrick basic_string_view(const _CharT* __s) 332*4bdff4beSrobert : __data_(__s), __size_(_VSTD::__char_traits_length_checked<_Traits>(__s)) {} 33376d0caaeSpatrick 33476d0caaeSpatrick#if _LIBCPP_STD_VER > 20 33576d0caaeSpatrick basic_string_view(nullptr_t) = delete; 33676d0caaeSpatrick#endif 33746035553Spatrick 33846035553Spatrick // [string.view.iterators], iterators 33946035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 34046035553Spatrick const_iterator begin() const _NOEXCEPT { return cbegin(); } 34146035553Spatrick 34246035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 34346035553Spatrick const_iterator end() const _NOEXCEPT { return cend(); } 34446035553Spatrick 34546035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 346*4bdff4beSrobert const_iterator cbegin() const _NOEXCEPT { return __data_; } 34746035553Spatrick 34846035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 349*4bdff4beSrobert const_iterator cend() const _NOEXCEPT { return __data_ + __size_; } 35046035553Spatrick 351*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_INLINE_VISIBILITY 35246035553Spatrick const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } 35346035553Spatrick 354*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_INLINE_VISIBILITY 35546035553Spatrick const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } 35646035553Spatrick 357*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_INLINE_VISIBILITY 35846035553Spatrick const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } 35946035553Spatrick 360*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_INLINE_VISIBILITY 36146035553Spatrick const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } 36246035553Spatrick 36346035553Spatrick // [string.view.capacity], capacity 36446035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 365*4bdff4beSrobert size_type size() const _NOEXCEPT { return __size_; } 36646035553Spatrick 36746035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 368*4bdff4beSrobert size_type length() const _NOEXCEPT { return __size_; } 36946035553Spatrick 37046035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 371*4bdff4beSrobert size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max() / sizeof(value_type); } 37246035553Spatrick 37346035553Spatrick _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 374*4bdff4beSrobert bool empty() const _NOEXCEPT { return __size_ == 0; } 37546035553Spatrick 37646035553Spatrick // [string.view.access], element access 37746035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 37876d0caaeSpatrick const_reference operator[](size_type __pos) const _NOEXCEPT { 379*4bdff4beSrobert return _LIBCPP_ASSERT(__pos < size(), "string_view[] index out of bounds"), __data_[__pos]; 38076d0caaeSpatrick } 38146035553Spatrick 38246035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 38346035553Spatrick const_reference at(size_type __pos) const 38446035553Spatrick { 38546035553Spatrick return __pos >= size() 386*4bdff4beSrobert ? (__throw_out_of_range("string_view::at"), __data_[0]) 387*4bdff4beSrobert : __data_[__pos]; 38846035553Spatrick } 38946035553Spatrick 39046035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 39146035553Spatrick const_reference front() const _NOEXCEPT 39246035553Spatrick { 393*4bdff4beSrobert return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data_[0]; 39446035553Spatrick } 39546035553Spatrick 39646035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 39746035553Spatrick const_reference back() const _NOEXCEPT 39846035553Spatrick { 399*4bdff4beSrobert return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data_[__size_-1]; 40046035553Spatrick } 40146035553Spatrick 40246035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 403*4bdff4beSrobert const_pointer data() const _NOEXCEPT { return __data_; } 40446035553Spatrick 40546035553Spatrick // [string.view.modifiers], modifiers: 406*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 40746035553Spatrick void remove_prefix(size_type __n) _NOEXCEPT 40846035553Spatrick { 40946035553Spatrick _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()"); 410*4bdff4beSrobert __data_ += __n; 411*4bdff4beSrobert __size_ -= __n; 41246035553Spatrick } 41346035553Spatrick 414*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 41546035553Spatrick void remove_suffix(size_type __n) _NOEXCEPT 41646035553Spatrick { 41746035553Spatrick _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()"); 418*4bdff4beSrobert __size_ -= __n; 41946035553Spatrick } 42046035553Spatrick 421*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 42246035553Spatrick void swap(basic_string_view& __other) _NOEXCEPT 42346035553Spatrick { 424*4bdff4beSrobert const value_type *__p = __data_; 425*4bdff4beSrobert __data_ = __other.__data_; 426*4bdff4beSrobert __other.__data_ = __p; 42746035553Spatrick 428*4bdff4beSrobert size_type __sz = __size_; 429*4bdff4beSrobert __size_ = __other.__size_; 430*4bdff4beSrobert __other.__size_ = __sz; 43146035553Spatrick } 43246035553Spatrick 433*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 43446035553Spatrick size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const 43546035553Spatrick { 43646035553Spatrick if (__pos > size()) 43746035553Spatrick __throw_out_of_range("string_view::copy"); 43846035553Spatrick size_type __rlen = _VSTD::min(__n, size() - __pos); 43946035553Spatrick _Traits::copy(__s, data() + __pos, __rlen); 44046035553Spatrick return __rlen; 44146035553Spatrick } 44246035553Spatrick 44346035553Spatrick _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 44446035553Spatrick basic_string_view substr(size_type __pos = 0, size_type __n = npos) const 44546035553Spatrick { 44646035553Spatrick return __pos > size() 44746035553Spatrick ? (__throw_out_of_range("string_view::substr"), basic_string_view()) 44846035553Spatrick : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); 44946035553Spatrick } 45046035553Spatrick 451*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT 45246035553Spatrick { 45346035553Spatrick size_type __rlen = _VSTD::min(size(), __sv.size()); 45446035553Spatrick int __retval = _Traits::compare(data(), __sv.data(), __rlen); 45546035553Spatrick if (__retval == 0) // first __rlen chars matched 45646035553Spatrick __retval = size() == __sv.size() ? 0 : (size() < __sv.size() ? -1 : 1); 45746035553Spatrick return __retval; 45846035553Spatrick } 45946035553Spatrick 460*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 46146035553Spatrick int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const 46246035553Spatrick { 46346035553Spatrick return substr(__pos1, __n1).compare(__sv); 46446035553Spatrick } 46546035553Spatrick 466*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 46746035553Spatrick int compare( size_type __pos1, size_type __n1, 46846035553Spatrick basic_string_view __sv, size_type __pos2, size_type __n2) const 46946035553Spatrick { 47046035553Spatrick return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 47146035553Spatrick } 47246035553Spatrick 473*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 47446035553Spatrick int compare(const _CharT* __s) const _NOEXCEPT 47546035553Spatrick { 47646035553Spatrick return compare(basic_string_view(__s)); 47746035553Spatrick } 47846035553Spatrick 479*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 48046035553Spatrick int compare(size_type __pos1, size_type __n1, const _CharT* __s) const 48146035553Spatrick { 48246035553Spatrick return substr(__pos1, __n1).compare(basic_string_view(__s)); 48346035553Spatrick } 48446035553Spatrick 485*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 48646035553Spatrick int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const 48746035553Spatrick { 48846035553Spatrick return substr(__pos1, __n1).compare(basic_string_view(__s, __n2)); 48946035553Spatrick } 49046035553Spatrick 49146035553Spatrick // find 492*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 49346035553Spatrick size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT 49446035553Spatrick { 49546035553Spatrick _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); 496*4bdff4beSrobert return std::__str_find<value_type, size_type, traits_type, npos> 49746035553Spatrick (data(), size(), __s.data(), __pos, __s.size()); 49846035553Spatrick } 49946035553Spatrick 500*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 50146035553Spatrick size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT 50246035553Spatrick { 503*4bdff4beSrobert return std::__str_find<value_type, size_type, traits_type, npos> 50446035553Spatrick (data(), size(), __c, __pos); 50546035553Spatrick } 50646035553Spatrick 507*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 50876d0caaeSpatrick size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 50946035553Spatrick { 51046035553Spatrick _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); 511*4bdff4beSrobert return std::__str_find<value_type, size_type, traits_type, npos> 51246035553Spatrick (data(), size(), __s, __pos, __n); 51346035553Spatrick } 51446035553Spatrick 515*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 51676d0caaeSpatrick size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT 51746035553Spatrick { 51846035553Spatrick _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); 519*4bdff4beSrobert return std::__str_find<value_type, size_type, traits_type, npos> 52046035553Spatrick (data(), size(), __s, __pos, traits_type::length(__s)); 52146035553Spatrick } 52246035553Spatrick 52346035553Spatrick // rfind 524*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 52546035553Spatrick size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT 52646035553Spatrick { 52746035553Spatrick _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); 528*4bdff4beSrobert return std::__str_rfind<value_type, size_type, traits_type, npos> 52946035553Spatrick (data(), size(), __s.data(), __pos, __s.size()); 53046035553Spatrick } 53146035553Spatrick 532*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 53346035553Spatrick size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT 53446035553Spatrick { 535*4bdff4beSrobert return std::__str_rfind<value_type, size_type, traits_type, npos> 53646035553Spatrick (data(), size(), __c, __pos); 53746035553Spatrick } 53846035553Spatrick 539*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 54076d0caaeSpatrick size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 54146035553Spatrick { 54246035553Spatrick _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); 543*4bdff4beSrobert return std::__str_rfind<value_type, size_type, traits_type, npos> 54446035553Spatrick (data(), size(), __s, __pos, __n); 54546035553Spatrick } 54646035553Spatrick 547*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 54876d0caaeSpatrick size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT 54946035553Spatrick { 55046035553Spatrick _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr"); 551*4bdff4beSrobert return std::__str_rfind<value_type, size_type, traits_type, npos> 55246035553Spatrick (data(), size(), __s, __pos, traits_type::length(__s)); 55346035553Spatrick } 55446035553Spatrick 55546035553Spatrick // find_first_of 556*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 55746035553Spatrick size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT 55846035553Spatrick { 55946035553Spatrick _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr"); 560*4bdff4beSrobert return std::__str_find_first_of<value_type, size_type, traits_type, npos> 56146035553Spatrick (data(), size(), __s.data(), __pos, __s.size()); 56246035553Spatrick } 56346035553Spatrick 564*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 56546035553Spatrick size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT 56646035553Spatrick { return find(__c, __pos); } 56746035553Spatrick 568*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 56976d0caaeSpatrick size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 57046035553Spatrick { 57146035553Spatrick _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); 572*4bdff4beSrobert return std::__str_find_first_of<value_type, size_type, traits_type, npos> 57346035553Spatrick (data(), size(), __s, __pos, __n); 57446035553Spatrick } 57546035553Spatrick 576*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 57776d0caaeSpatrick size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT 57846035553Spatrick { 57946035553Spatrick _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr"); 580*4bdff4beSrobert return std::__str_find_first_of<value_type, size_type, traits_type, npos> 58146035553Spatrick (data(), size(), __s, __pos, traits_type::length(__s)); 58246035553Spatrick } 58346035553Spatrick 58446035553Spatrick // find_last_of 585*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 58646035553Spatrick size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT 58746035553Spatrick { 58846035553Spatrick _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr"); 589*4bdff4beSrobert return std::__str_find_last_of<value_type, size_type, traits_type, npos> 59046035553Spatrick (data(), size(), __s.data(), __pos, __s.size()); 59146035553Spatrick } 59246035553Spatrick 593*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 59446035553Spatrick size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT 59546035553Spatrick { return rfind(__c, __pos); } 59646035553Spatrick 597*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 59876d0caaeSpatrick size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 59946035553Spatrick { 60046035553Spatrick _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); 601*4bdff4beSrobert return std::__str_find_last_of<value_type, size_type, traits_type, npos> 60246035553Spatrick (data(), size(), __s, __pos, __n); 60346035553Spatrick } 60446035553Spatrick 605*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 60676d0caaeSpatrick size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT 60746035553Spatrick { 60846035553Spatrick _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr"); 609*4bdff4beSrobert return std::__str_find_last_of<value_type, size_type, traits_type, npos> 61046035553Spatrick (data(), size(), __s, __pos, traits_type::length(__s)); 61146035553Spatrick } 61246035553Spatrick 61346035553Spatrick // find_first_not_of 614*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 61546035553Spatrick size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT 61646035553Spatrick { 61746035553Spatrick _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr"); 618*4bdff4beSrobert return std::__str_find_first_not_of<value_type, size_type, traits_type, npos> 61946035553Spatrick (data(), size(), __s.data(), __pos, __s.size()); 62046035553Spatrick } 62146035553Spatrick 622*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 62346035553Spatrick size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT 62446035553Spatrick { 625*4bdff4beSrobert return std::__str_find_first_not_of<value_type, size_type, traits_type, npos> 62646035553Spatrick (data(), size(), __c, __pos); 62746035553Spatrick } 62846035553Spatrick 629*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 63076d0caaeSpatrick size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 63146035553Spatrick { 63246035553Spatrick _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); 633*4bdff4beSrobert return std::__str_find_first_not_of<value_type, size_type, traits_type, npos> 63446035553Spatrick (data(), size(), __s, __pos, __n); 63546035553Spatrick } 63646035553Spatrick 637*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 63876d0caaeSpatrick size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT 63946035553Spatrick { 64046035553Spatrick _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); 641*4bdff4beSrobert return std::__str_find_first_not_of<value_type, size_type, traits_type, npos> 64246035553Spatrick (data(), size(), __s, __pos, traits_type::length(__s)); 64346035553Spatrick } 64446035553Spatrick 64546035553Spatrick // find_last_not_of 646*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 64746035553Spatrick size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT 64846035553Spatrick { 64946035553Spatrick _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr"); 650*4bdff4beSrobert return std::__str_find_last_not_of<value_type, size_type, traits_type, npos> 65146035553Spatrick (data(), size(), __s.data(), __pos, __s.size()); 65246035553Spatrick } 65346035553Spatrick 654*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 65546035553Spatrick size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT 65646035553Spatrick { 657*4bdff4beSrobert return std::__str_find_last_not_of<value_type, size_type, traits_type, npos> 65846035553Spatrick (data(), size(), __c, __pos); 65946035553Spatrick } 66046035553Spatrick 661*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 66276d0caaeSpatrick size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 66346035553Spatrick { 66446035553Spatrick _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); 665*4bdff4beSrobert return std::__str_find_last_not_of<value_type, size_type, traits_type, npos> 66646035553Spatrick (data(), size(), __s, __pos, __n); 66746035553Spatrick } 66846035553Spatrick 669*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 67076d0caaeSpatrick size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT 67146035553Spatrick { 67246035553Spatrick _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); 673*4bdff4beSrobert return std::__str_find_last_not_of<value_type, size_type, traits_type, npos> 67446035553Spatrick (data(), size(), __s, __pos, traits_type::length(__s)); 67546035553Spatrick } 67646035553Spatrick 67746035553Spatrick#if _LIBCPP_STD_VER > 17 678*4bdff4beSrobert constexpr _LIBCPP_INLINE_VISIBILITY 679*4bdff4beSrobert bool starts_with(basic_string_view __s) const noexcept 68046035553Spatrick { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; } 68146035553Spatrick 682*4bdff4beSrobert constexpr _LIBCPP_INLINE_VISIBILITY 683*4bdff4beSrobert bool starts_with(value_type __c) const noexcept 68446035553Spatrick { return !empty() && _Traits::eq(front(), __c); } 68546035553Spatrick 686*4bdff4beSrobert constexpr _LIBCPP_INLINE_VISIBILITY 687*4bdff4beSrobert bool starts_with(const value_type* __s) const noexcept 68846035553Spatrick { return starts_with(basic_string_view(__s)); } 68946035553Spatrick 690*4bdff4beSrobert constexpr _LIBCPP_INLINE_VISIBILITY 691*4bdff4beSrobert bool ends_with(basic_string_view __s) const noexcept 69246035553Spatrick { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; } 69346035553Spatrick 694*4bdff4beSrobert constexpr _LIBCPP_INLINE_VISIBILITY 695*4bdff4beSrobert bool ends_with(value_type __c) const noexcept 69646035553Spatrick { return !empty() && _Traits::eq(back(), __c); } 69746035553Spatrick 698*4bdff4beSrobert constexpr _LIBCPP_INLINE_VISIBILITY 699*4bdff4beSrobert bool ends_with(const value_type* __s) const noexcept 70046035553Spatrick { return ends_with(basic_string_view(__s)); } 70146035553Spatrick#endif 70246035553Spatrick 70376d0caaeSpatrick#if _LIBCPP_STD_VER > 20 70476d0caaeSpatrick constexpr _LIBCPP_INLINE_VISIBILITY 70576d0caaeSpatrick bool contains(basic_string_view __sv) const noexcept 70676d0caaeSpatrick { return find(__sv) != npos; } 70776d0caaeSpatrick 70876d0caaeSpatrick constexpr _LIBCPP_INLINE_VISIBILITY 70976d0caaeSpatrick bool contains(value_type __c) const noexcept 71076d0caaeSpatrick { return find(__c) != npos; } 71176d0caaeSpatrick 71276d0caaeSpatrick constexpr _LIBCPP_INLINE_VISIBILITY 71376d0caaeSpatrick bool contains(const value_type* __s) const 71476d0caaeSpatrick { return find(__s) != npos; } 71576d0caaeSpatrick#endif 71676d0caaeSpatrick 71746035553Spatrickprivate: 718*4bdff4beSrobert const value_type* __data_; 719*4bdff4beSrobert size_type __size_; 72046035553Spatrick}; 721*4bdff4beSrobert_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view); 72246035553Spatrick 723*4bdff4beSrobert#if _LIBCPP_STD_VER > 17 72476d0caaeSpatricktemplate <class _CharT, class _Traits> 72576d0caaeSpatrickinline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true; 72676d0caaeSpatrick 72776d0caaeSpatricktemplate <class _CharT, class _Traits> 72876d0caaeSpatrickinline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true; 729*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 17 730*4bdff4beSrobert 731*4bdff4beSrobert// [string.view.deduct] 732*4bdff4beSrobert 733*4bdff4beSrobert#if _LIBCPP_STD_VER > 17 734*4bdff4beSroberttemplate <contiguous_iterator _It, sized_sentinel_for<_It> _End> 735*4bdff4beSrobert basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>; 736*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 17 737*4bdff4beSrobert 738*4bdff4beSrobert 739*4bdff4beSrobert#if _LIBCPP_STD_VER > 20 740*4bdff4beSroberttemplate <ranges::contiguous_range _Range> 741*4bdff4beSrobert basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>; 742*4bdff4beSrobert#endif 74346035553Spatrick 74446035553Spatrick// [string.view.comparison] 74546035553Spatrick// operator == 74646035553Spatricktemplate<class _CharT, class _Traits> 747*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 74846035553Spatrickbool operator==(basic_string_view<_CharT, _Traits> __lhs, 74946035553Spatrick basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 75046035553Spatrick{ 75146035553Spatrick if (__lhs.size() != __rhs.size()) return false; 75246035553Spatrick return __lhs.compare(__rhs) == 0; 75346035553Spatrick} 75446035553Spatrick 755*4bdff4beSrobert// The dummy default template parameters are used to work around a MSVC issue with mangling, see VSO-409326 for details. 756*4bdff4beSrobert// This applies to the other sufficient overloads below for the other comparison operators. 757*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 1> 758*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 75946035553Spatrickbool operator==(basic_string_view<_CharT, _Traits> __lhs, 760*4bdff4beSrobert __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT 76146035553Spatrick{ 76246035553Spatrick if (__lhs.size() != __rhs.size()) return false; 76346035553Spatrick return __lhs.compare(__rhs) == 0; 76446035553Spatrick} 76546035553Spatrick 766*4bdff4beSrobert#if _LIBCPP_STD_VER < 20 767*4bdff4beSrobert// This overload is automatically generated in C++20. 768*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 2> 769*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 770*4bdff4beSrobertbool operator==(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, 77146035553Spatrick basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 77246035553Spatrick{ 77346035553Spatrick if (__lhs.size() != __rhs.size()) return false; 77446035553Spatrick return __lhs.compare(__rhs) == 0; 77546035553Spatrick} 776*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 17 77746035553Spatrick 778*4bdff4beSrobert// operator <=> 779*4bdff4beSrobert 780*4bdff4beSrobert#if _LIBCPP_STD_VER > 17 781*4bdff4beSrobert 782*4bdff4beSroberttemplate <class _CharT, class _Traits> 783*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI constexpr auto 784*4bdff4beSrobertoperator<=>(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) noexcept { 785*4bdff4beSrobert if constexpr (requires { typename _Traits::comparison_category; }) { 786*4bdff4beSrobert // [string.view]/4 787*4bdff4beSrobert static_assert( 788*4bdff4beSrobert __comparison_category<typename _Traits::comparison_category>, 789*4bdff4beSrobert "return type is not a comparison category type"); 790*4bdff4beSrobert return static_cast<typename _Traits::comparison_category>(__lhs.compare(__rhs) <=> 0); 791*4bdff4beSrobert } else { 792*4bdff4beSrobert return static_cast<weak_ordering>(__lhs.compare(__rhs) <=> 0); 793*4bdff4beSrobert } 794*4bdff4beSrobert} 795*4bdff4beSrobert 796*4bdff4beSroberttemplate <class _CharT, class _Traits, int = 1> 797*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>( 798*4bdff4beSrobert basic_string_view<_CharT, _Traits> __lhs, type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) noexcept { 799*4bdff4beSrobert if constexpr (requires { typename _Traits::comparison_category; }) { 800*4bdff4beSrobert // [string.view]/4 801*4bdff4beSrobert static_assert( 802*4bdff4beSrobert __comparison_category<typename _Traits::comparison_category>, 803*4bdff4beSrobert "return type is not a comparison category type"); 804*4bdff4beSrobert return static_cast<typename _Traits::comparison_category>(__lhs.compare(__rhs) <=> 0); 805*4bdff4beSrobert } else { 806*4bdff4beSrobert return static_cast<weak_ordering>(__lhs.compare(__rhs) <=> 0); 807*4bdff4beSrobert } 808*4bdff4beSrobert} 809*4bdff4beSrobert 810*4bdff4beSrobert#else // _LIBCPP_STD_VER > 17 81146035553Spatrick 81246035553Spatrick// operator != 81346035553Spatricktemplate<class _CharT, class _Traits> 814*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 81546035553Spatrickbool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 81646035553Spatrick{ 81746035553Spatrick if (__lhs.size() != __rhs.size()) 81846035553Spatrick return true; 81946035553Spatrick return __lhs.compare(__rhs) != 0; 82046035553Spatrick} 82146035553Spatrick 822*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 1> 823*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 82446035553Spatrickbool operator!=(basic_string_view<_CharT, _Traits> __lhs, 825*4bdff4beSrobert __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT 82646035553Spatrick{ 82746035553Spatrick if (__lhs.size() != __rhs.size()) 82846035553Spatrick return true; 82946035553Spatrick return __lhs.compare(__rhs) != 0; 83046035553Spatrick} 83146035553Spatrick 832*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 2> 833*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 834*4bdff4beSrobertbool operator!=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, 83546035553Spatrick basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 83646035553Spatrick{ 83746035553Spatrick if (__lhs.size() != __rhs.size()) 83846035553Spatrick return true; 83946035553Spatrick return __lhs.compare(__rhs) != 0; 84046035553Spatrick} 84146035553Spatrick 84246035553Spatrick 84346035553Spatrick// operator < 84446035553Spatricktemplate<class _CharT, class _Traits> 845*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 84646035553Spatrickbool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 84746035553Spatrick{ 84846035553Spatrick return __lhs.compare(__rhs) < 0; 84946035553Spatrick} 85046035553Spatrick 851*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 1> 852*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 85346035553Spatrickbool operator<(basic_string_view<_CharT, _Traits> __lhs, 854*4bdff4beSrobert __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT 85546035553Spatrick{ 85646035553Spatrick return __lhs.compare(__rhs) < 0; 85746035553Spatrick} 85846035553Spatrick 859*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 2> 860*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 861*4bdff4beSrobertbool operator<(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, 86246035553Spatrick basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 86346035553Spatrick{ 86446035553Spatrick return __lhs.compare(__rhs) < 0; 86546035553Spatrick} 86646035553Spatrick 86746035553Spatrick 86846035553Spatrick// operator > 86946035553Spatricktemplate<class _CharT, class _Traits> 870*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 87146035553Spatrickbool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 87246035553Spatrick{ 87346035553Spatrick return __lhs.compare(__rhs) > 0; 87446035553Spatrick} 87546035553Spatrick 876*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 1> 877*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 87846035553Spatrickbool operator>(basic_string_view<_CharT, _Traits> __lhs, 879*4bdff4beSrobert __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT 88046035553Spatrick{ 88146035553Spatrick return __lhs.compare(__rhs) > 0; 88246035553Spatrick} 88346035553Spatrick 884*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 2> 885*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 886*4bdff4beSrobertbool operator>(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, 88746035553Spatrick basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 88846035553Spatrick{ 88946035553Spatrick return __lhs.compare(__rhs) > 0; 89046035553Spatrick} 89146035553Spatrick 89246035553Spatrick 89346035553Spatrick// operator <= 89446035553Spatricktemplate<class _CharT, class _Traits> 895*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 89646035553Spatrickbool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 89746035553Spatrick{ 89846035553Spatrick return __lhs.compare(__rhs) <= 0; 89946035553Spatrick} 90046035553Spatrick 901*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 1> 902*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 90346035553Spatrickbool operator<=(basic_string_view<_CharT, _Traits> __lhs, 904*4bdff4beSrobert __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT 90546035553Spatrick{ 90646035553Spatrick return __lhs.compare(__rhs) <= 0; 90746035553Spatrick} 90846035553Spatrick 909*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 2> 910*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 911*4bdff4beSrobertbool operator<=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, 91246035553Spatrick basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 91346035553Spatrick{ 91446035553Spatrick return __lhs.compare(__rhs) <= 0; 91546035553Spatrick} 91646035553Spatrick 91746035553Spatrick 91846035553Spatrick// operator >= 91946035553Spatricktemplate<class _CharT, class _Traits> 920*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 92146035553Spatrickbool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 92246035553Spatrick{ 92346035553Spatrick return __lhs.compare(__rhs) >= 0; 92446035553Spatrick} 92546035553Spatrick 92646035553Spatrick 927*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 1> 928*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 92946035553Spatrickbool operator>=(basic_string_view<_CharT, _Traits> __lhs, 930*4bdff4beSrobert __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT 93146035553Spatrick{ 93246035553Spatrick return __lhs.compare(__rhs) >= 0; 93346035553Spatrick} 93446035553Spatrick 935*4bdff4beSroberttemplate<class _CharT, class _Traits, int = 2> 936*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY 937*4bdff4beSrobertbool operator>=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, 93846035553Spatrick basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 93946035553Spatrick{ 94046035553Spatrick return __lhs.compare(__rhs) >= 0; 94146035553Spatrick} 94246035553Spatrick 943*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 17 94446035553Spatrick 94546035553Spatricktemplate<class _CharT, class _Traits> 946*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 94746035553Spatrickoperator<<(basic_ostream<_CharT, _Traits>& __os, 94846035553Spatrick basic_string_view<_CharT, _Traits> __str); 94946035553Spatrick 95046035553Spatrick// [string.view.hash] 95146035553Spatricktemplate<class _CharT> 952*4bdff4beSrobertstruct __string_view_hash : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> 95346035553Spatrick{ 95446035553Spatrick _LIBCPP_INLINE_VISIBILITY 95546035553Spatrick size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT { 956*4bdff4beSrobert return std::__do_string_hash(__val.data(), __val.data() + __val.size()); 95746035553Spatrick } 95846035553Spatrick}; 95946035553Spatrick 960*4bdff4beSroberttemplate <> 961*4bdff4beSrobertstruct hash<basic_string_view<char, char_traits<char> > > : __string_view_hash<char> {}; 962*4bdff4beSrobert 963*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_CHAR8_T 964*4bdff4beSroberttemplate <> 965*4bdff4beSrobertstruct hash<basic_string_view<char8_t, char_traits<char8_t> > > : __string_view_hash<char8_t> {}; 966*4bdff4beSrobert#endif 967*4bdff4beSrobert 968*4bdff4beSroberttemplate <> 969*4bdff4beSrobertstruct hash<basic_string_view<char16_t, char_traits<char16_t> > > : __string_view_hash<char16_t> {}; 970*4bdff4beSrobert 971*4bdff4beSroberttemplate <> 972*4bdff4beSrobertstruct hash<basic_string_view<char32_t, char_traits<char32_t> > > : __string_view_hash<char32_t> {}; 973*4bdff4beSrobert 974*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 975*4bdff4beSroberttemplate <> 976*4bdff4beSrobertstruct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {}; 977*4bdff4beSrobert#endif 97846035553Spatrick 97946035553Spatrick#if _LIBCPP_STD_VER > 11 98046035553Spatrickinline namespace literals 98146035553Spatrick{ 98246035553Spatrick inline namespace string_view_literals 98346035553Spatrick { 98446035553Spatrick inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 98546035553Spatrick basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT 98646035553Spatrick { 98746035553Spatrick return basic_string_view<char> (__str, __len); 98846035553Spatrick } 98946035553Spatrick 990*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 99146035553Spatrick inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 99246035553Spatrick basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT 99346035553Spatrick { 99446035553Spatrick return basic_string_view<wchar_t> (__str, __len); 99546035553Spatrick } 996*4bdff4beSrobert#endif 99746035553Spatrick 99876d0caaeSpatrick#ifndef _LIBCPP_HAS_NO_CHAR8_T 99946035553Spatrick inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 100046035553Spatrick basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT 100146035553Spatrick { 100246035553Spatrick return basic_string_view<char8_t> (__str, __len); 100346035553Spatrick } 100446035553Spatrick#endif 100546035553Spatrick 100646035553Spatrick inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 100746035553Spatrick basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT 100846035553Spatrick { 100946035553Spatrick return basic_string_view<char16_t> (__str, __len); 101046035553Spatrick } 101146035553Spatrick 101246035553Spatrick inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 101346035553Spatrick basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT 101446035553Spatrick { 101546035553Spatrick return basic_string_view<char32_t> (__str, __len); 101646035553Spatrick } 1017*4bdff4beSrobert } // namespace string_view_literals 1018*4bdff4beSrobert} // namespace literals 101946035553Spatrick#endif 102046035553Spatrick_LIBCPP_END_NAMESPACE_STD 102146035553Spatrick 102246035553Spatrick_LIBCPP_POP_MACROS 102346035553Spatrick 1024*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 1025*4bdff4beSrobert# include <algorithm> 1026*4bdff4beSrobert# include <concepts> 1027*4bdff4beSrobert# include <functional> 1028*4bdff4beSrobert# include <iterator> 1029*4bdff4beSrobert#endif 1030*4bdff4beSrobert 103146035553Spatrick#endif // _LIBCPP_STRING_VIEW 1032