Upgrade to 2022-era LLVM LIBCXX

This commit is contained in:
Justine Tunney 2024-05-27 02:12:27 -07:00
parent 2f4ca71f26
commit 8e68384e15
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
2078 changed files with 165657 additions and 65010 deletions

129
third_party/libcxx/__iterator/access.h vendored Normal file
View file

@ -0,0 +1,129 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ACCESS_H
#define _LIBCPP___ITERATOR_ACCESS_H
#include <__config>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, size_t _Np>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
_Tp*
begin(_Tp (&__array)[_Np])
{
return __array;
}
template <class _Tp, size_t _Np>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
_Tp*
end(_Tp (&__array)[_Np])
{
return __array + _Np;
}
#if !defined(_LIBCPP_CXX03_LANG)
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto
begin(_Cp& __c) -> decltype(__c.begin())
{
return __c.begin();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto
begin(const _Cp& __c) -> decltype(__c.begin())
{
return __c.begin();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto
end(_Cp& __c) -> decltype(__c.end())
{
return __c.end();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto
end(const _Cp& __c) -> decltype(__c.end())
{
return __c.end();
}
#if _LIBCPP_STD_VER >= 14
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c))
{
return _VSTD::begin(__c);
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c))
{
return _VSTD::end(__c);
}
#endif
#else // defined(_LIBCPP_CXX03_LANG)
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY
typename _Cp::iterator
begin(_Cp& __c)
{
return __c.begin();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY
typename _Cp::const_iterator
begin(const _Cp& __c)
{
return __c.begin();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY
typename _Cp::iterator
end(_Cp& __c)
{
return __c.end();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY
typename _Cp::const_iterator
end(const _Cp& __c)
{
return __c.end();
}
#endif // !defined(_LIBCPP_CXX03_LANG)
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ACCESS_H

202
third_party/libcxx/__iterator/advance.h vendored Normal file
View file

@ -0,0 +1,202 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ADVANCE_H
#define _LIBCPP___ITERATOR_ADVANCE_H
#include <__assert>
#include <__concepts/assignable.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_integral.h>
#include <__utility/convert_to_integral.h>
#include <__utility/declval.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
void __advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) {
for (; __n > 0; --__n)
++__i;
}
template <class _BiDirIter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) {
if (__n >= 0)
for (; __n > 0; --__n)
++__i;
else
for (; __n < 0; ++__n)
--__i;
}
template <class _RandIter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) {
__i += __n;
}
template <
class _InputIter, class _Distance,
class _IntegralDistance = decltype(_VSTD::__convert_to_integral(std::declval<_Distance>())),
class = __enable_if_t<is_integral<_IntegralDistance>::value> >
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
void advance(_InputIter& __i, _Distance __orig_n) {
typedef typename iterator_traits<_InputIter>::difference_type _Difference;
_Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n));
_LIBCPP_ASSERT(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value,
"Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
_VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
}
#if _LIBCPP_STD_VER >= 20
// [range.iter.op.advance]
namespace ranges {
namespace __advance {
struct __fn {
private:
template <class _Ip>
_LIBCPP_HIDE_FROM_ABI
static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) {
while (__n > 0) {
--__n;
++__i;
}
}
template <class _Ip>
_LIBCPP_HIDE_FROM_ABI
static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) {
while (__n < 0) {
++__n;
--__i;
}
}
public:
// Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative.
template <input_or_output_iterator _Ip>
_LIBCPP_HIDE_FROM_ABI
constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const {
_LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>,
"If `n < 0`, then `bidirectional_iterator<I>` must be true.");
// If `I` models `random_access_iterator`, equivalent to `i += n`.
if constexpr (random_access_iterator<_Ip>) {
__i += __n;
return;
} else if constexpr (bidirectional_iterator<_Ip>) {
// Otherwise, if `n` is non-negative, increments `i` by `n`.
__advance_forward(__i, __n);
// Otherwise, decrements `i` by `-n`.
__advance_backward(__i, __n);
return;
} else {
// Otherwise, if `n` is non-negative, increments `i` by `n`.
__advance_forward(__i, __n);
return;
}
}
// Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound_sentinel) denotes a range.
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
_LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const {
// If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound_sentinel)`.
if constexpr (assignable_from<_Ip&, _Sp>) {
__i = _VSTD::move(__bound_sentinel);
}
// Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent to `ranges::advance(i, bound_sentinel - i)`.
else if constexpr (sized_sentinel_for<_Sp, _Ip>) {
(*this)(__i, __bound_sentinel - __i);
}
// Otherwise, while `bool(i != bound_sentinel)` is true, increments `i`.
else {
while (__i != __bound_sentinel) {
++__i;
}
}
}
// Preconditions:
// * If `n > 0`, [i, bound_sentinel) denotes a range.
// * If `n == 0`, [i, bound_sentinel) or [bound_sentinel, i) denotes a range.
// * If `n < 0`, [bound_sentinel, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`.
// Returns: `n - M`, where `M` is the difference between the ending and starting position.
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
_LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n,
_Sp __bound_sentinel) const {
_LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>),
"If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true.");
// If `S` and `I` model `sized_sentinel_for<S, I>`:
if constexpr (sized_sentinel_for<_Sp, _Ip>) {
// If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`.
// __magnitude_geq(a, b) returns |a| >= |b|, assuming they have the same sign.
auto __magnitude_geq = [](auto __a, auto __b) {
return __a == 0 ? __b == 0 :
__a > 0 ? __a >= __b :
__a <= __b;
};
if (const auto __m = __bound_sentinel - __i; __magnitude_geq(__n, __m)) {
(*this)(__i, __bound_sentinel);
return __n - __m;
}
// Otherwise, equivalent to `ranges::advance(i, n)`.
(*this)(__i, __n);
return 0;
} else {
// Otherwise, if `n` is non-negative, while `bool(i != bound_sentinel)` is true, increments `i` but at
// most `n` times.
while (__i != __bound_sentinel && __n > 0) {
++__i;
--__n;
}
// Otherwise, while `bool(i != bound_sentinel)` is true, decrements `i` but at most `-n` times.
if constexpr (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>) {
while (__i != __bound_sentinel && __n < 0) {
--__i;
++__n;
}
}
return __n;
}
__libcpp_unreachable();
}
};
} // namespace __advance
inline namespace __cpo {
inline constexpr auto advance = __advance::__fn{};
} // namespace __cpo
} // namespace ranges
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ADVANCE_H

View file

@ -0,0 +1,73 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_BACK_INSERT_ITERATOR_H
#define _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H
#include <__config>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__utility/move.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Container>
class _LIBCPP_TEMPLATE_VIS back_insert_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
_Container* container;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
#if _LIBCPP_STD_VER >= 20
typedef ptrdiff_t difference_type;
#else
typedef void difference_type;
#endif
typedef void pointer;
typedef void reference;
typedef _Container container_type;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(const typename _Container::value_type& __value)
{container->push_back(__value); return *this;}
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(typename _Container::value_type&& __value)
{container->push_back(_VSTD::move(__value)); return *this;}
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator*() {return *this;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator++() {return *this;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator operator++(int) {return *this;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Container* __get_container() const { return container; }
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(back_insert_iterator);
template <class _Container>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
back_insert_iterator<_Container>
back_inserter(_Container& __x)
{
return back_insert_iterator<_Container>(__x);
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H

View file

@ -0,0 +1,231 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_BOUNDED_ITER_H
#define _LIBCPP___ITERATOR_BOUNDED_ITER_H
#include <__assert>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__memory/pointer_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_convertible.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
// Iterator wrapper that carries the valid range it is allowed to access.
//
// This is a simple iterator wrapper for contiguous iterators that points
// within a [begin, end) range and carries these bounds with it. The iterator
// ensures that it is pointing within that [begin, end) range when it is
// dereferenced.
//
// Arithmetic operations are allowed and the bounds of the resulting iterator
// are not checked. Hence, it is possible to create an iterator pointing outside
// its range, but it is not possible to dereference it.
template <class _Iterator, class = __enable_if_t< __libcpp_is_contiguous_iterator<_Iterator>::value > >
struct __bounded_iter {
using value_type = typename iterator_traits<_Iterator>::value_type;
using difference_type = typename iterator_traits<_Iterator>::difference_type;
using pointer = typename iterator_traits<_Iterator>::pointer;
using reference = typename iterator_traits<_Iterator>::reference;
using iterator_category = typename iterator_traits<_Iterator>::iterator_category;
#if _LIBCPP_STD_VER >= 20
using iterator_concept = contiguous_iterator_tag;
#endif
// Create a singular iterator.
//
// Such an iterator does not point to any object and is conceptually out of bounds, so it is
// not dereferenceable. Observing operations like comparison and assignment are valid.
_LIBCPP_HIDE_FROM_ABI __bounded_iter() = default;
_LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter const&) = default;
_LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter&&) = default;
template <class _OtherIterator, class = __enable_if_t< is_convertible<_OtherIterator, _Iterator>::value > >
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT
: __current_(__other.__current_),
__begin_(__other.__begin_),
__end_(__other.__end_) {}
// Assign a bounded iterator to another one, rebinding the bounds of the iterator as well.
_LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter const&) = default;
_LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter&&) = default;
private:
// Create an iterator wrapping the given iterator, and whose bounds are described
// by the provided [begin, end) range.
//
// This constructor does not check whether the resulting iterator is within its bounds.
// However, it does check that the provided [begin, end) range is a valid range (that
// is, begin <= end).
//
// Since it is non-standard for iterators to have this constructor, __bounded_iter must
// be created via `std::__make_bounded_iter`.
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter(
_Iterator __current, _Iterator __begin, _Iterator __end)
: __current_(__current), __begin_(__begin), __end_(__end) {
_LIBCPP_ASSERT(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range");
}
template <class _It>
friend _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It, _It, _It);
public:
// Dereference and indexing operations.
//
// These operations check that the iterator is dereferenceable, that is within [begin, end).
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT {
_LIBCPP_ASSERT(
__in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator");
return *__current_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT {
_LIBCPP_ASSERT(
__in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator");
return std::__to_address(__current_);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT {
_LIBCPP_ASSERT(
__in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range");
return __current_[__n];
}
// Arithmetic operations.
//
// These operations do not check that the resulting iterator is within the bounds, since that
// would make it impossible to create a past-the-end iterator.
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator++() _NOEXCEPT {
++__current_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter operator++(int) _NOEXCEPT {
__bounded_iter __tmp(*this);
++*this;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator--() _NOEXCEPT {
--__current_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter operator--(int) _NOEXCEPT {
__bounded_iter __tmp(*this);
--*this;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator+=(difference_type __n) _NOEXCEPT {
__current_ += __n;
return *this;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter
operator+(__bounded_iter const& __self, difference_type __n) _NOEXCEPT {
__bounded_iter __tmp(__self);
__tmp += __n;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter
operator+(difference_type __n, __bounded_iter const& __self) _NOEXCEPT {
__bounded_iter __tmp(__self);
__tmp += __n;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator-=(difference_type __n) _NOEXCEPT {
__current_ -= __n;
return *this;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter
operator-(__bounded_iter const& __self, difference_type __n) _NOEXCEPT {
__bounded_iter __tmp(__self);
__tmp -= __n;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend difference_type
operator-(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ - __y.__current_;
}
// Comparison operations.
//
// These operations do not check whether the iterators are within their bounds.
// The valid range for each iterator is also not considered as part of the comparison,
// i.e. two iterators pointing to the same location will be considered equal even
// if they have different validity ranges.
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
operator==(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ == __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
operator!=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ != __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
operator<(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ < __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
operator>(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ > __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
operator<=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ <= __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
operator>=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ >= __y.__current_;
}
private:
// Return whether the given iterator is in the bounds of this __bounded_iter.
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Iterator const& __iter) const {
return __iter >= __begin_ && __iter < __end_;
}
template <class>
friend struct pointer_traits;
_Iterator __current_; // current iterator
_Iterator __begin_, __end_; // valid range represented as [begin, end)
};
template <class _It>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It __it, _It __begin, _It __end) {
return __bounded_iter<_It>(std::move(__it), std::move(__begin), std::move(__end));
}
#if _LIBCPP_STD_VER <= 17
template <class _Iterator>
struct __libcpp_is_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {};
#endif
template <class _Iterator>
struct pointer_traits<__bounded_iter<_Iterator> > {
using pointer = __bounded_iter<_Iterator>;
using element_type = typename pointer_traits<_Iterator>::element_type;
using difference_type = typename pointer_traits<_Iterator>::difference_type;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __it) _NOEXCEPT {
return std::__to_address(__it.__current_);
}
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H

View file

@ -0,0 +1,282 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_COMMON_ITERATOR_H
#define _LIBCPP___ITERATOR_COMMON_ITERATOR_H
#include <__assert>
#include <__concepts/assignable.h>
#include <__concepts/constructible.h>
#include <__concepts/convertible_to.h>
#include <__concepts/copyable.h>
#include <__concepts/derived_from.h>
#include <__concepts/equality_comparable.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iter_move.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
#include <__memory/addressof.h>
#include <__type_traits/is_pointer.h>
#include <__utility/declval.h>
#include <variant>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template<class _Iter>
concept __can_use_postfix_proxy =
constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> &&
move_constructible<iter_value_t<_Iter>>;
template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
requires (!same_as<_Iter, _Sent> && copyable<_Iter>)
class common_iterator {
struct __proxy {
_LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>* operator->() const noexcept {
return _VSTD::addressof(__value_);
}
iter_value_t<_Iter> __value_;
};
struct __postfix_proxy {
_LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>& operator*() const noexcept {
return __value_;
}
iter_value_t<_Iter> __value_;
};
public:
variant<_Iter, _Sent> __hold_;
_LIBCPP_HIDE_FROM_ABI common_iterator() requires default_initializable<_Iter> = default;
_LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {}
_LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {}
template<class _I2, class _S2>
requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent>
_LIBCPP_HIDE_FROM_ABI constexpr common_iterator(const common_iterator<_I2, _S2>& __other)
: __hold_([&]() -> variant<_Iter, _Sent> {
_LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator");
if (__other.__hold_.index() == 0)
return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)};
return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)};
}()) {}
template<class _I2, class _S2>
requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> &&
assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&>
_LIBCPP_HIDE_FROM_ABI common_iterator& operator=(const common_iterator<_I2, _S2>& __other) {
_LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator");
auto __idx = __hold_.index();
auto __other_idx = __other.__hold_.index();
// If they're the same index, just assign.
if (__idx == 0 && __other_idx == 0)
_VSTD::__unchecked_get<0>(__hold_) = _VSTD::__unchecked_get<0>(__other.__hold_);
else if (__idx == 1 && __other_idx == 1)
_VSTD::__unchecked_get<1>(__hold_) = _VSTD::__unchecked_get<1>(__other.__hold_);
// Otherwise replace with the oposite element.
else if (__other_idx == 1)
__hold_.template emplace<1>(_VSTD::__unchecked_get<1>(__other.__hold_));
else if (__other_idx == 0)
__hold_.template emplace<0>(_VSTD::__unchecked_get<0>(__other.__hold_));
return *this;
}
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*()
{
_LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
return *_VSTD::__unchecked_get<_Iter>(__hold_);
}
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const
requires __dereferenceable<const _Iter>
{
_LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
return *_VSTD::__unchecked_get<_Iter>(__hold_);
}
template<class _I2 = _Iter>
_LIBCPP_HIDE_FROM_ABI decltype(auto) operator->() const
requires indirectly_readable<const _I2> &&
(requires(const _I2& __i) { __i.operator->(); } ||
is_reference_v<iter_reference_t<_I2>> ||
constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>)
{
_LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) {
return _VSTD::__unchecked_get<_Iter>(__hold_);
} else if constexpr (is_reference_v<iter_reference_t<_Iter>>) {
auto&& __tmp = *_VSTD::__unchecked_get<_Iter>(__hold_);
return _VSTD::addressof(__tmp);
} else {
return __proxy{*_VSTD::__unchecked_get<_Iter>(__hold_)};
}
}
_LIBCPP_HIDE_FROM_ABI common_iterator& operator++() {
_LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
++_VSTD::__unchecked_get<_Iter>(__hold_); return *this;
}
_LIBCPP_HIDE_FROM_ABI decltype(auto) operator++(int) {
_LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
if constexpr (forward_iterator<_Iter>) {
auto __tmp = *this;
++*this;
return __tmp;
} else if constexpr (requires (_Iter& __i) { { *__i++ } -> __can_reference; } ||
!__can_use_postfix_proxy<_Iter>) {
return _VSTD::__unchecked_get<_Iter>(__hold_)++;
} else {
auto __p = __postfix_proxy{**this};
++*this;
return __p;
}
}
template<class _I2, sentinel_for<_Iter> _S2>
requires sentinel_for<_Sent, _I2>
_LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
_LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
_LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
auto __x_index = __x.__hold_.index();
auto __y_index = __y.__hold_.index();
if (__x_index == __y_index)
return true;
if (__x_index == 0)
return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_);
return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_);
}
template<class _I2, sentinel_for<_Iter> _S2>
requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2>
_LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
_LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
_LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
auto __x_index = __x.__hold_.index();
auto __y_index = __y.__hold_.index();
if (__x_index == 1 && __y_index == 1)
return true;
if (__x_index == 0 && __y_index == 0)
return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_);
if (__x_index == 0)
return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_);
return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_);
}
template<sized_sentinel_for<_Iter> _I2, sized_sentinel_for<_Iter> _S2>
requires sized_sentinel_for<_Sent, _I2>
_LIBCPP_HIDE_FROM_ABI
friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
_LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator");
_LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator");
auto __x_index = __x.__hold_.index();
auto __y_index = __y.__hold_.index();
if (__x_index == 1 && __y_index == 1)
return 0;
if (__x_index == 0 && __y_index == 0)
return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_);
if (__x_index == 0)
return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_S2>(__y.__hold_);
return _VSTD::__unchecked_get<_Sent>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_);
}
_LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i)
noexcept(noexcept(ranges::iter_move(std::declval<const _Iter&>())))
requires input_iterator<_Iter>
{
_LIBCPP_ASSERT(std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator");
return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_));
}
template<indirectly_swappable<_Iter> _I2, class _S2>
_LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y)
noexcept(noexcept(ranges::iter_swap(std::declval<const _Iter&>(), std::declval<const _I2&>())))
{
_LIBCPP_ASSERT(std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
_LIBCPP_ASSERT(std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_));
}
};
template<class _Iter, class _Sent>
struct incrementable_traits<common_iterator<_Iter, _Sent>> {
using difference_type = iter_difference_t<_Iter>;
};
template<class _Iter>
concept __denotes_forward_iter =
requires { typename iterator_traits<_Iter>::iterator_category; } &&
derived_from<typename iterator_traits<_Iter>::iterator_category, forward_iterator_tag>;
template<class _Iter, class _Sent>
concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) {
__a.operator->();
};
template<class, class>
struct __arrow_type_or_void {
using type = void;
};
template<class _Iter, class _Sent>
requires __common_iter_has_ptr_op<_Iter, _Sent>
struct __arrow_type_or_void<_Iter, _Sent> {
using type = decltype(std::declval<const common_iterator<_Iter, _Sent>&>().operator->());
};
template<input_iterator _Iter, class _Sent>
struct iterator_traits<common_iterator<_Iter, _Sent>> {
using iterator_concept = _If<forward_iterator<_Iter>,
forward_iterator_tag,
input_iterator_tag>;
using iterator_category = _If<__denotes_forward_iter<_Iter>,
forward_iterator_tag,
input_iterator_tag>;
using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type;
using value_type = iter_value_t<_Iter>;
using difference_type = iter_difference_t<_Iter>;
using reference = iter_reference_t<_Iter>;
};
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H

