cosmopolitan/third_party/libcxx/string_view

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

949 lines
41 KiB
Text
Raw Permalink Normal View History

// -*- C++ -*-
2024-05-27 09:12:27 +00:00
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_STRING_VIEW
#define _LIBCPP_STRING_VIEW
// clang-format off
2024-05-27 09:12:27 +00:00
/*
Prove that Makefile is fully defined The whole repository is now buildable with GNU Make Landlock sandboxing. This proves that no Makefile targets exist which touch files other than their declared prerequisites. In order to do this, we had to: 1. Stop code morphing GCC output in package.com and instead run a newly introduced FIXUPOBJ.COM command after GCC invocations. 2. Disable all the crumby Python unit tests that do things like create files in the current directory, or rename() files between folders. This ended up being a lot of tests, but most of them are still ok. 3. Introduce an .UNSANDBOXED variable to GNU Make to disable Landlock. We currently only do this for things like `make tags`. 4. This change deletes some GNU Make code that was preventing the execve() optimization from working. This means it should no longer be necessary in most cases for command invocations to be indirected through the cocmd interpreter. 5. Missing dependencies had to be declared in certain places, in cases where they couldn't be automatically determined by MKDEPS.COM 6. The libcxx header situation has finally been tamed. One of the things that makes this difficult is MKDEPS.COM only wants to consider the first 64kb of a file, in order to go fast. But libcxx likes to have #include lines buried after huge documentation. 7. An .UNVEIL variable has been introduced to GNU Make just in case we ever wish to explicitly specify additional things that need to be whitelisted which aren't strictly prerequisites. This works in a manner similar to the recently introduced .EXTRA_PREREQS feature. There's now a new build/bootstrap/make.com prebuilt binary available. It should no longer be possible to write invalid Makefile code.
2022-08-06 10:51:50 +00:00
2024-05-27 09:12:27 +00:00
string_view synopsis
Prove that Makefile is fully defined The whole repository is now buildable with GNU Make Landlock sandboxing. This proves that no Makefile targets exist which touch files other than their declared prerequisites. In order to do this, we had to: 1. Stop code morphing GCC output in package.com and instead run a newly introduced FIXUPOBJ.COM command after GCC invocations. 2. Disable all the crumby Python unit tests that do things like create files in the current directory, or rename() files between folders. This ended up being a lot of tests, but most of them are still ok. 3. Introduce an .UNSANDBOXED variable to GNU Make to disable Landlock. We currently only do this for things like `make tags`. 4. This change deletes some GNU Make code that was preventing the execve() optimization from working. This means it should no longer be necessary in most cases for command invocations to be indirected through the cocmd interpreter. 5. Missing dependencies had to be declared in certain places, in cases where they couldn't be automatically determined by MKDEPS.COM 6. The libcxx header situation has finally been tamed. One of the things that makes this difficult is MKDEPS.COM only wants to consider the first 64kb of a file, in order to go fast. But libcxx likes to have #include lines buried after huge documentation. 7. An .UNVEIL variable has been introduced to GNU Make just in case we ever wish to explicitly specify additional things that need to be whitelisted which aren't strictly prerequisites. This works in a manner similar to the recently introduced .EXTRA_PREREQS feature. There's now a new build/bootstrap/make.com prebuilt binary available. It should no longer be possible to write invalid Makefile code.
2022-08-06 10:51:50 +00:00
2024-05-27 09:12:27 +00:00
#include <compare>
namespace std {
// 7.2, Class template basic_string_view
template<class charT, class traits = char_traits<charT>>
class basic_string_view;
2024-05-27 09:12:27 +00:00
template<class charT, class traits>
inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true;
template<class charT, class traits>
inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20
// 7.9, basic_string_view non-member comparison functions
template<class charT, class traits>
constexpr bool operator==(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) noexcept;
2024-05-27 09:12:27 +00:00
template<class charT, class traits> // Removed in C++20
constexpr bool operator!=(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) noexcept;
2024-05-27 09:12:27 +00:00
template<class charT, class traits> // Removed in C++20
constexpr bool operator< (basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) noexcept;
2024-05-27 09:12:27 +00:00
template<class charT, class traits> // Removed in C++20
constexpr bool operator> (basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) noexcept;
2024-05-27 09:12:27 +00:00
template<class charT, class traits> // Removed in C++20
constexpr bool operator<=(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) noexcept;
2024-05-27 09:12:27 +00:00
template<class charT, class traits> // Removed in C++20
constexpr bool operator>=(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) noexcept;
2024-05-27 09:12:27 +00:00
template<class charT, class traits> // Since C++20
constexpr see below operator<=>(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) noexcept;
// see below, sufficient additional overloads of comparison functions
// 7.10, Inserters and extractors
template<class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,
basic_string_view<charT, traits> str);
// basic_string_view typedef names
typedef basic_string_view<char> string_view;
2024-05-27 09:12:27 +00:00
typedef basic_string_view<char8_t> u8string_view; // C++20
typedef basic_string_view<char16_t> u16string_view;
typedef basic_string_view<char32_t> u32string_view;
typedef basic_string_view<wchar_t> wstring_view;
template<class charT, class traits = char_traits<charT>>
class basic_string_view {
public:
// types
typedef traits traits_type;
typedef charT value_type;
typedef charT* pointer;
typedef const charT* const_pointer;
typedef charT& reference;
typedef const charT& const_reference;
typedef implementation-defined const_iterator;
typedef const_iterator iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef const_reverse_iterator reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
static constexpr size_type npos = size_type(-1);
// 7.3, basic_string_view constructors and assignment operators
constexpr basic_string_view() noexcept;
constexpr basic_string_view(const basic_string_view&) noexcept = default;
basic_string_view& operator=(const basic_string_view&) noexcept = default;
template<class Allocator>
constexpr basic_string_view(const charT* str);
2024-05-27 09:12:27 +00:00
basic_string_view(nullptr_t) = delete; // C++23
constexpr basic_string_view(const charT* str, size_type len);
2024-05-27 09:12:27 +00:00
template <class It, class End>
constexpr basic_string_view(It begin, End end); // C++20
template <class Range>
constexpr basic_string_view(Range&& r); // C++23
// 7.4, basic_string_view iterator support
constexpr const_iterator begin() const noexcept;
constexpr const_iterator end() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
// 7.5, basic_string_view capacity
constexpr size_type size() const noexcept;
constexpr size_type length() const noexcept;
constexpr size_type max_size() const noexcept;
constexpr bool empty() const noexcept;
// 7.6, basic_string_view element access
constexpr const_reference operator[](size_type pos) const;
constexpr const_reference at(size_type pos) const;
constexpr const_reference front() const;
constexpr const_reference back() const;
constexpr const_pointer data() const noexcept;
// 7.7, basic_string_view modifiers
constexpr void remove_prefix(size_type n);
constexpr void remove_suffix(size_type n);
constexpr void swap(basic_string_view& s) noexcept;
2024-05-27 09:12:27 +00:00
size_type copy(charT* s, size_type n, size_type pos = 0) const; // constexpr in C++20
constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
constexpr int compare(basic_string_view s) const noexcept;
constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
constexpr int compare(size_type pos1, size_type n1,
basic_string_view s, size_type pos2, size_type n2) const;
constexpr int compare(const charT* s) const;
constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
constexpr int compare(size_type pos1, size_type n1,
const charT* s, size_type n2) const;
constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
constexpr size_type find(charT c, size_type pos = 0) const noexcept;
2024-05-27 09:12:27 +00:00
constexpr size_type find(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
constexpr size_type find(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
2024-05-27 09:12:27 +00:00
constexpr size_type rfind(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
constexpr size_type rfind(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
2024-05-27 09:12:27 +00:00
constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
constexpr size_type find_first_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
2024-05-27 09:12:27 +00:00
constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
constexpr size_type find_last_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
2024-05-27 09:12:27 +00:00
constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
2024-05-27 09:12:27 +00:00
constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
2024-05-27 09:12:27 +00:00
constexpr bool starts_with(basic_string_view s) const noexcept; // C++20
constexpr bool starts_with(charT c) const noexcept; // C++20
constexpr bool starts_with(const charT* s) const; // C++20
constexpr bool ends_with(basic_string_view s) const noexcept; // C++20
constexpr bool ends_with(charT c) const noexcept; // C++20
constexpr bool ends_with(const charT* s) const; // C++20
constexpr bool contains(basic_string_view s) const noexcept; // C++23
constexpr bool contains(charT c) const noexcept; // C++23
constexpr bool contains(const charT* s) const; // C++23
private:
const_pointer data_; // exposition only
size_type size_; // exposition only
};
2024-05-27 09:12:27 +00:00
// basic_string_view deduction guides
template<class It, class End>
basic_string_view(It, End) -> basic_string_view<iter_value_t<It>>; // C++20
template<class Range>
basic_string_view(Range&&) -> basic_string_view<ranges::range_value_t<Range>>; // C++23
// 7.11, Hash support
template <class T> struct hash;
template <> struct hash<string_view>;
2024-05-27 09:12:27 +00:00
template <> struct hash<u8string_view>; // C++20
template <> struct hash<u16string_view>;
template <> struct hash<u32string_view>;
template <> struct hash<wstring_view>;
constexpr basic_string_view<char> operator""sv(const char *str, size_t len) noexcept;
constexpr basic_string_view<wchar_t> operator""sv(const wchar_t *str, size_t len) noexcept;
constexpr basic_string_view<char8_t> operator""sv(const char8_t *str, size_t len) noexcept; // C++20
constexpr basic_string_view<char16_t> operator""sv(const char16_t *str, size_t len) noexcept;
constexpr basic_string_view<char32_t> operator""sv(const char32_t *str, size_t len) noexcept;
} // namespace std
*/
// clang-format on
2024-05-27 09:12:27 +00:00
#include <__algorithm/min.h>
#include <__assert>
2024-05-27 09:12:27 +00:00
#include <__config>
#include <__functional/hash.h>
#include <__functional/unary_function.h>
#include <__fwd/ostream.h>
2024-05-27 09:12:27 +00:00
#include <__fwd/string_view.h>
#include <__iterator/bounded_iter.h>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
2024-05-27 09:12:27 +00:00
#include <__iterator/reverse_iterator.h>
#include <__iterator/wrap_iter.h>
2024-05-27 09:12:27 +00:00
#include <__memory/pointer_traits.h>
#include <__ranges/concepts.h>
#include <__ranges/data.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/enable_view.h>
#include <__ranges/size.h>
#include <__string/char_traits.h>
#include <__type_traits/is_array.h>
#include <__type_traits/is_convertible.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_standard_layout.h>
#include <__type_traits/is_trivial.h>
#include <__type_traits/remove_cvref.h>
#include <__type_traits/remove_reference.h>
#include <__type_traits/type_identity.h>
#include <cstddef>
#include <iosfwd>
#include <limits>
#include <stdexcept>
#include <version>
// standard-mandated includes
// [iterator.range]
#include <__iterator/access.h>
#include <__iterator/data.h>
#include <__iterator/empty.h>
#include <__iterator/reverse_access.h>
#include <__iterator/size.h>
// [string.view.synop]
#include <compare>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
// TODO: This is a workaround for some vendors to carry a downstream diff to accept `nullptr` in
// string_view constructors. This can be refactored when this exact form isn't needed anymore.
template <class _Traits>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR inline size_t
__char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
2024-05-27 09:12:27 +00:00
// This needs to be a single statement for C++11 constexpr
return _LIBCPP_ASSERT_NON_NULL(
__s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"),
_Traits::length(__s);
2024-05-27 09:12:27 +00:00
}
template <class _CharT, class _Traits>
2024-05-27 09:12:27 +00:00
class basic_string_view {
public:
// types
using traits_type = _Traits;
using value_type = _CharT;
using pointer = _CharT*;
using const_pointer = const _CharT*;
using reference = _CharT&;
using const_reference = const _CharT&;
#if defined(_LIBCPP_ABI_BOUNDED_ITERATORS)
using const_iterator = __bounded_iter<const_pointer>;
#elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW)
using const_iterator = __wrap_iter<const_pointer>;
2024-05-27 09:12:27 +00:00
#else
using const_iterator = const_pointer;
2024-05-27 09:12:27 +00:00
#endif
using iterator = const_iterator;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;
using size_type = size_t;
using difference_type = ptrdiff_t;
static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
static_assert(!is_array<value_type>::value, "Character type of basic_string_view must not be an array");
static_assert(is_standard_layout<value_type>::value, "Character type of basic_string_view must be standard-layout");
static_assert(is_trivial<value_type>::value, "Character type of basic_string_view must be trivial");
static_assert(is_same<_CharT, typename traits_type::char_type>::value,
"traits_type::char_type must be the same type as CharT");
// [string.view.cons], construct/copy
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view() _NOEXCEPT : __data_(nullptr), __size_(0) {}
_LIBCPP_HIDE_FROM_ABI basic_string_view(const basic_string_view&) _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
: __data_(__s),
__size_(__len) {
2024-05-27 09:12:27 +00:00
#if _LIBCPP_STD_VER >= 14
// Allocations must fit in `ptrdiff_t` for pointer arithmetic to work. If `__len` exceeds it, the input
// range could not have been valid. Most likely the caller underflowed some arithmetic and inadvertently
// passed in a negative length.
_LIBCPP_ASSERT_VALID_INPUT_RANGE(
__len <= static_cast<size_type>(numeric_limits<difference_type>::max()),
"string_view::string_view(_CharT *, size_t): length does not fit in difference_type");
_LIBCPP_ASSERT_NON_NULL(
__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
#endif
}
2024-05-27 09:12:27 +00:00
#if _LIBCPP_STD_VER >= 20
template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
requires(is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>)
constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end)
: __data_(std::to_address(__begin)), __size_(__end - __begin) {
_LIBCPP_ASSERT_VALID_INPUT_RANGE(
(__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range");
}
2024-05-27 09:12:27 +00:00
#endif // _LIBCPP_STD_VER >= 20
#if _LIBCPP_STD_VER >= 23
template <class _Range>
requires(!is_same_v<remove_cvref_t<_Range>, basic_string_view> && ranges::contiguous_range<_Range> &&
ranges::sized_range<_Range> && is_same_v<ranges::range_value_t<_Range>, _CharT> &&
!is_convertible_v<_Range, const _CharT*> &&
(!requires(remove_cvref_t<_Range>& __d) { __d.operator std::basic_string_view<_CharT, _Traits>(); }))
constexpr explicit _LIBCPP_HIDE_FROM_ABI basic_string_view(_Range&& __r)
: __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}
2024-05-27 09:12:27 +00:00
#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s)
: __data_(__s), __size_(std::__char_traits_length_checked<_Traits>(__s)) {}
2024-05-27 09:12:27 +00:00
#if _LIBCPP_STD_VER >= 23
basic_string_view(nullptr_t) = delete;
2024-05-27 09:12:27 +00:00
#endif
// [string.view.iterators], iterators
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); }
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); }
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
return std::__make_bounded_iter(data(), data(), data() + size());
2024-05-27 09:12:27 +00:00
#else
return const_iterator(__data_);
2024-05-27 09:12:27 +00:00
#endif
}
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
return std::__make_bounded_iter(data() + size(), data(), data() + size());
2024-05-27 09:12:27 +00:00
#else
return const_iterator(__data_ + __size_);
2024-05-27 09:12:27 +00:00
#endif
}
_LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
return const_reverse_iterator(cend());
}
_LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
return const_reverse_iterator(cbegin());
}
_LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
return const_reverse_iterator(cend());
}
_LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
return const_reverse_iterator(cbegin());
}
// [string.view.capacity], capacity
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; }
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
return numeric_limits<size_type>::max() / sizeof(value_type);
}
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return __size_ == 0; }
// [string.view.access], element access
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __pos) const _NOEXCEPT {
return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];
}
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const {
return __pos >= size() ? (__throw_out_of_range("string_view::at"), __data_[0]) : __data_[__pos];
}
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0];
}
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"), __data_[__size_ - 1];
}
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; }
// [string.view.modifiers], modifiers:
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_prefix(size_type __n) _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_prefix() can't remove more than size()");
__data_ += __n;
__size_ -= __n;
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_suffix(size_type __n) _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_suffix() can't remove more than size()");
__size_ -= __n;
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void swap(basic_string_view& __other) _NOEXCEPT {
const value_type* __p = __data_;
__data_ = __other.__data_;
__other.__data_ = __p;
size_type __sz = __size_;
__size_ = __other.__size_;
__other.__size_ = __sz;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
copy(_CharT* __s, size_type __n, size_type __pos = 0) const {
if (__pos > size())
__throw_out_of_range("string_view::copy");
size_type __rlen = std::min(__n, size() - __pos);
_Traits::copy(__s, data() + __pos, __rlen);
return __rlen;
}
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view substr(size_type __pos = 0, size_type __n = npos) const {
return __pos > size() ? (__throw_out_of_range("string_view::substr"), basic_string_view())
: basic_string_view(data() + __pos, std::min(__n, size() - __pos));
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT {
size_type __rlen = std::min(size(), __sv.size());
int __retval = _Traits::compare(data(), __sv.data(), __rlen);
if (__retval == 0) // first __rlen chars matched
__retval = size() == __sv.size() ? 0 : (size() < __sv.size() ? -1 : 1);
return __retval;
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
compare(size_type __pos1, size_type __n1, basic_string_view __sv) const {
return substr(__pos1, __n1).compare(__sv);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
compare(size_type __pos1, size_type __n1, basic_string_view __sv, size_type __pos2, size_type __n2) const {
return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int compare(const _CharT* __s) const _NOEXCEPT {
return compare(basic_string_view(__s));
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
compare(size_type __pos1, size_type __n1, const _CharT* __s) const {
return substr(__pos1, __n1).compare(basic_string_view(__s));
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const {
return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
}
// find
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
// rfind
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
rfind(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
// find_first_of
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
return find(__c, __pos);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_of(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
// find_last_of
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
return rfind(__c, __pos);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_of(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_of(): received nullptr");
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
// find_first_not_of
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_not_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(
__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_not_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_not_of(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
// find_last_not_of
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_not_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(
__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_not_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_not_of(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
2024-05-27 09:12:27 +00:00
#if _LIBCPP_STD_VER >= 20
constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept {
return size() >= __s.size() && compare(0, __s.size(), __s) == 0;
}
constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
return !empty() && _Traits::eq(front(), __c);
}
constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* __s) const noexcept {
return starts_with(basic_string_view(__s));
}
constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept {
return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0;
}
constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
return !empty() && _Traits::eq(back(), __c);
}
constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* __s) const noexcept {
return ends_with(basic_string_view(__s));
}
#endif
2024-05-27 09:12:27 +00:00
#if _LIBCPP_STD_VER >= 23
constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept { return find(__sv) != npos; }
2024-05-27 09:12:27 +00:00
constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return find(__c) != npos; }
2024-05-27 09:12:27 +00:00
constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const { return find(__s) != npos; }
2024-05-27 09:12:27 +00:00
#endif
private:
const value_type* __data_;
size_type __size_;
};
2024-05-27 09:12:27 +00:00
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view);
#if _LIBCPP_STD_VER >= 20
template <class _CharT, class _Traits>
inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
template <class _CharT, class _Traits>
inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
#endif // _LIBCPP_STD_VER >= 20
2024-05-27 09:12:27 +00:00
// [string.view.deduct]
#if _LIBCPP_STD_VER >= 20
template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
2024-05-27 09:12:27 +00:00
#endif // _LIBCPP_STD_VER >= 20
#if _LIBCPP_STD_VER >= 23
template <ranges::contiguous_range _Range>
basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;
2024-05-27 09:12:27 +00:00
#endif
// [string.view.comparison]
#if _LIBCPP_STD_VER >= 20
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(basic_string_view<_CharT, _Traits> __lhs,
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) noexcept {
if (__lhs.size() != __rhs.size())
return false;
return __lhs.compare(__rhs) == 0;
}
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(basic_string_view<_CharT, _Traits> __lhs,
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) noexcept {
if constexpr (requires { typename _Traits::comparison_category; }) {
// [string.view]/4
static_assert(
__comparison_category<typename _Traits::comparison_category>, "return type is not a comparison category type");
return static_cast<typename _Traits::comparison_category>(__lhs.compare(__rhs) <=> 0);
} else {
return static_cast<weak_ordering>(__lhs.compare(__rhs) <=> 0);
}
}
2024-05-27 09:12:27 +00:00
#else
2024-05-27 09:12:27 +00:00
// operator ==
2024-05-27 09:12:27 +00:00
template <class _CharT, class _Traits>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator==(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
if (__lhs.size() != __rhs.size())
return false;
return __lhs.compare(__rhs) == 0;
2024-05-27 09:12:27 +00:00
}
// The dummy default template parameters are used to work around a MSVC issue with mangling, see VSO-409326 for details.
// This applies to the other sufficient overloads below for the other comparison operators.
2024-05-27 09:12:27 +00:00
template <class _CharT, class _Traits, int = 1>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator==(basic_string_view<_CharT, _Traits> __lhs,
__type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
if (__lhs.size() != __rhs.size())
return false;
return __lhs.compare(__rhs) == 0;
2024-05-27 09:12:27 +00:00
}
template <class _CharT, class _Traits, int = 2>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator==(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
if (__lhs.size() != __rhs.size())
return false;
return __lhs.compare(__rhs) == 0;
}
// operator !=
template <class _CharT, class _Traits>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
if (__lhs.size() != __rhs.size())
return true;
return __lhs.compare(__rhs) != 0;
}
template <class _CharT, class _Traits, int = 1>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator!=(basic_string_view<_CharT, _Traits> __lhs,
__type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
if (__lhs.size() != __rhs.size())
return true;
return __lhs.compare(__rhs) != 0;
}
template <class _CharT, class _Traits, int = 2>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator!=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
if (__lhs.size() != __rhs.size())
return true;
return __lhs.compare(__rhs) != 0;
}
// operator <
template <class _CharT, class _Traits>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) < 0;
}
template <class _CharT, class _Traits, int = 1>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator<(basic_string_view<_CharT, _Traits> __lhs,
__type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) < 0;
}
template <class _CharT, class _Traits, int = 2>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator<(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) < 0;
}
// operator >
template <class _CharT, class _Traits>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator>(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) > 0;
}
template <class _CharT, class _Traits, int = 1>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator>(basic_string_view<_CharT, _Traits> __lhs,
__type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) > 0;
}
template <class _CharT, class _Traits, int = 2>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator>(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) > 0;
}
// operator <=
template <class _CharT, class _Traits>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) <= 0;
}
template <class _CharT, class _Traits, int = 1>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator<=(basic_string_view<_CharT, _Traits> __lhs,
__type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) <= 0;
}
template <class _CharT, class _Traits, int = 2>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator<=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) <= 0;
}
// operator >=
template <class _CharT, class _Traits>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) >= 0;
}
template <class _CharT, class _Traits, int = 1>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator>=(basic_string_view<_CharT, _Traits> __lhs,
__type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) >= 0;
}
template <class _CharT, class _Traits, int = 2>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
operator>=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
return __lhs.compare(__rhs) >= 0;
}
2024-05-27 09:12:27 +00:00
#endif // _LIBCPP_STD_VER >= 20
template <class _CharT, class _Traits>
2024-05-27 09:12:27 +00:00
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __str);
// [string.view.hash]
template <class _CharT>
struct __string_view_hash : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> {
_LIBCPP_HIDE_FROM_ABI size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
return std::__do_string_hash(__val.data(), __val.data() + __val.size());
}
};
2024-05-27 09:12:27 +00:00
template <>
struct hash<basic_string_view<char, char_traits<char> > > : __string_view_hash<char> {};
#ifndef _LIBCPP_HAS_NO_CHAR8_T
template <>
struct hash<basic_string_view<char8_t, char_traits<char8_t> > > : __string_view_hash<char8_t> {};
#endif
template <>
struct hash<basic_string_view<char16_t, char_traits<char16_t> > > : __string_view_hash<char16_t> {};
template <>
struct hash<basic_string_view<char32_t, char_traits<char32_t> > > : __string_view_hash<char32_t> {};
2024-05-27 09:12:27 +00:00
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <>
struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {};
#endif
#if _LIBCPP_STD_VER >= 14
inline namespace literals {
inline namespace string_view_literals {
inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char> operator""sv(const char* __str, size_t __len) noexcept {
return basic_string_view<char>(__str, __len);
}
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t>
operator""sv(const wchar_t* __str, size_t __len) noexcept {
return basic_string_view<wchar_t>(__str, __len);
}
# endif
# ifndef _LIBCPP_HAS_NO_CHAR8_T
inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t>
operator""sv(const char8_t* __str, size_t __len) noexcept {
return basic_string_view<char8_t>(__str, __len);
}
# endif
inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t>
operator""sv(const char16_t* __str, size_t __len) noexcept {
return basic_string_view<char16_t>(__str, __len);
}
inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t>
operator""sv(const char32_t* __str, size_t __len) noexcept {
return basic_string_view<char32_t>(__str, __len);
}
} // namespace string_view_literals
2024-05-27 09:12:27 +00:00
} // namespace literals
#endif
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
2024-05-27 09:12:27 +00:00
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <algorithm>
# include <concepts>
# include <cstdlib>
# include <iterator>
# include <type_traits>
#endif
#endif // _LIBCPP_STRING_VIEW