300
third_party/libcxx/__iterator/concepts.h vendored Normal file
View file

@ -0,0 +1,300 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_CONCEPTS_H
#define _LIBCPP___ITERATOR_CONCEPTS_H
#include <__concepts/arithmetic.h>
#include <__concepts/assignable.h>
#include <__concepts/common_reference_with.h>
#include <__concepts/constructible.h>
#include <__concepts/copyable.h>
#include <__concepts/derived_from.h>
#include <__concepts/equality_comparable.h>
#include <__concepts/invocable.h>
#include <__concepts/movable.h>
#include <__concepts/predicate.h>
#include <__concepts/regular.h>
#include <__concepts/relation.h>
#include <__concepts/same_as.h>
#include <__concepts/semiregular.h>
#include <__concepts/totally_ordered.h>
#include <__config>
#include <__functional/invoke.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iter_move.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
#include <__memory/pointer_traits.h>
#include <__type_traits/add_pointer.h>
#include <__type_traits/common_reference.h>
#include <__type_traits/is_pointer.h>
#include <__type_traits/is_reference.h>
#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
// [iterator.concept.readable]
template<class _In>
concept __indirectly_readable_impl =
requires(const _In __i) {
typename iter_value_t<_In>;
typename iter_reference_t<_In>;
typename iter_rvalue_reference_t<_In>;
{ *__i } -> same_as<iter_reference_t<_In>>;
{ ranges::iter_move(__i) } -> same_as<iter_rvalue_reference_t<_In>>;
} &&
common_reference_with<iter_reference_t<_In>&&, iter_value_t<_In>&> &&
common_reference_with<iter_reference_t<_In>&&, iter_rvalue_reference_t<_In>&&> &&
common_reference_with<iter_rvalue_reference_t<_In>&&, const iter_value_t<_In>&>;
template<class _In>
concept indirectly_readable = __indirectly_readable_impl<remove_cvref_t<_In>>;
template<indirectly_readable _Tp>
using iter_common_reference_t = common_reference_t<iter_reference_t<_Tp>, iter_value_t<_Tp>&>;
// [iterator.concept.writable]
template<class _Out, class _Tp>
concept indirectly_writable =
requires(_Out&& __o, _Tp&& __t) {
*__o = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
*_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
const_cast<const iter_reference_t<_Out>&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
const_cast<const iter_reference_t<_Out>&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
};
// [iterator.concept.winc]
template<class _Tp>
concept __integer_like = integral<_Tp> && !same_as<_Tp, bool>;
template<class _Tp>
concept __signed_integer_like = signed_integral<_Tp>;
template<class _Ip>
concept weakly_incrementable =
// TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173).
!same_as<_Ip, bool> && // Currently, clang does not handle bool correctly.
movable<_Ip> &&
requires(_Ip __i) {
typename iter_difference_t<_Ip>;
requires __signed_integer_like<iter_difference_t<_Ip>>;
{ ++__i } -> same_as<_Ip&>; // not required to be equality-preserving
__i++; // not required to be equality-preserving
};
// [iterator.concept.inc]
template<class _Ip>
concept incrementable =
regular<_Ip> &&
weakly_incrementable<_Ip> &&
requires(_Ip __i) {
{ __i++ } -> same_as<_Ip>;
};
// [iterator.concept.iterator]
template<class _Ip>
concept input_or_output_iterator =
requires(_Ip __i) {
{ *__i } -> __can_reference;
} &&
weakly_incrementable<_Ip>;
// [iterator.concept.sentinel]
template<class _Sp, class _Ip>
concept sentinel_for =
semiregular<_Sp> &&
input_or_output_iterator<_Ip> &&
__weakly_equality_comparable_with<_Sp, _Ip>;
template<class, class>
inline constexpr bool disable_sized_sentinel_for = false;
template<class _Sp, class _Ip>
concept sized_sentinel_for =
sentinel_for<_Sp, _Ip> &&
!disable_sized_sentinel_for<remove_cv_t<_Sp>, remove_cv_t<_Ip>> &&
requires(const _Ip& __i, const _Sp& __s) {
{ __s - __i } -> same_as<iter_difference_t<_Ip>>;
{ __i - __s } -> same_as<iter_difference_t<_Ip>>;
};
// [iterator.concept.input]
template<class _Ip>
concept input_iterator =
input_or_output_iterator<_Ip> &&
indirectly_readable<_Ip> &&
requires { typename _ITER_CONCEPT<_Ip>; } &&
derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>;
// [iterator.concept.output]
template<class _Ip, class _Tp>
concept output_iterator =
input_or_output_iterator<_Ip> &&
indirectly_writable<_Ip, _Tp> &&
requires (_Ip __it, _Tp&& __t) {
*__it++ = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
};
// [iterator.concept.forward]
template<class _Ip>
concept forward_iterator =
input_iterator<_Ip> &&
derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> &&
incrementable<_Ip> &&
sentinel_for<_Ip, _Ip>;
// [iterator.concept.bidir]
template<class _Ip>
concept bidirectional_iterator =
forward_iterator<_Ip> &&
derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> &&
requires(_Ip __i) {
{ --__i } -> same_as<_Ip&>;
{ __i-- } -> same_as<_Ip>;
};
template<class _Ip>
concept random_access_iterator =
bidirectional_iterator<_Ip> &&
derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> &&
totally_ordered<_Ip> &&
sized_sentinel_for<_Ip, _Ip> &&
requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) {
{ __i += __n } -> same_as<_Ip&>;
{ __j + __n } -> same_as<_Ip>;
{ __n + __j } -> same_as<_Ip>;
{ __i -= __n } -> same_as<_Ip&>;
{ __j - __n } -> same_as<_Ip>;
{ __j[__n] } -> same_as<iter_reference_t<_Ip>>;
};
template<class _Ip>
concept contiguous_iterator =
random_access_iterator<_Ip> &&
derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> &&
is_lvalue_reference_v<iter_reference_t<_Ip>> &&
same_as<iter_value_t<_Ip>, remove_cvref_t<iter_reference_t<_Ip>>> &&
requires(const _Ip& __i) {
{ _VSTD::to_address(__i) } -> same_as<add_pointer_t<iter_reference_t<_Ip>>>;
};
template<class _Ip>
concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); });
// [indirectcallable.indirectinvocable]
template<class _Fp, class _It>
concept indirectly_unary_invocable =
indirectly_readable<_It> &&
copy_constructible<_Fp> &&
invocable<_Fp&, iter_value_t<_It>&> &&
invocable<_Fp&, iter_reference_t<_It>> &&
invocable<_Fp&, iter_common_reference_t<_It>> &&
common_reference_with<
invoke_result_t<_Fp&, iter_value_t<_It>&>,
invoke_result_t<_Fp&, iter_reference_t<_It>>>;
template<class _Fp, class _It>
concept indirectly_regular_unary_invocable =
indirectly_readable<_It> &&
copy_constructible<_Fp> &&
regular_invocable<_Fp&, iter_value_t<_It>&> &&
regular_invocable<_Fp&, iter_reference_t<_It>> &&
regular_invocable<_Fp&, iter_common_reference_t<_It>> &&
common_reference_with<
invoke_result_t<_Fp&, iter_value_t<_It>&>,
invoke_result_t<_Fp&, iter_reference_t<_It>>>;
template<class _Fp, class _It>
concept indirect_unary_predicate =
indirectly_readable<_It> &&
copy_constructible<_Fp> &&
predicate<_Fp&, iter_value_t<_It>&> &&
predicate<_Fp&, iter_reference_t<_It>> &&
predicate<_Fp&, iter_common_reference_t<_It>>;
template<class _Fp, class _It1, class _It2>
concept indirect_binary_predicate =
indirectly_readable<_It1> && indirectly_readable<_It2> &&
copy_constructible<_Fp> &&
predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
template<class _Fp, class _It1, class _It2 = _It1>
concept indirect_equivalence_relation =
indirectly_readable<_It1> && indirectly_readable<_It2> &&
copy_constructible<_Fp> &&
equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
template<class _Fp, class _It1, class _It2 = _It1>
concept indirect_strict_weak_order =
indirectly_readable<_It1> && indirectly_readable<_It2> &&
copy_constructible<_Fp> &&
strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
template<class _Fp, class... _Its>
requires (indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...>
using indirect_result_t = invoke_result_t<_Fp, iter_reference_t<_Its>...>;
template<class _In, class _Out>
concept indirectly_movable =
indirectly_readable<_In> &&
indirectly_writable<_Out, iter_rvalue_reference_t<_In>>;
template<class _In, class _Out>
concept indirectly_movable_storable =
indirectly_movable<_In, _Out> &&
indirectly_writable<_Out, iter_value_t<_In>> &&
movable<iter_value_t<_In>> &&
constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>> &&
assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>;
template<class _In, class _Out>
concept indirectly_copyable =
indirectly_readable<_In> &&
indirectly_writable<_Out, iter_reference_t<_In>>;
template<class _In, class _Out>
concept indirectly_copyable_storable =
indirectly_copyable<_In, _Out> &&
indirectly_writable<_Out, iter_value_t<_In>&> &&
indirectly_writable<_Out, const iter_value_t<_In>&> &&
indirectly_writable<_Out, iter_value_t<_In>&&> &&
indirectly_writable<_Out, const iter_value_t<_In>&&> &&
copyable<iter_value_t<_In>> &&
constructible_from<iter_value_t<_In>, iter_reference_t<_In>> &&
assignable_from<iter_value_t<_In>&, iter_reference_t<_In>>;
// Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle
// (both iter_swap and indirectly_swappable require indirectly_readable).
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_CONCEPTS_H

View file

@ -0,0 +1,310 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_COUNTED_ITERATOR_H
#define _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
#include <__assert>
#include <__concepts/assignable.h>
#include <__concepts/common_with.h>
#include <__concepts/constructible.h>
#include <__concepts/convertible_to.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/default_sentinel.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iter_move.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
#include <__memory/pointer_traits.h>
#include <__type_traits/add_pointer.h>
#include <__type_traits/conditional.h>
#include <__utility/move.h>
#include <compare>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template<class>
struct __counted_iterator_concept {};
template<class _Iter>
requires requires { typename _Iter::iterator_concept; }
struct __counted_iterator_concept<_Iter> {
using iterator_concept = typename _Iter::iterator_concept;
};
template<class>
struct __counted_iterator_category {};
template<class _Iter>
requires requires { typename _Iter::iterator_category; }
struct __counted_iterator_category<_Iter> {
using iterator_category = typename _Iter::iterator_category;
};
template<class>
struct __counted_iterator_value_type {};
template<indirectly_readable _Iter>
struct __counted_iterator_value_type<_Iter> {
using value_type = iter_value_t<_Iter>;
};
template<input_or_output_iterator _Iter>
class counted_iterator
: public __counted_iterator_concept<_Iter>
, public __counted_iterator_category<_Iter>
, public __counted_iterator_value_type<_Iter>
{
public:
_LIBCPP_NO_UNIQUE_ADDRESS _Iter __current_ = _Iter();
iter_difference_t<_Iter> __count_ = 0;
using iterator_type = _Iter;
using difference_type = iter_difference_t<_Iter>;
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator() requires default_initializable<_Iter> = default;
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n)
: __current_(_VSTD::move(__iter)), __count_(__n) {
_LIBCPP_ASSERT(__n >= 0, "__n must not be negative.");
}
template<class _I2>
requires convertible_to<const _I2&, _Iter>
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator(const counted_iterator<_I2>& __other)
: __current_(__other.__current_), __count_(__other.__count_) {}
template<class _I2>
requires assignable_from<_Iter&, const _I2&>
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator& operator=(const counted_iterator<_I2>& __other) {
__current_ = __other.__current_;
__count_ = __other.__count_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI
constexpr const _Iter& base() const& noexcept { return __current_; }
_LIBCPP_HIDE_FROM_ABI
constexpr _Iter base() && { return _VSTD::move(__current_); }
_LIBCPP_HIDE_FROM_ABI
constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; }
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator*() {
_LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
return *__current_;
}
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator*() const
requires __dereferenceable<const _Iter>
{
_LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
return *__current_;
}
_LIBCPP_HIDE_FROM_ABI
constexpr auto operator->() const noexcept
requires contiguous_iterator<_Iter>
{
return _VSTD::to_address(__current_);
}
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator& operator++() {
_LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
++__current_;
--__count_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI
decltype(auto) operator++(int) {
_LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
--__count_;
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try { return __current_++; }
catch(...) { ++__count_; throw; }
#else
return __current_++;
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator operator++(int)
requires forward_iterator<_Iter>
{
_LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
counted_iterator __tmp = *this;
++*this;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator& operator--()
requires bidirectional_iterator<_Iter>
{
--__current_;
++__count_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator operator--(int)
requires bidirectional_iterator<_Iter>
{
counted_iterator __tmp = *this;
--*this;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator operator+(iter_difference_t<_Iter> __n) const
requires random_access_iterator<_Iter>
{
return counted_iterator(__current_ + __n, __count_ - __n);
}
_LIBCPP_HIDE_FROM_ABI
friend constexpr counted_iterator operator+(
iter_difference_t<_Iter> __n, const counted_iterator& __x)
requires random_access_iterator<_Iter>
{
return __x + __n;
}
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n)
requires random_access_iterator<_Iter>
{
_LIBCPP_ASSERT(__n <= __count_, "Cannot advance iterator past end.");
__current_ += __n;
__count_ -= __n;
return *this;
}
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator operator-(iter_difference_t<_Iter> __n) const
requires random_access_iterator<_Iter>
{
return counted_iterator(__current_ - __n, __count_ + __n);
}
template<common_with<_Iter> _I2>
_LIBCPP_HIDE_FROM_ABI
friend constexpr iter_difference_t<_I2> operator-(
const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs)
{
return __rhs.__count_ - __lhs.__count_;
}
_LIBCPP_HIDE_FROM_ABI
friend constexpr iter_difference_t<_Iter> operator-(
const counted_iterator& __lhs, default_sentinel_t)
{
return -__lhs.__count_;
}
_LIBCPP_HIDE_FROM_ABI
friend constexpr iter_difference_t<_Iter> operator-(
default_sentinel_t, const counted_iterator& __rhs)
{
return __rhs.__count_;
}
_LIBCPP_HIDE_FROM_ABI
constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n)
requires random_access_iterator<_Iter>
{
_LIBCPP_ASSERT(-__n <= __count_, "Attempt to subtract too large of a size: "
"counted_iterator would be decremented before the "
"first element of its range.");
__current_ -= __n;
__count_ += __n;
return *this;
}
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const
requires random_access_iterator<_Iter>
{
_LIBCPP_ASSERT(__n < __count_, "Subscript argument must be less than size.");
return __current_[__n];
}
template<common_with<_Iter> _I2>
_LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(
const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs)
{
return __lhs.__count_ == __rhs.__count_;
}
_LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(
const counted_iterator& __lhs, default_sentinel_t)
{
return __lhs.__count_ == 0;
}
template<common_with<_Iter> _I2>
_LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering operator<=>(
const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs)
{
return __rhs.__count_ <=> __lhs.__count_;
}
_LIBCPP_HIDE_FROM_ABI
friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const counted_iterator& __i)
noexcept(noexcept(ranges::iter_move(__i.__current_)))
requires input_iterator<_Iter>
{
_LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range.");
return ranges::iter_move(__i.__current_);
}
template<indirectly_swappable<_Iter> _I2>
_LIBCPP_HIDE_FROM_ABI
friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y)
noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
{
_LIBCPP_ASSERT(__x.__count_ > 0 && __y.__count_ > 0,
"Iterators must not be past end of range.");
return ranges::iter_swap(__x.__current_, __y.__current_);
}
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(counted_iterator);
template<input_iterator _Iter>
requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>>
struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> {
using pointer = conditional_t<contiguous_iterator<_Iter>,
add_pointer_t<iter_reference_t<_Iter>>, void>;
};
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H

51
third_party/libcxx/__iterator/data.h vendored Normal file
View file

@ -0,0 +1,51 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_DATA_H
#define _LIBCPP___ITERATOR_DATA_H
#include <__config>
#include <cstddef>
#include <initializer_list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 17
template <class _Cont> constexpr
_LIBCPP_INLINE_VISIBILITY
auto data(_Cont& __c)
_NOEXCEPT_(noexcept(__c.data()))
-> decltype (__c.data())
{ return __c.data(); }
template <class _Cont> constexpr
_LIBCPP_INLINE_VISIBILITY
auto data(const _Cont& __c)
_NOEXCEPT_(noexcept(__c.data()))
-> decltype (__c.data())
{ return __c.data(); }
template <class _Tp, size_t _Sz>
_LIBCPP_INLINE_VISIBILITY
constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; }
template <class _Ep>
_LIBCPP_INLINE_VISIBILITY
constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
#endif
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_DATA_H

View file

@ -0,0 +1,30 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_DEFAULT_SENTINEL_H
#define _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
struct default_sentinel_t { };
inline constexpr default_sentinel_t default_sentinel{};
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H

108
third_party/libcxx/__iterator/distance.h vendored Normal file
View file

@ -0,0 +1,108 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_DISTANCE_H
#define _LIBCPP___ITERATOR_DISTANCE_H
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/size.h>
#include <__type_traits/decay.h>
#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
typename iterator_traits<_InputIter>::difference_type
__distance(_InputIter __first, _InputIter __last, input_iterator_tag)
{
typename iterator_traits<_InputIter>::difference_type __r(0);
for (; __first != __last; ++__first)
++__r;
return __r;
}
template <class _RandIter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
typename iterator_traits<_RandIter>::difference_type
__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
{
return __last - __first;
}
template <class _InputIter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
typename iterator_traits<_InputIter>::difference_type
distance(_InputIter __first, _InputIter __last)
{
return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
}
#if _LIBCPP_STD_VER >= 20
// [range.iter.op.distance]
namespace ranges {
namespace __distance {
struct __fn {
template<class _Ip, sentinel_for<_Ip> _Sp>
requires (!sized_sentinel_for<_Sp, _Ip>)
_LIBCPP_HIDE_FROM_ABI
constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const {
iter_difference_t<_Ip> __n = 0;
while (__first != __last) {
++__first;
++__n;
}
return __n;
}
template<class _Ip, sized_sentinel_for<decay_t<_Ip>> _Sp>
_LIBCPP_HIDE_FROM_ABI
constexpr iter_difference_t<_Ip> operator()(_Ip&& __first, _Sp __last) const {
if constexpr (sized_sentinel_for<_Sp, __remove_cvref_t<_Ip>>) {
return __last - __first;
} else {
return __last - decay_t<_Ip>(__first);
}
}
template<range _Rp>
_LIBCPP_HIDE_FROM_ABI
constexpr range_difference_t<_Rp> operator()(_Rp&& __r) const {
if constexpr (sized_range<_Rp>) {
return static_cast<range_difference_t<_Rp>>(ranges::size(__r));
} else {
return operator()(ranges::begin(__r), ranges::end(__r));
}
}
};
} // namespace __distance
inline namespace __cpo {
inline constexpr auto distance = __distance::__fn{};
} // namespace __cpo
} // namespace ranges
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_DISTANCE_H

44
third_party/libcxx/__iterator/empty.h vendored Normal file
View file

@ -0,0 +1,44 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_EMPTY_H
#define _LIBCPP___ITERATOR_EMPTY_H
#include <__config>
#include <cstddef>
#include <initializer_list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 17
template <class _Cont>
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
constexpr auto empty(const _Cont& __c)
_NOEXCEPT_(noexcept(__c.empty()))
-> decltype (__c.empty())
{ return __c.empty(); }
template <class _Tp, size_t _Sz>
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; }
template <class _Ep>
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
#endif // _LIBCPP_STD_VER >= 17
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_EMPTY_H

View file

@ -0,0 +1,40 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ERASE_IF_CONTAINER_H
#define _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Container, class _Predicate>
_LIBCPP_HIDE_FROM_ABI
typename _Container::size_type
__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
typename _Container::size_type __old_size = __c.size();
const typename _Container::iterator __last = __c.end();
for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) {
if (__pred(*__iter))
__iter = __c.erase(__iter);
else
++__iter;
}
return __old_size - __c.size();
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H

View file

@ -0,0 +1,71 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_FRONT_INSERT_ITERATOR_H
#define _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H
#include <__config>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__utility/move.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Container>
class _LIBCPP_TEMPLATE_VIS front_insert_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
_Container* container;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
#if _LIBCPP_STD_VER >= 20
typedef ptrdiff_t difference_type;
#else
typedef void difference_type;
#endif
typedef void pointer;
typedef void reference;
typedef _Container container_type;
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(const typename _Container::value_type& __value)
{container->push_front(__value); return *this;}
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(typename _Container::value_type&& __value)
{container->push_front(_VSTD::move(__value)); return *this;}
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator++() {return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator operator++(int) {return *this;}
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(front_insert_iterator);
template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
front_insert_iterator<_Container>
front_inserter(_Container& __x)
{
return front_insert_iterator<_Container>(__x);
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H

View file

@ -0,0 +1,78 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_INCREMENTABLE_TRAITS_H
#define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
#include <__concepts/arithmetic.h>
#include <__config>
#include <__type_traits/conditional.h>
#include <__type_traits/is_object.h>
#include <__type_traits/is_primary_template.h>
#include <__type_traits/make_signed.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/declval.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
// [incrementable.traits]
template<class> struct incrementable_traits {};
template<class _Tp>
requires is_object_v<_Tp>
struct incrementable_traits<_Tp*> {
using difference_type = ptrdiff_t;
};
template<class _Ip>
struct incrementable_traits<const _Ip> : incrementable_traits<_Ip> {};
template<class _Tp>
concept __has_member_difference_type = requires { typename _Tp::difference_type; };
template<__has_member_difference_type _Tp>
struct incrementable_traits<_Tp> {
using difference_type = typename _Tp::difference_type;
};
template<class _Tp>
concept __has_integral_minus =
requires(const _Tp& __x, const _Tp& __y) {
{ __x - __y } -> integral;
};
template<__has_integral_minus _Tp>
requires (!__has_member_difference_type<_Tp>)
struct incrementable_traits<_Tp> {
using difference_type = make_signed_t<decltype(std::declval<_Tp>() - std::declval<_Tp>())>;
};
template <class>
struct iterator_traits;
// Let `RI` be `remove_cvref_t<I>`. The type `iter_difference_t<I>` denotes
// `incrementable_traits<RI>::difference_type` if `iterator_traits<RI>` names a specialization
// generated from the primary template, and `iterator_traits<RI>::difference_type` otherwise.
template <class _Ip>
using iter_difference_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
incrementable_traits<remove_cvref_t<_Ip> >,
iterator_traits<remove_cvref_t<_Ip> > >::difference_type;
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H

View file

@ -0,0 +1,34 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_INDIRECTLY_COMPARABLE_H
#define _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H
#include <__config>
#include <__functional/identity.h>
#include <__iterator/concepts.h>
#include <__iterator/projected.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template <class _I1, class _I2, class _Rp, class _P1 = identity, class _P2 = identity>
concept indirectly_comparable =
indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>;
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H

View file

@ -0,0 +1,81 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_INSERT_ITERATOR_H
#define _LIBCPP___ITERATOR_INSERT_ITERATOR_H
#include <__config>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__ranges/access.h>
#include <__utility/move.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template <class _Container>
using __insert_iterator_iter_t = ranges::iterator_t<_Container>;
#else
template <class _Container>
using __insert_iterator_iter_t = typename _Container::iterator;
#endif
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Container>
class _LIBCPP_TEMPLATE_VIS insert_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
_Container* container;
__insert_iterator_iter_t<_Container> iter;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
#if _LIBCPP_STD_VER >= 20
typedef ptrdiff_t difference_type;
#else
typedef void difference_type;
#endif
typedef void pointer;
typedef void reference;
typedef _Container container_type;
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i)
: container(_VSTD::addressof(__x)), iter(__i) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(const typename _Container::value_type& __value)
{iter = container->insert(iter, __value); ++iter; return *this;}
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(typename _Container::value_type&& __value)
{iter = container->insert(iter, _VSTD::move(__value)); ++iter; return *this;}
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++() {return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++(int) {return *this;}
};
template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
insert_iterator<_Container>
inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i)
{
return insert_iterator<_Container>(__x, __i);
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H

View file

@ -0,0 +1,105 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ISTREAM_ITERATOR_H
#define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H
#include <__config>
#include <__iterator/default_sentinel.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <cstddef>
#include <iosfwd> // for forward declarations of char_traits and basic_istream
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp, class _CharT = char,
class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
class _LIBCPP_TEMPLATE_VIS istream_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
typedef input_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
typedef _CharT char_type;
typedef _Traits traits_type;
typedef basic_istream<_CharT,_Traits> istream_type;
private:
istream_type* __in_stream_;
_Tp __value_;
public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {}
#if _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {}
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
{
if (!(*__in_stream_ >> __value_))
__in_stream_ = nullptr;
}
_LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}
_LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));}
_LIBCPP_INLINE_VISIBILITY istream_iterator& operator++()
{
if (!(*__in_stream_ >> __value_))
__in_stream_ = nullptr;
return *this;
}
_LIBCPP_INLINE_VISIBILITY istream_iterator operator++(int)
{istream_iterator __t(*this); ++(*this); return __t;}
template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
friend _LIBCPP_INLINE_VISIBILITY
bool
operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
#if _LIBCPP_STD_VER >= 20
friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) {
return __i.__in_stream_ == nullptr;
}
#endif // _LIBCPP_STD_VER >= 20
};
template <class _Tp, class _CharT, class _Traits, class _Distance>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
{
return __x.__in_stream_ == __y.__in_stream_;
}
#if _LIBCPP_STD_VER <= 17
template <class _Tp, class _CharT, class _Traits, class _Distance>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
{
return !(__x == __y);
}
#endif // _LIBCPP_STD_VER <= 17
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H

View file

@ -0,0 +1,119 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ISTREAMBUF_ITERATOR_H
#define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H
#include <__config>
#include <__iterator/default_sentinel.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <iosfwd> // for forward declaration of basic_streambuf
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template<class _CharT, class _Traits>
class _LIBCPP_TEMPLATE_VIS istreambuf_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<input_iterator_tag, _CharT,
typename _Traits::off_type, _CharT*,
_CharT>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
typedef input_iterator_tag iterator_category;
typedef _CharT value_type;
typedef typename _Traits::off_type difference_type;
typedef _CharT* pointer;
typedef _CharT reference;
typedef _CharT char_type;
typedef _Traits traits_type;
typedef typename _Traits::int_type int_type;
typedef basic_streambuf<_CharT,_Traits> streambuf_type;
typedef basic_istream<_CharT,_Traits> istream_type;
private:
mutable streambuf_type* __sbuf_;
class __proxy
{
char_type __keep_;
streambuf_type* __sbuf_;
_LIBCPP_INLINE_VISIBILITY
explicit __proxy(char_type __c, streambuf_type* __s)
: __keep_(__c), __sbuf_(__s) {}
friend class istreambuf_iterator;
public:
_LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;}
};
_LIBCPP_INLINE_VISIBILITY
bool __test_for_eof() const
{
if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
__sbuf_ = nullptr;
return __sbuf_ == nullptr;
}
public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {}
#if _LIBCPP_STD_VER >= 20
_LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept
: istreambuf_iterator() {}
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
: __sbuf_(__s.rdbuf()) {}
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
: __sbuf_(__s) {}
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT
: __sbuf_(__p.__sbuf_) {}
_LIBCPP_INLINE_VISIBILITY char_type operator*() const
{return static_cast<char_type>(__sbuf_->sgetc());}
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
{
__sbuf_->sbumpc();
return *this;
}
_LIBCPP_INLINE_VISIBILITY __proxy operator++(int)
{
return __proxy(__sbuf_->sbumpc(), __sbuf_);
}
_LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
{return __test_for_eof() == __b.__test_for_eof();}
#if _LIBCPP_STD_VER >= 20
friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) {
return __i.__test_for_eof();
}
#endif // _LIBCPP_STD_VER >= 20
};
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
const istreambuf_iterator<_CharT,_Traits>& __b)
{return __a.equal(__b);}
#if _LIBCPP_STD_VER <= 17
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
const istreambuf_iterator<_CharT,_Traits>& __b)
{return !__a.equal(__b);}
#endif // _LIBCPP_STD_VER <= 17
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H

View file

@ -0,0 +1,104 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ITER_MOVE_H
#define _LIBCPP___ITERATOR_ITER_MOVE_H
#include <__concepts/class_or_enum.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_reference.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
// [iterator.cust.move]
namespace ranges {
namespace __iter_move {
void iter_move();
template <class _Tp>
concept __unqualified_iter_move =
__class_or_enum<remove_cvref_t<_Tp>> &&
requires (_Tp&& __t) {
// NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap
iter_move(std::forward<_Tp>(__t));
};
template<class _Tp>
concept __move_deref =
!__unqualified_iter_move<_Tp> &&
requires (_Tp&& __t) {
*__t;
requires is_lvalue_reference_v<decltype(*__t)>;
};
template<class _Tp>
concept __just_deref =
!__unqualified_iter_move<_Tp> &&
!__move_deref<_Tp> &&
requires (_Tp&& __t) {
*__t;
requires (!is_lvalue_reference_v<decltype(*__t)>);
};
// [iterator.cust.move]
struct __fn {
// NOLINTBEGIN(libcpp-robust-against-adl) iter_move ADL calls should only be made through ranges::iter_move
template<class _Ip>
requires __unqualified_iter_move<_Ip>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
noexcept(noexcept(iter_move(std::forward<_Ip>(__i))))
{
return iter_move(std::forward<_Ip>(__i));
}
// NOLINTEND(libcpp-robust-against-adl)
template<class _Ip>
requires __move_deref<_Ip>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const
noexcept(noexcept(std::move(*std::forward<_Ip>(__i))))
-> decltype( std::move(*std::forward<_Ip>(__i)))
{ return std::move(*std::forward<_Ip>(__i)); }
template<class _Ip>
requires __just_deref<_Ip>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const
noexcept(noexcept(*std::forward<_Ip>(__i)))
-> decltype( *std::forward<_Ip>(__i))
{ return *std::forward<_Ip>(__i); }
};
} // namespace __iter_move
inline namespace __cpo {
inline constexpr auto iter_move = __iter_move::__fn{};
} // namespace __cpo
} // namespace ranges
template<__dereferenceable _Tp>
requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; }
using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>()));
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ITER_MOVE_H

View file

@ -0,0 +1,113 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ITER_SWAP_H
#define _LIBCPP___ITERATOR_ITER_SWAP_H
#include <__concepts/class_or_enum.h>
#include <__concepts/swappable.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iter_move.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
// [iter.cust.swap]
namespace ranges {
namespace __iter_swap {
template<class _I1, class _I2>
void iter_swap(_I1, _I2) = delete;
template<class _T1, class _T2>
concept __unqualified_iter_swap =
(__class_or_enum<remove_cvref_t<_T1>> || __class_or_enum<remove_cvref_t<_T2>>) &&
requires (_T1&& __x, _T2&& __y) {
// NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap
iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
};
template<class _T1, class _T2>
concept __readable_swappable =
indirectly_readable<_T1> && indirectly_readable<_T2> &&
swappable_with<iter_reference_t<_T1>, iter_reference_t<_T2>>;
struct __fn {
// NOLINTBEGIN(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap
template <class _T1, class _T2>
requires __unqualified_iter_swap<_T1, _T2>
_LIBCPP_HIDE_FROM_ABI
constexpr void operator()(_T1&& __x, _T2&& __y) const
noexcept(noexcept(iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y))))
{
(void)iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
}
// NOLINTEND(libcpp-robust-against-adl)
template <class _T1, class _T2>
requires (!__unqualified_iter_swap<_T1, _T2>) &&
__readable_swappable<_T1, _T2>
_LIBCPP_HIDE_FROM_ABI
constexpr void operator()(_T1&& __x, _T2&& __y) const
noexcept(noexcept(ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y))))
{
ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y));
}
template <class _T1, class _T2>
requires (!__unqualified_iter_swap<_T1, _T2> &&
!__readable_swappable<_T1, _T2>) &&
indirectly_movable_storable<_T1, _T2> &&
indirectly_movable_storable<_T2, _T1>
_LIBCPP_HIDE_FROM_ABI
constexpr void operator()(_T1&& __x, _T2&& __y) const
noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) &&
noexcept(*__y = ranges::iter_move(__x)) &&
noexcept(*_VSTD::forward<_T1>(__x) = std::declval<iter_value_t<_T2>>()))
{
iter_value_t<_T2> __old(ranges::iter_move(__y));
*__y = ranges::iter_move(__x);
*_VSTD::forward<_T1>(__x) = _VSTD::move(__old);
}
};
} // namespace __iter_swap
inline namespace __cpo {
inline constexpr auto iter_swap = __iter_swap::__fn{};
} // namespace __cpo
} // namespace ranges
template<class _I1, class _I2 = _I1>
concept indirectly_swappable =
indirectly_readable<_I1> && indirectly_readable<_I2> &&
requires(const _I1 __i1, const _I2 __i2) {
ranges::iter_swap(__i1, __i1);
ranges::iter_swap(__i2, __i2);
ranges::iter_swap(__i1, __i2);
ranges::iter_swap(__i2, __i1);
};
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ITER_SWAP_H

View file

@ -0,0 +1,35 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ITERATOR_H
#define _LIBCPP___ITERATOR_ITERATOR_H
#include <__config>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template<class _Category, class _Tp, class _Distance = ptrdiff_t,
class _Pointer = _Tp*, class _Reference = _Tp&>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator
{
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Pointer pointer;
typedef _Reference reference;
typedef _Category iterator_category;
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ITERATOR_H

View file

@ -0,0 +1,539 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ITERATOR_TRAITS_H
#define _LIBCPP___ITERATOR_ITERATOR_TRAITS_H
#include <__concepts/arithmetic.h>
#include <__concepts/constructible.h>
#include <__concepts/convertible_to.h>
#include <__concepts/copyable.h>
#include <__concepts/equality_comparable.h>
#include <__concepts/same_as.h>
#include <__concepts/totally_ordered.h>
#include <__config>
#include <__fwd/pair.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/readable_traits.h>
#include <__type_traits/add_const.h>
#include <__type_traits/common_reference.h>
#include <__type_traits/conditional.h>
#include <__type_traits/disjunction.h>
#include <__type_traits/is_convertible.h>
#include <__type_traits/is_object.h>
#include <__type_traits/is_primary_template.h>
#include <__type_traits/is_reference.h>
#include <__type_traits/is_valid_expansion.h>
#include <__type_traits/remove_const.h>
#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_cvref.h>
#include <__type_traits/void_t.h>
#include <__utility/declval.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template <class _Tp>
using __with_reference = _Tp&;
template <class _Tp>
concept __can_reference = requires {
typename __with_reference<_Tp>;
};
template <class _Tp>
concept __dereferenceable = requires(_Tp& __t) {
{ *__t } -> __can_reference; // not required to be equality-preserving
};
// [iterator.traits]
template<__dereferenceable _Tp>
using iter_reference_t = decltype(*std::declval<_Tp&>());
#endif // _LIBCPP_STD_VER >= 20
template <class _Iter>
struct _LIBCPP_TEMPLATE_VIS iterator_traits;
struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {};
struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {};
struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {};
struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
#if _LIBCPP_STD_VER >= 20
struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {};
#endif
template <class _Iter>
struct __iter_traits_cache {
using type = _If<
__is_primary_template<iterator_traits<_Iter> >::value,
_Iter,
iterator_traits<_Iter>
>;
};
template <class _Iter>
using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type;
struct __iter_concept_concept_test {
template <class _Iter>
using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept;
};
struct __iter_concept_category_test {
template <class _Iter>
using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category;
};
struct __iter_concept_random_fallback {
template <class _Iter>
using _Apply = __enable_if_t<
__is_primary_template<iterator_traits<_Iter> >::value,
random_access_iterator_tag
>;
};
template <class _Iter, class _Tester> struct __test_iter_concept
: _IsValidExpansion<_Tester::template _Apply, _Iter>,
_Tester
{
};
template <class _Iter>
struct __iter_concept_cache {
using type = _Or<
__test_iter_concept<_Iter, __iter_concept_concept_test>,
__test_iter_concept<_Iter, __iter_concept_category_test>,
__test_iter_concept<_Iter, __iter_concept_random_fallback>
>;
};
template <class _Iter>
using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>;
template <class _Tp>
struct __has_iterator_typedefs
{
private:
template <class _Up> static false_type __test(...);
template <class _Up> static true_type __test(__void_t<typename _Up::iterator_category>* = nullptr,
__void_t<typename _Up::difference_type>* = nullptr,
__void_t<typename _Up::value_type>* = nullptr,
__void_t<typename _Up::reference>* = nullptr,
__void_t<typename _Up::pointer>* = nullptr);
public:
static const bool value = decltype(__test<_Tp>(0,0,0,0,0))::value;
};
template <class _Tp>
struct __has_iterator_category
{
private:
template <class _Up> static false_type __test(...);
template <class _Up> static true_type __test(typename _Up::iterator_category* = nullptr);
public:
static const bool value = decltype(__test<_Tp>(nullptr))::value;
};
template <class _Tp>
struct __has_iterator_concept
{
private:
template <class _Up> static false_type __test(...);
template <class _Up> static true_type __test(typename _Up::iterator_concept* = nullptr);
public:
static const bool value = decltype(__test<_Tp>(nullptr))::value;
};
#if _LIBCPP_STD_VER >= 20
// The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements
// from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to
// a "detail" namespace indicating they have a niche use-case.
namespace __iterator_traits_detail {
template<class _Ip>
concept __cpp17_iterator =
requires(_Ip __i) {
{ *__i } -> __can_reference;
{ ++__i } -> same_as<_Ip&>;
{ *__i++ } -> __can_reference;
} &&
copyable<_Ip>;
template<class _Ip>
concept __cpp17_input_iterator =
__cpp17_iterator<_Ip> &&
equality_comparable<_Ip> &&
requires(_Ip __i) {
typename incrementable_traits<_Ip>::difference_type;
typename indirectly_readable_traits<_Ip>::value_type;
typename common_reference_t<iter_reference_t<_Ip>&&,
typename indirectly_readable_traits<_Ip>::value_type&>;
typename common_reference_t<decltype(*__i++)&&,
typename indirectly_readable_traits<_Ip>::value_type&>;
requires signed_integral<typename incrementable_traits<_Ip>::difference_type>;
};
template<class _Ip>
concept __cpp17_forward_iterator =
__cpp17_input_iterator<_Ip> &&
constructible_from<_Ip> &&
is_reference_v<iter_reference_t<_Ip>> &&
same_as<remove_cvref_t<iter_reference_t<_Ip>>,
typename indirectly_readable_traits<_Ip>::value_type> &&
requires(_Ip __i) {
{ __i++ } -> convertible_to<_Ip const&>;
{ *__i++ } -> same_as<iter_reference_t<_Ip>>;
};
template<class _Ip>
concept __cpp17_bidirectional_iterator =
__cpp17_forward_iterator<_Ip> &&
requires(_Ip __i) {
{ --__i } -> same_as<_Ip&>;
{ __i-- } -> convertible_to<_Ip const&>;
{ *__i-- } -> same_as<iter_reference_t<_Ip>>;
};
template<class _Ip>
concept __cpp17_random_access_iterator =
__cpp17_bidirectional_iterator<_Ip> &&
totally_ordered<_Ip> &&
requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) {
{ __i += __n } -> same_as<_Ip&>;
{ __i -= __n } -> same_as<_Ip&>;
{ __i + __n } -> same_as<_Ip>;
{ __n + __i } -> same_as<_Ip>;
{ __i - __n } -> same_as<_Ip>;
{ __i - __i } -> same_as<decltype(__n)>; // NOLINT(misc-redundant-expression) ; This is llvm.org/PR54114
{ __i[__n] } -> convertible_to<iter_reference_t<_Ip>>;
};
} // namespace __iterator_traits_detail
template<class _Ip>
concept __has_member_reference = requires { typename _Ip::reference; };
template<class _Ip>
concept __has_member_pointer = requires { typename _Ip::pointer; };
template<class _Ip>
concept __has_member_iterator_category = requires { typename _Ip::iterator_category; };
template<class _Ip>
concept __specifies_members = requires {
typename _Ip::value_type;
typename _Ip::difference_type;
requires __has_member_reference<_Ip>;
requires __has_member_iterator_category<_Ip>;
};
template<class>
struct __iterator_traits_member_pointer_or_void {
using type = void;
};
template<__has_member_pointer _Tp>
struct __iterator_traits_member_pointer_or_void<_Tp> {
using type = typename _Tp::pointer;
};
template<class _Tp>
concept __cpp17_iterator_missing_members =
!__specifies_members<_Tp> &&
__iterator_traits_detail::__cpp17_iterator<_Tp>;
template<class _Tp>
concept __cpp17_input_iterator_missing_members =
__cpp17_iterator_missing_members<_Tp> &&
__iterator_traits_detail::__cpp17_input_iterator<_Tp>;
// Otherwise, `pointer` names `void`.
template<class>
struct __iterator_traits_member_pointer_or_arrow_or_void { using type = void; };
// [iterator.traits]/3.2.1
// If the qualified-id `I::pointer` is valid and denotes a type, `pointer` names that type.
template<__has_member_pointer _Ip>
struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typename _Ip::pointer; };
// Otherwise, if `decltype(declval<I&>().operator->())` is well-formed, then `pointer` names that
// type.
template<class _Ip>
requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>)
struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> {
using type = decltype(std::declval<_Ip&>().operator->());
};
// Otherwise, `reference` names `iter-reference-t<I>`.
template<class _Ip>
struct __iterator_traits_member_reference { using type = iter_reference_t<_Ip>; };
// [iterator.traits]/3.2.2
// If the qualified-id `I::reference` is valid and denotes a type, `reference` names that type.
template<__has_member_reference _Ip>
struct __iterator_traits_member_reference<_Ip> { using type = typename _Ip::reference; };
// [iterator.traits]/3.2.3.4
// input_iterator_tag
template<class _Ip>
struct __deduce_iterator_category {
using type = input_iterator_tag;
};
// [iterator.traits]/3.2.3.1
// `random_access_iterator_tag` if `I` satisfies `cpp17-random-access-iterator`, or otherwise
template<__iterator_traits_detail::__cpp17_random_access_iterator _Ip>
struct __deduce_iterator_category<_Ip> {
using type = random_access_iterator_tag;
};
// [iterator.traits]/3.2.3.2
// `bidirectional_iterator_tag` if `I` satisfies `cpp17-bidirectional-iterator`, or otherwise
template<__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip>
struct __deduce_iterator_category<_Ip> {
using type = bidirectional_iterator_tag;
};
// [iterator.traits]/3.2.3.3
// `forward_iterator_tag` if `I` satisfies `cpp17-forward-iterator`, or otherwise
template<__iterator_traits_detail::__cpp17_forward_iterator _Ip>
struct __deduce_iterator_category<_Ip> {
using type = forward_iterator_tag;
};
template<class _Ip>
struct __iterator_traits_iterator_category : __deduce_iterator_category<_Ip> {};
// [iterator.traits]/3.2.3
// If the qualified-id `I::iterator-category` is valid and denotes a type, `iterator-category` names
// that type.
template<__has_member_iterator_category _Ip>
struct __iterator_traits_iterator_category<_Ip> {
using type = typename _Ip::iterator_category;
};
// otherwise, it names void.
template<class>
struct __iterator_traits_difference_type { using type = void; };
// If the qualified-id `incrementable_traits<I>::difference_type` is valid and denotes a type, then
// `difference_type` names that type;
template<class _Ip>
requires requires { typename incrementable_traits<_Ip>::difference_type; }
struct __iterator_traits_difference_type<_Ip> {
using type = typename incrementable_traits<_Ip>::difference_type;
};
// [iterator.traits]/3.4
// Otherwise, `iterator_traits<I>` has no members by any of the above names.
template<class>
struct __iterator_traits {};
// [iterator.traits]/3.1
// If `I` has valid ([temp.deduct]) member types `difference-type`, `value-type`, `reference`, and
// `iterator-category`, then `iterator-traits<I>` has the following publicly accessible members:
template<__specifies_members _Ip>
struct __iterator_traits<_Ip> {
using iterator_category = typename _Ip::iterator_category;
using value_type = typename _Ip::value_type;
using difference_type = typename _Ip::difference_type;
using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type;
using reference = typename _Ip::reference;
};
// [iterator.traits]/3.2
// Otherwise, if `I` satisfies the exposition-only concept `cpp17-input-iterator`,
// `iterator-traits<I>` has the following publicly accessible members:
template<__cpp17_input_iterator_missing_members _Ip>
struct __iterator_traits<_Ip> {
using iterator_category = typename __iterator_traits_iterator_category<_Ip>::type;
using value_type = typename indirectly_readable_traits<_Ip>::value_type;
using difference_type = typename incrementable_traits<_Ip>::difference_type;
using pointer = typename __iterator_traits_member_pointer_or_arrow_or_void<_Ip>::type;
using reference = typename __iterator_traits_member_reference<_Ip>::type;
};
// Otherwise, if `I` satisfies the exposition-only concept `cpp17-iterator`, then
// `iterator_traits<I>` has the following publicly accessible members:
template<__cpp17_iterator_missing_members _Ip>
struct __iterator_traits<_Ip> {
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type = typename __iterator_traits_difference_type<_Ip>::type;
using pointer = void;
using reference = void;
};
template<class _Ip>
struct iterator_traits : __iterator_traits<_Ip> {
using __primary_template = iterator_traits;
};
#else // _LIBCPP_STD_VER >= 20
template <class _Iter, bool> struct __iterator_traits {};
template <class _Iter, bool> struct __iterator_traits_impl {};
template <class _Iter>
struct __iterator_traits_impl<_Iter, true>
{
typedef typename _Iter::difference_type difference_type;
typedef typename _Iter::value_type value_type;
typedef typename _Iter::pointer pointer;
typedef typename _Iter::reference reference;
typedef typename _Iter::iterator_category iterator_category;
};
template <class _Iter>
struct __iterator_traits<_Iter, true>
: __iterator_traits_impl
<
_Iter,
is_convertible<typename _Iter::iterator_category, input_iterator_tag>::value ||
is_convertible<typename _Iter::iterator_category, output_iterator_tag>::value
>
{};
// iterator_traits<Iterator> will only have the nested types if Iterator::iterator_category
// exists. Else iterator_traits<Iterator> will be an empty class. This is a
// conforming extension which allows some programs to compile and behave as
// the client expects instead of failing at compile time.
template <class _Iter>
struct _LIBCPP_TEMPLATE_VIS iterator_traits
: __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {
using __primary_template = iterator_traits;
};
#endif // _LIBCPP_STD_VER >= 20
template<class _Tp>
#if _LIBCPP_STD_VER >= 20
requires is_object_v<_Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
{
typedef ptrdiff_t difference_type;
typedef __remove_cv_t<_Tp> value_type;
typedef _Tp* pointer;
typedef _Tp& reference;
typedef random_access_iterator_tag iterator_category;
#if _LIBCPP_STD_VER >= 20
typedef contiguous_iterator_tag iterator_concept;
#endif
};
template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
struct __has_iterator_category_convertible_to
: is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up>
{};
template <class _Tp, class _Up>
struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {};
template <class _Tp, class _Up, bool = __has_iterator_concept<_Tp>::value>
struct __has_iterator_concept_convertible_to
: is_convertible<typename _Tp::iterator_concept, _Up>
{};
template <class _Tp, class _Up>
struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {};
template <class _Tp>
using __has_input_iterator_category = __has_iterator_category_convertible_to<_Tp, input_iterator_tag>;
template <class _Tp>
using __has_forward_iterator_category = __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>;
template <class _Tp>
using __has_bidirectional_iterator_category = __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>;
template <class _Tp>
using __has_random_access_iterator_category = __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>;
// __libcpp_is_contiguous_iterator determines if an iterator is known by
// libc++ to be contiguous, either because it advertises itself as such
// (in C++20) or because it is a pointer type or a known trivial wrapper
// around a (possibly fancy) pointer type, such as __wrap_iter<T*>.
// Such iterators receive special "contiguous" optimizations in
// std::copy and std::sort.
//
#if _LIBCPP_STD_VER >= 20
template <class _Tp>
struct __libcpp_is_contiguous_iterator : _Or<
__has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>,
__has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag>
> {};
#else
template <class _Tp>
struct __libcpp_is_contiguous_iterator : false_type {};
#endif
// Any native pointer which is an iterator is also a contiguous iterator.
template <class _Up>
struct __libcpp_is_contiguous_iterator<_Up*> : true_type {};
template <class _Iter>
class __wrap_iter;
template <class _Tp>
using __has_exactly_input_iterator_category
= integral_constant<bool,
__has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
!__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value>;
template <class _Tp>
using __has_exactly_forward_iterator_category
= integral_constant<bool,
__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value &&
!__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value>;
template <class _Tp>
using __has_exactly_bidirectional_iterator_category
= integral_constant<bool,
__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value &&
!__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>;
template<class _InputIterator>
using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
template<class _InputIterator>
using __iter_key_type = __remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>;
template<class _InputIterator>
using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type;
template<class _InputIterator>
using __iter_to_alloc_type = pair<
typename add_const<typename iterator_traits<_InputIterator>::value_type::first_type>::type,
typename iterator_traits<_InputIterator>::value_type::second_type>;
template <class _Iter>
using __iterator_category_type = typename iterator_traits<_Iter>::iterator_category;
template <class _Iter>
using __iterator_pointer_type = typename iterator_traits<_Iter>::pointer;
template <class _Iter>
using __iter_diff_t = typename iterator_traits<_Iter>::difference_type;
template <class _Iter>
using __iter_reference = typename iterator_traits<_Iter>::reference;
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ITERATOR_TRAITS_H

View file

@ -0,0 +1,100 @@
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ITERATOR_WITH_DATA_H
#define _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H
#include <__compare/compare_three_way_result.h>
#include <__compare/three_way_comparable.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iter_move.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
template <forward_iterator _Iterator, class _Data>
class __iterator_with_data {
_Iterator __iter_{};
_Data __data_{};
public:
using value_type = iter_value_t<_Iterator>;
using difference_type = iter_difference_t<_Iterator>;
_LIBCPP_HIDE_FROM_ABI __iterator_with_data() = default;
constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data(_Iterator __iter, _Data __data)
: __iter_(std::move(__iter)), __data_(std::move(__data)) {}
constexpr _LIBCPP_HIDE_FROM_ABI _Iterator __get_iter() const { return __iter_; }
constexpr _LIBCPP_HIDE_FROM_ABI _Data __get_data() && { return std::move(__data_); }
friend constexpr _LIBCPP_HIDE_FROM_ABI bool
operator==(const __iterator_with_data& __lhs, const __iterator_with_data& __rhs) {
return __lhs.__iter_ == __rhs.__iter_;
}
constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator++() {
++__iter_;
return *this;
}
constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator++(int) {
auto __tmp = *this;
__iter_++;
return __tmp;
}
constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator--()
requires bidirectional_iterator<_Iterator>
{
--__iter_;
return *this;
}
constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator--(int)
requires bidirectional_iterator<_Iterator>
{
auto __tmp = *this;
--__iter_;
return __tmp;
}
constexpr _LIBCPP_HIDE_FROM_ABI iter_reference_t<_Iterator> operator*() const { return *__iter_; }
_LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iterator>
iter_move(const __iterator_with_data& __iter) noexcept(noexcept(ranges::iter_move(__iter.__iter_))) {
return ranges::iter_move(__iter.__iter_);
}
_LIBCPP_HIDE_FROM_ABI friend constexpr void
iter_swap(const __iterator_with_data& __lhs,
const __iterator_with_data& __rhs) noexcept(noexcept(ranges::iter_swap(__lhs.__iter_, __rhs.__iter_)))
requires indirectly_swappable<_Iterator>
{
return ranges::iter_swap(__lhs.__data_, __rhs.__iter_);
}
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H

View file

@ -0,0 +1,41 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_MERGEABLE_H
#define _LIBCPP___ITERATOR_MERGEABLE_H
#include <__config>
#include <__functional/identity.h>
#include <__functional/ranges_operations.h>
#include <__iterator/concepts.h>
#include <__iterator/projected.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template <class _Input1, class _Input2, class _Output,
class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity>
concept mergeable =
input_iterator<_Input1> &&
input_iterator<_Input2> &&
weakly_incrementable<_Output> &&
indirectly_copyable<_Input1, _Output> &&
indirectly_copyable<_Input2, _Output> &&
indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>;
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_MERGEABLE_H

View file

@ -0,0 +1,350 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_MOVE_ITERATOR_H
#define _LIBCPP___ITERATOR_MOVE_ITERATOR_H
#include <__compare/compare_three_way_result.h>
#include <__compare/three_way_comparable.h>
#include <__concepts/assignable.h>
#include <__concepts/convertible_to.h>
#include <__concepts/derived_from.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iter_move.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/move_sentinel.h>
#include <__iterator/readable_traits.h>
#include <__type_traits/conditional.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_assignable.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_convertible.h>
#include <__type_traits/is_reference.h>
#include <__type_traits/is_same.h>
#include <__type_traits/remove_reference.h>
#include <__utility/declval.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template<class _Iter, class = void>
struct __move_iter_category_base {};
template<class _Iter>
requires requires { typename iterator_traits<_Iter>::iterator_category; }
struct __move_iter_category_base<_Iter> {
using iterator_category = _If<
derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>,
random_access_iterator_tag,
typename iterator_traits<_Iter>::iterator_category
>;
};
template<class _Iter, class _Sent>
concept __move_iter_comparable = requires {
{ std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>;
};
#endif // _LIBCPP_STD_VER >= 20
template <class _Iter>
class _LIBCPP_TEMPLATE_VIS move_iterator
#if _LIBCPP_STD_VER >= 20
: public __move_iter_category_base<_Iter>
#endif
{
#if _LIBCPP_STD_VER >= 20
private:
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __get_iter_concept() {
if constexpr (random_access_iterator<_Iter>) {
return random_access_iterator_tag{};
} else if constexpr (bidirectional_iterator<_Iter>) {
return bidirectional_iterator_tag{};
} else if constexpr (forward_iterator<_Iter>) {
return forward_iterator_tag{};
} else {
return input_iterator_tag{};
}
}
#endif // _LIBCPP_STD_VER >= 20
public:
#if _LIBCPP_STD_VER >= 20
using iterator_type = _Iter;
using iterator_concept = decltype(__get_iter_concept());
// iterator_category is inherited and not always present
using value_type = iter_value_t<_Iter>;
using difference_type = iter_difference_t<_Iter>;
using pointer = _Iter;
using reference = iter_rvalue_reference_t<_Iter>;
#else
typedef _Iter iterator_type;
typedef _If<
__has_random_access_iterator_category<_Iter>::value,
random_access_iterator_tag,
typename iterator_traits<_Iter>::iterator_category
> iterator_category;
typedef typename iterator_traits<iterator_type>::value_type value_type;
typedef typename iterator_traits<iterator_type>::difference_type difference_type;
typedef iterator_type pointer;
typedef typename iterator_traits<iterator_type>::reference __reference;
typedef typename conditional<
is_reference<__reference>::value,
__libcpp_remove_reference_t<__reference>&&,
__reference
>::type reference;
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator& operator++() { ++__current_; return *this; }
_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
pointer operator->() const { return __current_; }
#if _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI constexpr
move_iterator() requires is_constructible_v<_Iter> : __current_() {}
template <class _Up>
requires (!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter>
_LIBCPP_HIDE_FROM_ABI constexpr
move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {}
template <class _Up>
requires (!_IsSame<_Up, _Iter>::value) &&
convertible_to<const _Up&, _Iter> &&
assignable_from<_Iter&, const _Up&>
_LIBCPP_HIDE_FROM_ABI constexpr
move_iterator& operator=(const move_iterator<_Up>& __u) {
__current_ = __u.base();
return *this;
}
_LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; }
_LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); }
_LIBCPP_HIDE_FROM_ABI constexpr
reference operator*() const { return ranges::iter_move(__current_); }
_LIBCPP_HIDE_FROM_ABI constexpr
reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); }
_LIBCPP_HIDE_FROM_ABI constexpr
auto operator++(int)
requires forward_iterator<_Iter>
{
move_iterator __tmp(*this); ++__current_; return __tmp;
}
_LIBCPP_HIDE_FROM_ABI constexpr
void operator++(int) { ++__current_; }
#else
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator() : __current_() {}
template <class _Up, class = __enable_if_t<
!is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value
> >
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {}
template <class _Up, class = __enable_if_t<
!is_same<_Up, _Iter>::value &&
is_convertible<const _Up&, _Iter>::value &&
is_assignable<_Iter&, const _Up&>::value
> >
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator& operator=(const move_iterator<_Up>& __u) {
__current_ = __u.base();
return *this;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
_Iter base() const { return __current_; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
reference operator*() const { return static_cast<reference>(*__current_); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; }
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator& operator--() { --__current_; return *this; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; }
#if _LIBCPP_STD_VER >= 20
template<sentinel_for<_Iter> _Sent>
friend _LIBCPP_HIDE_FROM_ABI constexpr
bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
requires __move_iter_comparable<_Iter, _Sent>
{
return __x.base() == __y.base();
}
template<sized_sentinel_for<_Iter> _Sent>
friend _LIBCPP_HIDE_FROM_ABI constexpr
iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y)
{
return __x.base() - __y.base();
}
template<sized_sentinel_for<_Iter> _Sent>
friend _LIBCPP_HIDE_FROM_ABI constexpr
iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y)
{
return __x.base() - __y.base();
}
friend _LIBCPP_HIDE_FROM_ABI constexpr
iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i)
noexcept(noexcept(ranges::iter_move(__i.__current_)))
{
return ranges::iter_move(__i.__current_);
}
template<indirectly_swappable<_Iter> _It2>
friend _LIBCPP_HIDE_FROM_ABI constexpr
void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y)
noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
{
return ranges::iter_swap(__x.__current_, __y.__current_);
}
#endif // _LIBCPP_STD_VER >= 20
private:
template<class _It2> friend class move_iterator;
_Iter __current_;
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator);
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
{
return __x.base() == __y.base();
}
#if _LIBCPP_STD_VER <= 17
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
{
return __x.base() != __y.base();
}
#endif // _LIBCPP_STD_VER <= 17
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
{
return __x.base() < __y.base();
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
{
return __x.base() > __y.base();
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
{
return __x.base() <= __y.base();
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
{
return __x.base() >= __y.base();
}
#if _LIBCPP_STD_VER >= 20
template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
inline _LIBCPP_HIDE_FROM_ABI constexpr
auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
-> compare_three_way_result_t<_Iter1, _Iter2>
{
return __x.base() <=> __y.base();
}
#endif // _LIBCPP_STD_VER >= 20
#ifndef _LIBCPP_CXX03_LANG
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
-> decltype(__x.base() - __y.base())
{
return __x.base() - __y.base();
}
#else
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI
typename move_iterator<_Iter1>::difference_type
operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
{
return __x.base() - __y.base();
}
#endif // !_LIBCPP_CXX03_LANG
#if _LIBCPP_STD_VER >= 20
template <class _Iter>
inline _LIBCPP_HIDE_FROM_ABI constexpr
move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x)
requires requires { { __x.base() + __n } -> same_as<_Iter>; }
{
return __x + __n;
}
#else
template <class _Iter>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator<_Iter>
operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
{
return move_iterator<_Iter>(__x.base() + __n);
}
#endif // _LIBCPP_STD_VER >= 20
template <class _Iter>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
move_iterator<_Iter>
make_move_iterator(_Iter __i)
{
return move_iterator<_Iter>(std::move(__i));
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H

View file

@ -0,0 +1,59 @@
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_MOVE_SENTINEL_H
#define _LIBCPP___ITERATOR_MOVE_SENTINEL_H
#include <__concepts/assignable.h>
#include <__concepts/convertible_to.h>
#include <__concepts/semiregular.h>
#include <__config>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template <semiregular _Sent>
class _LIBCPP_TEMPLATE_VIS move_sentinel
{
public:
_LIBCPP_HIDE_FROM_ABI
move_sentinel() = default;
_LIBCPP_HIDE_FROM_ABI constexpr
explicit move_sentinel(_Sent __s) : __last_(std::move(__s)) {}
template <class _S2>
requires convertible_to<const _S2&, _Sent>
_LIBCPP_HIDE_FROM_ABI constexpr
move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {}
template <class _S2>
requires assignable_from<_Sent&, const _S2&>
_LIBCPP_HIDE_FROM_ABI constexpr
move_sentinel& operator=(const move_sentinel<_S2>& __s)
{ __last_ = __s.base(); return *this; }
_LIBCPP_HIDE_FROM_ABI constexpr _Sent base() const { return __last_; }
private:
_Sent __last_ = _Sent();
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel);
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H

84
third_party/libcxx/__iterator/next.h vendored Normal file
View file

@ -0,0 +1,84 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_NEXT_H
#define _LIBCPP___ITERATOR_NEXT_H
#include <__assert>
#include <__config>
#include <__iterator/advance.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type
next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
_LIBCPP_ASSERT(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value,
"Attempt to next(it, n) with negative n on a non-bidirectional iterator");
_VSTD::advance(__x, __n);
return __x;
}
#if _LIBCPP_STD_VER >= 20
// [range.iter.op.next]
namespace ranges {
namespace __next {
struct __fn {
template <input_or_output_iterator _Ip>
_LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x) const {
++__x;
return __x;
}
template <input_or_output_iterator _Ip>
_LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const {
ranges::advance(__x, __n);
return __x;
}
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
_LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, _Sp __bound_sentinel) const {
ranges::advance(__x, __bound_sentinel);
return __x;
}
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
_LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound_sentinel) const {
ranges::advance(__x, __n, __bound_sentinel);
return __x;
}
};
} // namespace __next
inline namespace __cpo {
inline constexpr auto next = __next::__fn{};
} // namespace __cpo
} // namespace ranges
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_NEXT_H

View file

@ -0,0 +1,71 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_OSTREAM_ITERATOR_H
#define _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H
#include <__config>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <cstddef>
#include <iosfwd> // for forward declarations of char_traits and basic_ostream
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
class _LIBCPP_TEMPLATE_VIS ostream_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
#if _LIBCPP_STD_VER >= 20
typedef ptrdiff_t difference_type;
#else
typedef void difference_type;
#endif
typedef void pointer;
typedef void reference;
typedef _CharT char_type;
typedef _Traits traits_type;
typedef basic_ostream<_CharT, _Traits> ostream_type;
private:
ostream_type* __out_stream_;
const char_type* __delim_;
public:
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT
: __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {}
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
: __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {}
_LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value)
{
*__out_stream_ << __value;
if (__delim_)
*__out_stream_ << __delim_;
return *this;
}
_LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++() {return *this;}
_LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H

View file

@ -0,0 +1,77 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_OSTREAMBUF_ITERATOR_H
#define _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
#include <__config>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <cstddef>
#include <iosfwd> // for forward declaration of basic_streambuf
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _CharT, class _Traits>
class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
#if _LIBCPP_STD_VER >= 20
typedef ptrdiff_t difference_type;
#else
typedef void difference_type;
#endif
typedef void pointer;
typedef void reference;
typedef _CharT char_type;
typedef _Traits traits_type;
typedef basic_streambuf<_CharT, _Traits> streambuf_type;
typedef basic_ostream<_CharT, _Traits> ostream_type;
private:
streambuf_type* __sbuf_;
public:
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
: __sbuf_(__s.rdbuf()) {}
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
: __sbuf_(__s) {}
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c)
{
if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))
__sbuf_ = nullptr;
return *this;
}
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++() {return *this;}
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}
_LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == nullptr;}
template <class _Ch, class _Tr>
friend
_LIBCPP_HIDE_FROM_ABI
ostreambuf_iterator<_Ch, _Tr>
__pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,
const _Ch* __ob, const _Ch* __op, const _Ch* __oe,
ios_base& __iob, _Ch __fl);
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H

View file

@ -0,0 +1,35 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_PERMUTABLE_H
#define _LIBCPP___ITERATOR_PERMUTABLE_H
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iter_swap.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template <class _Iterator>
concept permutable =
forward_iterator<_Iterator> &&
indirectly_movable_storable<_Iterator, _Iterator> &&
indirectly_swappable<_Iterator, _Iterator>;
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_PERMUTABLE_H

77
third_party/libcxx/__iterator/prev.h vendored Normal file
View file

@ -0,0 +1,77 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_PREV_H
#define _LIBCPP___ITERATOR_PREV_H
#include <__assert>
#include <__config>
#include <__iterator/advance.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type
prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
_LIBCPP_ASSERT(__n <= 0 || __has_bidirectional_iterator_category<_InputIter>::value,
"Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
_VSTD::advance(__x, -__n);
return __x;
}
#if _LIBCPP_STD_VER >= 20
// [range.iter.op.prev]
namespace ranges {
namespace __prev {
struct __fn {
template <bidirectional_iterator _Ip>
_LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x) const {
--__x;
return __x;
}
template <bidirectional_iterator _Ip>
_LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const {
ranges::advance(__x, -__n);
return __x;
}
template <bidirectional_iterator _Ip>
_LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound_iter) const {
ranges::advance(__x, -__n, __bound_iter);
return __x;
}
};
} // namespace __prev
inline namespace __cpo {
inline constexpr auto prev = __prev::__fn{};
} // namespace __cpo
} // namespace ranges
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_PREV_H

View file

@ -0,0 +1,41 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_PROJECTED_H
#define _LIBCPP___ITERATOR_PROJECTED_H
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template<indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj>
struct projected {
using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>;
indirect_result_t<_Proj&, _It> operator*() const; // not defined
};
template<weakly_incrementable _It, class _Proj>
struct incrementable_traits<projected<_It, _Proj>> {
using difference_type = iter_difference_t<_It>;
};
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_PROJECTED_H

View file

@ -0,0 +1,92 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_READABLE_TRAITS_H
#define _LIBCPP___ITERATOR_READABLE_TRAITS_H
#include <__concepts/same_as.h>
#include <__config>
#include <__type_traits/conditional.h>
#include <__type_traits/is_array.h>
#include <__type_traits/is_object.h>
#include <__type_traits/is_primary_template.h>
#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_cvref.h>
#include <__type_traits/remove_extent.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
// [readable.traits]
template<class> struct __cond_value_type {};
template<class _Tp>
requires is_object_v<_Tp>
struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; };
template<class _Tp>
concept __has_member_value_type = requires { typename _Tp::value_type; };
template<class _Tp>
concept __has_member_element_type = requires { typename _Tp::element_type; };
template<class> struct indirectly_readable_traits {};
template<class _Ip>
requires is_array_v<_Ip>
struct indirectly_readable_traits<_Ip> {
using value_type = remove_cv_t<remove_extent_t<_Ip>>;
};
template<class _Ip>
struct indirectly_readable_traits<const _Ip> : indirectly_readable_traits<_Ip> {};
template<class _Tp>
struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {};
template<__has_member_value_type _Tp>
struct indirectly_readable_traits<_Tp>
: __cond_value_type<typename _Tp::value_type> {};
template<__has_member_element_type _Tp>
struct indirectly_readable_traits<_Tp>
: __cond_value_type<typename _Tp::element_type> {};
template<__has_member_value_type _Tp>
requires __has_member_element_type<_Tp>
struct indirectly_readable_traits<_Tp> {};
template<__has_member_value_type _Tp>
requires __has_member_element_type<_Tp> &&
same_as<remove_cv_t<typename _Tp::element_type>,
remove_cv_t<typename _Tp::value_type>>
struct indirectly_readable_traits<_Tp>
: __cond_value_type<typename _Tp::value_type> {};
template <class>
struct iterator_traits;
// Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes
// `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization
// generated from the primary template, and `iterator_traits<RI>::value_type` otherwise.
template <class _Ip>
using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
indirectly_readable_traits<remove_cvref_t<_Ip> >,
iterator_traits<remove_cvref_t<_Ip> > >::value_type;
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H

View file

@ -0,0 +1,100 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_REVERSE_ACCESS_H
#define _LIBCPP___ITERATOR_REVERSE_ACCESS_H
#include <__config>
#include <__iterator/reverse_iterator.h>
#include <cstddef>
#include <initializer_list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 14
template <class _Tp, size_t _Np>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
{
return reverse_iterator<_Tp*>(__array + _Np);
}
template <class _Tp, size_t _Np>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
{
return reverse_iterator<_Tp*>(__array);
}
template <class _Ep>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
{
return reverse_iterator<const _Ep*>(__il.end());
}
template <class _Ep>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
{
return reverse_iterator<const _Ep*>(__il.begin());
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
{
return __c.rbegin();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
{
return __c.rbegin();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto rend(_Cp& __c) -> decltype(__c.rend())
{
return __c.rend();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto rend(const _Cp& __c) -> decltype(__c.rend())
{
return __c.rend();
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c))
{
return _VSTD::rbegin(__c);
}
template <class _Cp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
{
return _VSTD::rend(__c);
}
#endif // _LIBCPP_STD_VER >= 14
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_REVERSE_ACCESS_H

View file

@ -0,0 +1,533 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_REVERSE_ITERATOR_H
#define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
#include <__algorithm/unwrap_iter.h>
#include <__compare/compare_three_way_result.h>
#include <__compare/three_way_comparable.h>
#include <__concepts/convertible_to.h>
#include <__config>
#include <__iterator/advance.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iter_move.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/next.h>
#include <__iterator/prev.h>
#include <__iterator/readable_traits.h>
#include <__iterator/segmented_iterator.h>
#include <__memory/addressof.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/subrange.h>
#include <__type_traits/conditional.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_assignable.h>
#include <__type_traits/is_convertible.h>
#include <__type_traits/is_nothrow_copy_constructible.h>
#include <__type_traits/is_pointer.h>
#include <__type_traits/is_same.h>
#include <__utility/declval.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Iter>
class _LIBCPP_TEMPLATE_VIS reverse_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<typename iterator_traits<_Iter>::iterator_category,
typename iterator_traits<_Iter>::value_type,
typename iterator_traits<_Iter>::difference_type,
typename iterator_traits<_Iter>::pointer,
typename iterator_traits<_Iter>::reference>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
private:
#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
_Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break
#endif
#if _LIBCPP_STD_VER >= 20
static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>,
"reverse_iterator<It> requires It to be a bidirectional iterator.");
#endif // _LIBCPP_STD_VER >= 20
protected:
_Iter current;
public:
using iterator_type = _Iter;
using iterator_category = _If<__has_random_access_iterator_category<_Iter>::value,
random_access_iterator_tag,
typename iterator_traits<_Iter>::iterator_category>;
using pointer = typename iterator_traits<_Iter>::pointer;
#if _LIBCPP_STD_VER >= 20
using iterator_concept = _If<random_access_iterator<_Iter>, random_access_iterator_tag, bidirectional_iterator_tag>;
using value_type = iter_value_t<_Iter>;
using difference_type = iter_difference_t<_Iter>;
using reference = iter_reference_t<_Iter>;
#else
using value_type = typename iterator_traits<_Iter>::value_type;
using difference_type = typename iterator_traits<_Iter>::difference_type;
using reference = typename iterator_traits<_Iter>::reference;
#endif
#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator() : __t_(), current() {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {}
template <class _Up, class = __enable_if_t<
!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator(const reverse_iterator<_Up>& __u)
: __t_(__u.base()), current(__u.base())
{ }
template <class _Up, class = __enable_if_t<
!is_same<_Up, _Iter>::value &&
is_convertible<_Up const&, _Iter>::value &&
is_assignable<_Iter&, _Up const&>::value
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
__t_ = current = __u.base();
return *this;
}
#else
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator() : current() {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
explicit reverse_iterator(_Iter __x) : current(__x) {}
template <class _Up, class = __enable_if_t<
!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator(const reverse_iterator<_Up>& __u)
: current(__u.base())
{ }
template <class _Up, class = __enable_if_t<
!is_same<_Up, _Iter>::value &&
is_convertible<_Up const&, _Iter>::value &&
is_assignable<_Iter&, _Up const&>::value
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
current = __u.base();
return *this;
}
#endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
_Iter base() const {return current;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reference operator*() const {_Iter __tmp = current; return *--__tmp;}
#if _LIBCPP_STD_VER >= 20
_LIBCPP_INLINE_VISIBILITY
constexpr pointer operator->() const
requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); }
{
if constexpr (is_pointer_v<_Iter>) {
return std::prev(current);
} else {
return std::prev(current).operator->();
}
}
#else
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
pointer operator->() const {
return std::addressof(operator*());
}
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator& operator++() {--current; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator& operator--() {++current; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reference operator[](difference_type __n) const {return *(*this + __n);}
#if _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI friend constexpr
iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i)
noexcept(is_nothrow_copy_constructible_v<_Iter> &&
noexcept(ranges::iter_move(--std::declval<_Iter&>()))) {
auto __tmp = __i.base();
return ranges::iter_move(--__tmp);
}
template <indirectly_swappable<_Iter> _Iter2>
_LIBCPP_HIDE_FROM_ABI friend constexpr
void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y)
noexcept(is_nothrow_copy_constructible_v<_Iter> &&
is_nothrow_copy_constructible_v<_Iter2> &&
noexcept(ranges::iter_swap(--std::declval<_Iter&>(), --std::declval<_Iter2&>()))) {
auto __xtmp = __x.base();
auto __ytmp = __y.base();
ranges::iter_swap(--__xtmp, --__ytmp);
}
#endif // _LIBCPP_STD_VER >= 20
};
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
bool
operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
#if _LIBCPP_STD_VER >= 20
requires requires {
{ __x.base() == __y.base() } -> convertible_to<bool>;
}
#endif // _LIBCPP_STD_VER >= 20
{
return __x.base() == __y.base();
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
bool
operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
#if _LIBCPP_STD_VER >= 20
requires requires {
{ __x.base() > __y.base() } -> convertible_to<bool>;
}
#endif // _LIBCPP_STD_VER >= 20
{
return __x.base() > __y.base();
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
bool
operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
#if _LIBCPP_STD_VER >= 20
requires requires {
{ __x.base() != __y.base() } -> convertible_to<bool>;
}
#endif // _LIBCPP_STD_VER >= 20
{
return __x.base() != __y.base();
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
bool
operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
#if _LIBCPP_STD_VER >= 20
requires requires {
{ __x.base() < __y.base() } -> convertible_to<bool>;
}
#endif // _LIBCPP_STD_VER >= 20
{
return __x.base() < __y.base();
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
bool
operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
#if _LIBCPP_STD_VER >= 20
requires requires {
{ __x.base() <= __y.base() } -> convertible_to<bool>;
}
#endif // _LIBCPP_STD_VER >= 20
{
return __x.base() <= __y.base();
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
bool
operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
#if _LIBCPP_STD_VER >= 20
requires requires {
{ __x.base() >= __y.base() } -> convertible_to<bool>;
}
#endif // _LIBCPP_STD_VER >= 20
{
return __x.base() >= __y.base();
}
#if _LIBCPP_STD_VER >= 20
template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
_LIBCPP_HIDE_FROM_ABI constexpr
compare_three_way_result_t<_Iter1, _Iter2>
operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
{
return __y.base() <=> __x.base();
}
#endif // _LIBCPP_STD_VER >= 20
#ifndef _LIBCPP_CXX03_LANG
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
auto
operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
-> decltype(__y.base() - __x.base())
{
return __y.base() - __x.base();
}
#else
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY
typename reverse_iterator<_Iter1>::difference_type
operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
{
return __y.base() - __x.base();
}
#endif
template <class _Iter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator<_Iter>
operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
{
return reverse_iterator<_Iter>(__x.base() - __n);
}
#if _LIBCPP_STD_VER >= 20
template <class _Iter1, class _Iter2>
requires (!sized_sentinel_for<_Iter1, _Iter2>)
inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true;
#endif // _LIBCPP_STD_VER >= 20
#if _LIBCPP_STD_VER >= 14
template <class _Iter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
{
return reverse_iterator<_Iter>(__i);
}
#endif
#if _LIBCPP_STD_VER <= 17
template <class _Iter>
using __unconstrained_reverse_iterator = reverse_iterator<_Iter>;
#else
// __unconstrained_reverse_iterator allows us to use reverse iterators in the implementation of algorithms by working
// around a language issue in C++20.
// In C++20, when a reverse iterator wraps certain C++20-hostile iterators, calling comparison operators on it will
// result in a compilation error. However, calling comparison operators on the pristine hostile iterator is not
// an error. Thus, we cannot use reverse_iterators in the implementation of an algorithm that accepts a
// C++20-hostile iterator. This class is an internal workaround -- it is a copy of reverse_iterator with
// tweaks to make it support hostile iterators.
//
// A C++20-hostile iterator is one that defines a comparison operator where one of the arguments is an exact match
// and the other requires an implicit conversion, for example:
// friend bool operator==(const BaseIter&, const DerivedIter&);
//
// C++20 rules for rewriting equality operators create another overload of this function with parameters reversed:
// friend bool operator==(const DerivedIter&, const BaseIter&);
//
// This creates an ambiguity in overload resolution.
//
// Clang treats this ambiguity differently in different contexts. When operator== is actually called in the function
// body, the code is accepted with a warning. When a concept requires operator== to be a valid expression, however,
// it evaluates to false. Thus, the implementation of reverse_iterator::operator== can actually call operator== on its
// base iterators, but the constraints on reverse_iterator::operator== prevent it from being considered during overload
// resolution. This class simply removes the problematic constraints from comparison functions.
template <class _Iter>
class __unconstrained_reverse_iterator {
_Iter __iter_;
public:
static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>);
using iterator_type = _Iter;
using iterator_category =
_If<__has_random_access_iterator_category<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>;
using pointer = __iterator_pointer_type<_Iter>;
using value_type = iter_value_t<_Iter>;
using difference_type = iter_difference_t<_Iter>;
using reference = iter_reference_t<_Iter>;
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator() = default;
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator(const __unconstrained_reverse_iterator&) = default;
_LIBCPP_HIDE_FROM_ABI constexpr explicit __unconstrained_reverse_iterator(_Iter __iter) : __iter_(__iter) {}
_LIBCPP_HIDE_FROM_ABI constexpr _Iter base() const { return __iter_; }
_LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const {
auto __tmp = __iter_;
return *--__tmp;
}
_LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const {
if constexpr (is_pointer_v<_Iter>) {
return std::prev(__iter_);
} else {
return std::prev(__iter_).operator->();
}
}
_LIBCPP_HIDE_FROM_ABI friend constexpr
iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i)
noexcept(is_nothrow_copy_constructible_v<_Iter> &&
noexcept(ranges::iter_move(--std::declval<_Iter&>()))) {
auto __tmp = __i.base();
return ranges::iter_move(--__tmp);
}
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator++() {
--__iter_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator++(int) {
auto __tmp = *this;
--__iter_;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator--() {
++__iter_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator--(int) {
auto __tmp = *this;
++__iter_;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator+=(difference_type __n) {
__iter_ -= __n;
return *this;
}
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator-=(difference_type __n) {
__iter_ += __n;
return *this;
}
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator+(difference_type __n) const {
return __unconstrained_reverse_iterator(__iter_ - __n);
}
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator-(difference_type __n) const {
return __unconstrained_reverse_iterator(__iter_ + __n);
}
_LIBCPP_HIDE_FROM_ABI constexpr difference_type operator-(const __unconstrained_reverse_iterator& __other) const {
return __other.__iter_ - __iter_;
}
_LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const { return *(*this + __n); }
// Deliberately unconstrained unlike the comparison functions in `reverse_iterator` -- see the class comment for the
// rationale.
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
operator==(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
return __lhs.base() == __rhs.base();
}
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
operator!=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
return __lhs.base() != __rhs.base();
}
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
operator<(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
return __lhs.base() > __rhs.base();
}
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
operator>(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
return __lhs.base() < __rhs.base();
}
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
operator<=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
return __lhs.base() >= __rhs.base();
}
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
operator>=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
return __lhs.base() <= __rhs.base();
}
};
#endif // _LIBCPP_STD_VER <= 17
template <template <class> class _RevIter1, template <class> class _RevIter2, class _Iter>
struct __unwrap_reverse_iter_impl {
using _UnwrappedIter = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>()));
using _ReverseWrapper = _RevIter1<_RevIter2<_Iter> >;
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ReverseWrapper
__rewrap(_ReverseWrapper __orig_iter, _UnwrappedIter __unwrapped_iter) {
return _ReverseWrapper(
_RevIter2<_Iter>(__unwrap_iter_impl<_Iter>::__rewrap(__orig_iter.base().base(), __unwrapped_iter)));
}
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _UnwrappedIter __unwrap(_ReverseWrapper __i) _NOEXCEPT {
return __unwrap_iter_impl<_Iter>::__unwrap(__i.base().base());
}
};
#if _LIBCPP_STD_VER >= 20
template <ranges::bidirectional_range _Range>
_LIBCPP_HIDE_FROM_ABI constexpr ranges::
subrange<reverse_iterator<ranges::iterator_t<_Range>>, reverse_iterator<ranges::iterator_t<_Range>>>
__reverse_range(_Range&& __range) {
auto __first = ranges::begin(__range);
return {std::make_reverse_iterator(ranges::next(__first, ranges::end(__range))), std::make_reverse_iterator(__first)};
}
#endif
template <class _Iter, bool __b>
struct __unwrap_iter_impl<reverse_iterator<reverse_iterator<_Iter> >, __b>
: __unwrap_reverse_iter_impl<reverse_iterator, reverse_iterator, _Iter> {};
#if _LIBCPP_STD_VER >= 20
template <class _Iter, bool __b>
struct __unwrap_iter_impl<reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
: __unwrap_reverse_iter_impl<reverse_iterator, __unconstrained_reverse_iterator, _Iter> {};
template <class _Iter, bool __b>
struct __unwrap_iter_impl<__unconstrained_reverse_iterator<reverse_iterator<_Iter>>, __b>
: __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, reverse_iterator, _Iter> {};
template <class _Iter, bool __b>
struct __unwrap_iter_impl<__unconstrained_reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
: __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, __unconstrained_reverse_iterator, _Iter> {};
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H

View file

@ -0,0 +1,79 @@
//===----------------------------------------------------------------------===//
//
// 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___SEGMENTED_ITERATOR_H
#define _LIBCPP___SEGMENTED_ITERATOR_H
// Segmented iterators are iterators over (not necessarily contiguous) sub-ranges.
//
// For example, std::deque stores its data into multiple blocks of contiguous memory,
// which are not stored contiguously themselves. The concept of segmented iterators
// allows algorithms to operate over these multi-level iterators natively, opening the
// door to various optimizations. See http://lafstern.org/matt/segmented.pdf for details.
//
// If __segmented_iterator_traits can be instantiated, the following functions and associated types must be provided:
// - Traits::__local_iterator
// The type of iterators used to iterate inside a segment.
//
// - Traits::__segment_iterator
// The type of iterators used to iterate over segments.
// Segment iterators can be forward iterators or bidirectional iterators, depending on the
// underlying data structure.
//
// - static __segment_iterator Traits::__segment(It __it)
// Returns an iterator to the segment that the provided iterator is in.
//
// - static __local_iterator Traits::__local(It __it)
// Returns the local iterator pointing to the element that the provided iterator points to.
//
// - static __local_iterator Traits::__begin(__segment_iterator __it)
// Returns the local iterator to the beginning of the segment that the provided iterator is pointing into.
//
// - static __local_iterator Traits::__end(__segment_iterator __it)
// Returns the one-past-the-end local iterator to the segment that the provided iterator is pointing into.
//
// - static It Traits::__compose(__segment_iterator, __local_iterator)
// Returns the iterator composed of the segment iterator and local iterator.
#include <__config>
#include <__type_traits/integral_constant.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Iterator>
struct __segmented_iterator_traits;
/* exposition-only:
{
using __segment_iterator = ...;
using __local_iterator = ...;
static __segment_iterator __segment(_Iterator);
static __local_iterator __local(_Iterator);
static __local_iterator __begin(__segment_iterator);
static __local_iterator __end(__segment_iterator);
static _Iterator __compose(__segment_iterator, __local_iterator);
};
*/
template <class _Tp, size_t = 0>
struct __has_specialization : false_type {};
template <class _Tp>
struct __has_specialization<_Tp, sizeof(_Tp) * 0> : true_type {};
template <class _Iterator>
using __is_segmented_iterator = __has_specialization<__segmented_iterator_traits<_Iterator> >;
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___SEGMENTED_ITERATOR_H

59
third_party/libcxx/__iterator/size.h vendored Normal file
View file

@ -0,0 +1,59 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_SIZE_H
#define _LIBCPP___ITERATOR_SIZE_H
#include <__config>
#include <__type_traits/common_type.h>
#include <__type_traits/make_signed.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 17
template <class _Cont>
_LIBCPP_INLINE_VISIBILITY
constexpr auto size(const _Cont& __c)
_NOEXCEPT_(noexcept(__c.size()))
-> decltype (__c.size())
{ return __c.size(); }
template <class _Tp, size_t _Sz>
_LIBCPP_INLINE_VISIBILITY
constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
#if _LIBCPP_STD_VER >= 20
template <class _Cont>
_LIBCPP_INLINE_VISIBILITY
constexpr auto ssize(const _Cont& __c)
_NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size())))
-> common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>
{ return static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); }
// GCC complains about the implicit conversion from ptrdiff_t to size_t in
// the array bound.
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wsign-conversion")
template <class _Tp, ptrdiff_t _Sz>
_LIBCPP_INLINE_VISIBILITY
constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
_LIBCPP_DIAGNOSTIC_POP
#endif
#endif // _LIBCPP_STD_VER >= 17
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_SIZE_H

View file

@ -0,0 +1,37 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_SORTABLE_H
#define _LIBCPP___ITERATOR_SORTABLE_H
#include <__config>
#include <__functional/identity.h>
#include <__functional/ranges_operations.h>
#include <__iterator/concepts.h>
#include <__iterator/permutable.h>
#include <__iterator/projected.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template <class _Iter, class _Comp = ranges::less, class _Proj = identity>
concept sortable =
permutable<_Iter> &&
indirect_strict_weak_order<_Comp, projected<_Iter, _Proj>>;
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_SORTABLE_H

View file

@ -0,0 +1,38 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_UNREACHABLE_SENTINEL_H
#define _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H
#include <__config>
#include <__iterator/concepts.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
struct unreachable_sentinel_t {
template<weakly_incrementable _Iter>
_LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(unreachable_sentinel_t, const _Iter&) noexcept {
return false;
}
};
inline constexpr unreachable_sentinel_t unreachable_sentinel{};
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H

View file

@ -0,0 +1,286 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_WRAP_ITER_H
#define _LIBCPP___ITERATOR_WRAP_ITER_H
#include <__config>
#include <__debug>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__memory/pointer_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_convertible.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Iter>
class __wrap_iter
{
public:
typedef _Iter iterator_type;
typedef typename iterator_traits<iterator_type>::value_type value_type;
typedef typename iterator_traits<iterator_type>::difference_type difference_type;
typedef typename iterator_traits<iterator_type>::pointer pointer;
typedef typename iterator_traits<iterator_type>::reference reference;
typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
#if _LIBCPP_STD_VER >= 20
typedef contiguous_iterator_tag iterator_concept;
#endif
private:
iterator_type __i_;
public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT
: __i_()
{
_VSTD::__debug_db_insert_i(this);
}
template <class _Up> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
__wrap_iter(const __wrap_iter<_Up>& __u,
typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT
: __i_(__u.base())
{
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (!__libcpp_is_constant_evaluated())
__get_db()->__iterator_copy(this, _VSTD::addressof(__u));
#endif
}
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
__wrap_iter(const __wrap_iter& __x)
: __i_(__x.base())
{
if (!__libcpp_is_constant_evaluated())
__get_db()->__iterator_copy(this, _VSTD::addressof(__x));
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
__wrap_iter& operator=(const __wrap_iter& __x)
{
if (this != _VSTD::addressof(__x))
{
if (!__libcpp_is_constant_evaluated())
__get_db()->__iterator_copy(this, _VSTD::addressof(__x));
__i_ = __x.__i_;
}
return *this;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
~__wrap_iter()
{
if (!__libcpp_is_constant_evaluated())
__get_db()->__erase_i(this);
}
#endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
"Attempted to dereference a non-dereferenceable iterator");
return *__i_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
"Attempted to dereference a non-dereferenceable iterator");
return _VSTD::__to_address(__i_);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator++() _NOEXCEPT
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
"Attempted to increment a non-incrementable iterator");
++__i_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator++(int) _NOEXCEPT
{__wrap_iter __tmp(*this); ++(*this); return __tmp;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator--() _NOEXCEPT
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this),
"Attempted to decrement a non-decrementable iterator");
--__i_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator--(int) _NOEXCEPT
{__wrap_iter __tmp(*this); --(*this); return __tmp;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator+ (difference_type __n) const _NOEXCEPT
{__wrap_iter __w(*this); __w += __n; return __w;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__addable(this, __n),
"Attempted to add/subtract an iterator outside its valid range");
__i_ += __n;
return *this;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator- (difference_type __n) const _NOEXCEPT
{return *this + (-__n);}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
{*this += -__n; return *this;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__subscriptable(this, __n),
"Attempted to subscript an iterator outside its valid range");
return __i_[__n];
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator_type base() const _NOEXCEPT {return __i_;}
private:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
explicit __wrap_iter(const void* __p, iterator_type __x) _NOEXCEPT : __i_(__x)
{
(void)__p;
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (!__libcpp_is_constant_evaluated())
__get_db()->__insert_ic(this, __p);
#endif
}
template <class _Up> friend class __wrap_iter;
template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span;
};
template <class _Iter1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
{
return __x.base() == __y.base();
}
template <class _Iter1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
{
return __x.base() == __y.base();
}
template <class _Iter1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)),
"Attempted to compare incomparable iterators");
return __x.base() < __y.base();
}
template <class _Iter1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
"Attempted to compare incomparable iterators");
return __x.base() < __y.base();
}
template <class _Iter1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
{
return !(__x == __y);
}
template <class _Iter1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
{
return !(__x == __y);
}
template <class _Iter1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
{
return __y < __x;
}
template <class _Iter1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
{
return __y < __x;
}
template <class _Iter1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
{
return !(__x < __y);
}
template <class _Iter1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
{
return !(__x < __y);
}
template <class _Iter1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
{
return !(__y < __x);
}
template <class _Iter1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
{
return !(__y < __x);
}
template <class _Iter1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
#ifndef _LIBCPP_CXX03_LANG
auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
-> decltype(__x.base() - __y.base())
#else
typename __wrap_iter<_Iter1>::difference_type
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
#endif // C++03
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)),
"Attempted to subtract incompatible iterators");
return __x.base() - __y.base();
}
template <class _Iter1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
__wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT
{
__x += __n;
return __x;
}
#if _LIBCPP_STD_VER <= 17
template <class _It>
struct __libcpp_is_contiguous_iterator<__wrap_iter<_It> > : true_type {};
#endif
template <class _It>
struct _LIBCPP_TEMPLATE_VIS pointer_traits<__wrap_iter<_It> >
{
typedef __wrap_iter<_It> pointer;
typedef typename pointer_traits<_It>::element_type element_type;
typedef typename pointer_traits<_It>::difference_type difference_type;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
static element_type *to_address(pointer __w) _NOEXCEPT {
return _VSTD::__to_address(__w.base());
}
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_WRAP_ITER_H