41 changes: 41 additions & 0 deletions libcxx/include/__iterator/indirectly_swappable.h
Original file line number Diff line number Diff line change
@@ -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_INDIRECTLY_SWAPPABLE_H
#define _LIBCPP___ITERATOR_INDIRECTLY_SWAPPABLE_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 > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_RANGES)

// [alg.req.ind.swap]

template<class _It1, class _It2 = _It1>
concept indirectly_swappable =
indirectly_readable<_It1> && indirectly_readable<_It2> &&
requires (const _It1 __it1, const _It2 __it2) {
ranges::iter_swap(__it1, __it1);
ranges::iter_swap(__it2, __it2);
ranges::iter_swap(__it1, __it2);
ranges::iter_swap(__it2, __it1);
};

#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_RANGES)

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___ITERATOR_INDIRECTLY_SWAPPABLE_H
13 changes: 2 additions & 11 deletions libcxx/include/__iterator/iter_swap.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
#define _LIBCPP___ITERATOR_ITER_SWAP_H

#include <__config>
#include <__concepts/swappable.h>
#include <__iterator/concepts.h>
#include <__iterator/indirectly_movable.h>
#include <__iterator/iter_move.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
#include <__ranges/access.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <concepts>
#include <type_traits>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Expand Down Expand Up @@ -87,16 +88,6 @@ inline 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 // !defined(_LIBCPP_HAS_NO_RANGES)

_LIBCPP_END_NAMESPACE_STD
Expand Down
8 changes: 7 additions & 1 deletion libcxx/include/__iterator/iterator_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@
#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 <__iterator/incrementable_traits.h>
#include <__iterator/readable_traits.h>
#include <concepts>
#include <type_traits>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Expand Down
72 changes: 72 additions & 0 deletions libcxx/include/__iterator/ranges_distance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// -*- 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_RANGES_DISTANCE_H
#define _LIBCPP___ITERATOR_RANGES_DISTANCE_H

#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/size.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

#if !defined(_LIBCPP_HAS_NO_RANGES)

// [range.iter.op.distance]

namespace ranges {

namespace __distance {

struct __fn {
template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
requires (!sized_sentinel_for<_Sent, _It>)
constexpr iter_difference_t<_It> operator()(_It __first, _Sent __last) const {
iter_difference_t<_It> __count = 0;
while (__first != __last) {
++__first;
++__count;
}
return __count;
}

template<input_or_output_iterator _It, sized_sentinel_for<_It> _Sent>
constexpr iter_difference_t<_It> operator()(_It __first, _Sent __last) const {
return __last - __first;
}

template<range _Rp>
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 (*this)(ranges::begin(__r), ranges::end(__r));
}
}
};

} // namespace __distance

inline namespace __cpo {
inline constexpr auto distance = __distance::__fn{};
} // namespace __cpo

} // namespace ranges

#endif // !defined(_LIBCPP_HAS_NO_RANGES)

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___ITERATOR_RANGES_DISTANCE_H
4 changes: 3 additions & 1 deletion libcxx/include/__ranges/counted.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges::views {

namespace __counted {

template<class _From, class _To>
concept __explicitly_convertible = requires {
_To(_From{});
Expand Down Expand Up @@ -79,7 +80,8 @@ namespace __counted {
return ranges::subrange(counted_iterator(_VSTD::forward<_Iter>(__it), __c), default_sentinel);
}
};
}

} // namespace __counted

inline namespace __cpo {
inline constexpr auto counted = __counted::__fn{};
Expand Down
151 changes: 151 additions & 0 deletions libcxx/include/__ranges/drop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// -*- 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___RANGES_DROP_H
#define _LIBCPP___RANGES_DROP_H

#include <__algorithm/min.h>
#include <__concepts/constructible.h>
#include <__config>
#include <__functional/bind_back.h>
#include <__iterator/ranges_distance.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/drop_view.h>
#include <__ranges/empty_view.h>
#include <__ranges/iota_view.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/size.h>
#include <__ranges/subrange.h>
#include <__utility/forward.h>
#include <__utility/priority_tag.h>
#include <concepts>
#include <span>
#include <string_view>
#include <type_traits>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

#if !defined(_LIBCPP_HAS_NO_RANGES)

namespace ranges::views {

namespace __drop {

template<class> struct __is_iota_view : false_type {};
template<class _Start, class _Bound> struct __is_iota_view<iota_view<_Start, _Bound>> : true_type {};

template<class> struct __is_string_view : false_type {};
template<class _CharT, class _Traits> struct __is_string_view<basic_string_view<_CharT, _Traits>> : true_type {};

template<class> struct __is_subrange : false_type {};
template<class _Ip, class _Sp, ranges::subrange_kind _Kp> struct __is_subrange<subrange<_Ip, _Sp, _Kp>> : true_type {};

template<class> struct __is_subrange_without_storesize : false_type {};
template<class _Ip, class _Sp> struct __is_subrange<subrange<_Ip, _Sp, subrange_kind::unsized>> : bool_constant<!sized_sentinel_for<_Sp, _Ip>> {};

struct __fn : __range_adaptor_closure<__fn> {

template<class _Result, class _It, class _Dp, class _Sent>
requires __is_subrange_without_storesize<_Result>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __make_result(_It __first, _Dp __n, type_identity_t<_Dp> __count, _Sent __last)
noexcept(noexcept(_Result(__first + _VSTD::min(__n, __count), __last, _VSTD::__to_unsigned_like(__n - std::min(__n, __count)))))
-> decltype( _Result(__first + _VSTD::min(__n, __count), __last, _VSTD::__to_unsigned_like(__n - std::min(__n, __count))))
{ return _Result(__first + _VSTD::min(__n, __count), __last, _VSTD::__to_unsigned_like(__n - std::min(__n, __count))); }

template<class _Result, class _It, class _Dp, class _Sent>
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __make_result(_It __first, _Dp __n, type_identity_t<_Dp> __count, _Sent __last)
noexcept(noexcept(_Result(__first + _VSTD::min(__n, __count), __last)))
-> decltype( _Result(__first + _VSTD::min(__n, __count), __last))
{ return _Result(__first + _VSTD::min(__n, __count), __last); }

template<class _Rp, class _Count>
requires __is_empty_view<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr decay_t<_Rp> __go(_Rp&& __r, _Count&&) noexcept {
return _VSTD::forward<_Rp>(__r);
}

template<class _Rp, class _Count>
requires random_access_range<_Rp> && sized_range<_Rp> && __is_std_span<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(__make_result<span<typename decay_t<_Rp>::element_type>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r))))
-> decltype( __make_result<span<typename decay_t<_Rp>::element_type>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r)))
{ return __make_result<span<typename decay_t<_Rp>::element_type>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r)); }

template<class _Rp, class _Count>
requires random_access_range<_Rp> && sized_range<_Rp> && __is_string_view<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(__make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r))))
-> decltype( __make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r)))
{ return __make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r)); }

template<class _Rp, class _Count>
requires random_access_range<_Rp> && sized_range<_Rp> && __is_iota_view<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(__make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r))))
-> decltype( __make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r)))
{ return __make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r)); }

template<class _Rp, class _Count>
requires random_access_range<_Rp> && sized_range<_Rp> && __is_subrange<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(__make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r))))
-> decltype( __make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r)))
{ return __make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count, ranges::end(__r)); }

template<class _Rp, class _Count>
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(ranges::drop_view(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count))))
-> decltype( ranges::drop_view(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count)))
{ return ranges::drop_view(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count)); }

template<class _Rp, convertible_to<range_difference_t<_Rp&&>> _Count>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Rp&& __r, _Count&& __count) const
noexcept(noexcept(__go(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count))))
-> decltype( __go(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count)))
{ return __go(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count)); }

template<class _Count>
requires constructible_from<decay_t<_Count>, _Count>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Count&& __count) const
noexcept(is_nothrow_constructible_v<decay_t<_Count>, _Count>)
{ return __range_adaptor_closure_t(_VSTD::__bind_back(*this, _VSTD::forward<_Count>(__count))); }
};

} // namespace __drop

inline namespace __cpo {
inline constexpr auto drop = __drop::__fn{};
} // namespace __cpo

} // namespace ranges::views

#endif // !defined(_LIBCPP_HAS_NO_RANGES)

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___RANGES_DROP_H
4 changes: 4 additions & 0 deletions libcxx/include/__ranges/empty_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; }
_LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; }
};

template<class> struct __is_empty_view : false_type {};
template<class _Tp> struct __is_empty_view<empty_view<_Tp>> : true_type {};

} // namespace ranges

#endif // !defined(_LIBCPP_HAS_NO_RANGES)
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__ranges/join_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/indirectly_swappable.h>
#include <__iterator/iterator_traits.h>
#include <__ranges/access.h>
#include <__ranges/all.h>
Expand Down
147 changes: 147 additions & 0 deletions libcxx/include/__ranges/take.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// -*- 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___RANGES_TAKE_H
#define _LIBCPP___RANGES_TAKE_H

#include <__algorithm/min.h>
#include <__concepts/constructible.h>
#include <__config>
#include <__functional/bind_back.h>
#include <__iterator/ranges_distance.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/empty_view.h>
#include <__ranges/iota_view.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/size.h>
#include <__ranges/subrange.h>
#include <__ranges/take_view.h>
#include <__utility/forward.h>
#include <__utility/priority_tag.h>
#include <concepts>
#include <span>
#include <string_view>
#include <type_traits>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

#if !defined(_LIBCPP_HAS_NO_RANGES)

namespace ranges::views {

namespace __take {

template<class> struct __is_iota_view : false_type {};
template<class _Start, class _Bound> struct __is_iota_view<iota_view<_Start, _Bound>> : true_type {};

template<class> struct __is_string_view : false_type {};
template<class _CharT, class _Traits> struct __is_string_view<basic_string_view<_CharT, _Traits>> : true_type {};

template<class> struct __is_subrange : false_type {};
template<class _Ip, class _Sp, ranges::subrange_kind _Kp> struct __is_subrange<subrange<_Ip, _Sp, _Kp>> : true_type {};

struct __fn : __range_adaptor_closure<__fn> {

template<class _It, class _Dp>
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __make_iota_view(_It __first, _Dp __n, type_identity_t<_Dp> __count)
noexcept(noexcept(ranges::iota_view(*__first, *(__first + _VSTD::min(__n, __count)))))
-> decltype( ranges::iota_view(*__first, *(__first + _VSTD::min(__n, __count))))
{ return ranges::iota_view(*__first, *(__first + _VSTD::min(__n, __count))); }

template<class _Result, class _It, class _Dp>
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __make_result(_It __first, _Dp __n, type_identity_t<_Dp> __count)
noexcept(noexcept(_Result(__first, __first + _VSTD::min(__n, __count))))
-> decltype( _Result(__first, __first + _VSTD::min(__n, __count)))
{ return _Result(__first, __first + _VSTD::min(__n, __count)); }

template<class _Rp, class _Count>
requires __is_empty_view<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr decay_t<_Rp> __go(_Rp&& __r, _Count&&) noexcept {
return _VSTD::forward<_Rp>(__r);
}

template<class _Rp, class _Count>
requires random_access_range<_Rp> && sized_range<_Rp> && __is_std_span<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(__make_result<span<typename decay_t<_Rp>::element_type>>(ranges::begin(__r), ranges::distance(__r), __count)))
-> decltype( __make_result<span<typename decay_t<_Rp>::element_type>>(ranges::begin(__r), ranges::distance(__r), __count))
{ return __make_result<span<typename decay_t<_Rp>::element_type>>(ranges::begin(__r), ranges::distance(__r), __count); }

template<class _Rp, class _Count>
requires random_access_range<_Rp> && sized_range<_Rp> && __is_string_view<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(__make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count)))
-> decltype( __make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count))
{ return __make_result<decay_t<_Rp>>(ranges::begin(__r), ranges::distance(__r), __count); }

template<class _Rp, class _Count>
requires random_access_range<_Rp> && sized_range<_Rp> && __is_subrange<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(__make_result<subrange<iterator_t<decay_t<_Rp>>>>(ranges::begin(__r), ranges::distance(__r), __count)))
-> decltype( __make_result<subrange<iterator_t<decay_t<_Rp>>>>(ranges::begin(__r), ranges::distance(__r), __count))
{ return __make_result<subrange<iterator_t<decay_t<_Rp>>>>(ranges::begin(__r), ranges::distance(__r), __count); }

template<class _Rp, class _Count>
requires random_access_range<_Rp> && sized_range<_Rp> && __is_iota_view<decay_t<_Rp>>::value
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(__make_iota_view(ranges::begin(__r), ranges::distance(__r), __count)))
-> decltype( __make_iota_view(ranges::begin(__r), ranges::distance(__r), __count))
{ return __make_iota_view(ranges::begin(__r), ranges::distance(__r), __count); }

template<class _Rp, class _Count>
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_Rp&& __r, _Count&& __count)
noexcept(noexcept(ranges::take_view(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count))))
-> decltype( ranges::take_view(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count)))
{ return ranges::take_view(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count)); }

template<class _Rp, convertible_to<range_difference_t<_Rp&&>> _Count>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Rp&& __r, _Count&& __count) const
noexcept(noexcept(__go(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count))))
-> decltype( __go(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count)))
{ return __go(_VSTD::forward<_Rp>(__r), _VSTD::forward<_Count>(__count)); }

template<class _Count>
requires constructible_from<decay_t<_Count>, _Count>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Count&& __count) const
noexcept(is_nothrow_constructible_v<decay_t<_Count>, _Count>)
{ return __range_adaptor_closure_t(_VSTD::__bind_back(*this, _VSTD::forward<_Count>(__count))); }
};

} // namespace __take

inline namespace __cpo {
inline constexpr auto take = __take::__fn{};
} // namespace __cpo

} // namespace ranges::views

#endif // !defined(_LIBCPP_HAS_NO_RANGES)

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___RANGES_TAKE_H
1 change: 1 addition & 0 deletions libcxx/include/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ template <class BidirectionalIterator, class Compare>
#include <__algorithm/pop_heap.h>
#include <__algorithm/prev_permutation.h>
#include <__algorithm/push_heap.h>
#include <__algorithm/ranges_equal.h>
#include <__algorithm/remove.h>
#include <__algorithm/remove_copy.h>
#include <__algorithm/remove_copy_if.h>
Expand Down
5 changes: 5 additions & 0 deletions libcxx/include/iterator
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <__functional_base>
#include <__iterator/access.h>
#include <__iterator/advance.h>
#include <__iterator/algorithm_concepts.h>
#include <__iterator/back_insert_iterator.h>
#include <__iterator/common_iterator.h>
#include <__iterator/concepts.h>
Expand All @@ -593,6 +594,9 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <__iterator/erase_if_container.h>
#include <__iterator/front_insert_iterator.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/indirectly_copyable.h>
#include <__iterator/indirectly_movable.h>
#include <__iterator/indirectly_swappable.h>
#include <__iterator/insert_iterator.h>
#include <__iterator/istreambuf_iterator.h>
#include <__iterator/istream_iterator.h>
Expand All @@ -606,6 +610,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <__iterator/ostream_iterator.h>
#include <__iterator/prev.h>
#include <__iterator/projected.h>
#include <__iterator/ranges_distance.h>
#include <__iterator/readable_traits.h>
#include <__iterator/reverse_access.h>
#include <__iterator/reverse_iterator.h>
Expand Down
8 changes: 8 additions & 0 deletions libcxx/include/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ module std [system] {
module pop_heap { private header "__algorithm/pop_heap.h" }
module prev_permutation { private header "__algorithm/prev_permutation.h" }
module push_heap { private header "__algorithm/push_heap.h" }
module ranges_equal { private header "__algorithm/ranges_equal.h" }
module remove { private header "__algorithm/remove.h" }
module remove_copy { private header "__algorithm/remove_copy.h" }
module remove_copy_if { private header "__algorithm/remove_copy_if.h" }
Expand Down Expand Up @@ -564,6 +565,7 @@ module std [system] {
private header "__iterator/advance.h"
export __function_like
}
module algorithm_concepts { private header "__iterator/algorithm_concepts.h" }
module back_insert_iterator { private header "__iterator/back_insert_iterator.h" }
module common_iterator { private header "__iterator/common_iterator.h" }
module concepts { private header "__iterator/concepts.h" }
Expand All @@ -575,6 +577,9 @@ module std [system] {
module erase_if_container { private header "__iterator/erase_if_container.h" }
module front_insert_iterator { private header "__iterator/front_insert_iterator.h" }
module incrementable_traits { private header "__iterator/incrementable_traits.h" }
module indirectly_copyable { private header "__iterator/indirectly_copyable.h" }
module indirectly_movable { private header "__iterator/indirectly_movable.h" }
module indirectly_swappable { private header "__iterator/indirectly_swappable.h" }
module insert_iterator { private header "__iterator/insert_iterator.h" }
module istream_iterator { private header "__iterator/istream_iterator.h" }
module istreambuf_iterator { private header "__iterator/istreambuf_iterator.h" }
Expand All @@ -594,6 +599,7 @@ module std [system] {
export __function_like
}
module projected { private header "__iterator/projected.h" }
module ranges_distance { private header "__iterator/ranges_distance.h" }
module readable_traits { private header "__iterator/readable_traits.h" }
module reverse_access { private header "__iterator/reverse_access.h" }
module reverse_iterator { private header "__iterator/reverse_iterator.h" }
Expand Down Expand Up @@ -757,6 +763,7 @@ module std [system] {
module counted { private header "__ranges/counted.h" }
module dangling { private header "__ranges/dangling.h" }
module data { private header "__ranges/data.h" }
module drop { private header "__ranges/drop.h" }
module drop_view { private header "__ranges/drop_view.h" }
module empty { private header "__ranges/empty.h" }
module empty_view { private header "__ranges/empty_view.h" }
Expand All @@ -771,6 +778,7 @@ module std [system] {
module size { private header "__ranges/size.h" }
module single_view { private header "__ranges/single_view.h" }
module subrange { private header "__ranges/subrange.h" }
module take { private header "__ranges/take.h" }
module take_view { private header "__ranges/take_view.h" }
module transform_view {
private header "__ranges/transform_view.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ namespace std::ranges {
#include <__ranges/counted.h>
#include <__ranges/dangling.h>
#include <__ranges/data.h>
#include <__ranges/drop.h>
#include <__ranges/drop_view.h>
#include <__ranges/empty_view.h>
#include <__ranges/empty.h>
Expand All @@ -218,6 +219,7 @@ namespace std::ranges {
#include <__ranges/single_view.h>
#include <__ranges/size.h>
#include <__ranges/subrange.h>
#include <__ranges/take.h>
#include <__ranges/take_view.h>
#include <__ranges/transform_view.h>
#include <__ranges/view_interface.h>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// REQUIRES: modules-build

// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.

// expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_equal.h'}}
#include <__algorithm/ranges_equal.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// REQUIRES: modules-build

// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.

// expected-error@*:* {{use of private header from outside its module: '__iterator/algorithm_concepts.h'}}
#include <__iterator/algorithm_concepts.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// REQUIRES: modules-build

// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.

// expected-error@*:* {{use of private header from outside its module: '__iterator/indirectly_copyable.h'}}
#include <__iterator/indirectly_copyable.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// REQUIRES: modules-build

// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.

// expected-error@*:* {{use of private header from outside its module: '__iterator/indirectly_movable.h'}}
#include <__iterator/indirectly_movable.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// REQUIRES: modules-build

// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.

// expected-error@*:* {{use of private header from outside its module: '__iterator/indirectly_swappable.h'}}
#include <__iterator/indirectly_swappable.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// REQUIRES: modules-build

// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.

// expected-error@*:* {{use of private header from outside its module: '__iterator/ranges_distance.h'}}
#include <__iterator/ranges_distance.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// REQUIRES: modules-build

// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.

// expected-error@*:* {{use of private header from outside its module: '__ranges/drop.h'}}
#include <__ranges/drop.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// REQUIRES: modules-build

// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.

// expected-error@*:* {{use of private header from outside its module: '__ranges/take.h'}}
#include <__ranges/take.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts

// template<class In, class Out>
// concept indirectly_movable;

#include <iterator>

#include "test_macros.h"
#include "MoveOnly.h"

struct IndirectlyMovableFromIntPtr {
struct AssignableFromIntRvalue {
AssignableFromIntRvalue& operator=(int&&);
};
AssignableFromIntRvalue& operator*() const;
};

struct IndirectlyCopyableFromLvaluesOnly {
struct AssignableFromIntLvalue {
AssignableFromIntLvalue& operator=(int&);
};
AssignableFromIntLvalue& operator*() const;
};
static_assert(!std::indirectly_movable<int*, IndirectlyCopyableFromLvaluesOnly>);

struct IndirectlyCopyableFromIntPtr {
struct AssignableFromInt {
AssignableFromInt& operator=(int);
};
AssignableFromInt& operator*() const;
};

static_assert( std::indirectly_copyable<int*, int*>);
static_assert( std::indirectly_copyable<const int*, int*>);
static_assert(!std::indirectly_copyable<int*, const int*>);
static_assert(!std::indirectly_copyable<const int*, const int*>);
static_assert(!std::indirectly_copyable<MoveOnly*, MoveOnly*>);
static_assert(!std::indirectly_copyable<const MoveOnly*, MoveOnly*>);
static_assert(!std::indirectly_copyable<int*, IndirectlyMovableFromIntPtr>);
static_assert( std::indirectly_copyable<int*, IndirectlyCopyableFromLvaluesOnly>);
static_assert( std::indirectly_copyable<int*, IndirectlyCopyableFromIntPtr>);
static_assert( std::indirectly_copyable<const int*, IndirectlyCopyableFromIntPtr>);
static_assert(!std::indirectly_copyable<IndirectlyCopyableFromIntPtr, int*>);
static_assert(!std::indirectly_copyable<IndirectlyCopyableFromIntPtr, const int*>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts

// template<class In, class Out>
// concept indirectly_copyable;

#include <iterator>

template<std::indirectly_readable I, class O>
constexpr bool indirectly_copyable_subsumption() {
return false;
}

template<class I, std::indirectly_writable<std::iter_reference_t<I>> O>
constexpr bool indirectly_copyable_subsumption() {
return false;
}

template<class I, class O>
requires std::indirectly_copyable<I, O>
constexpr bool indirectly_copyable_subsumption() {
return true;
}

static_assert(indirectly_copyable_subsumption<int*, int*>());
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,24 @@
#include <iterator>

#include "test_macros.h"
#include "MoveOnly.h"

struct IndirectlyMovableWithInt {
int& operator*() const;
};

struct Empty {};

struct MoveOnly {
MoveOnly(MoveOnly&&) = default;
MoveOnly(MoveOnly const&) = delete;
MoveOnly& operator=(MoveOnly&&) = default;
MoveOnly& operator=(MoveOnly const&) = delete;
MoveOnly() = default;
};

template<class T>
struct PointerTo {
using value_type = T;
T& operator*() const;
struct IndirectlyMovableFromIntPtr {
struct AssignableFromIntRvalue {
AssignableFromIntRvalue& operator=(int&&);
};
AssignableFromIntRvalue& operator*() const;
};

static_assert( std::indirectly_movable<int*, int*>);
static_assert( std::indirectly_movable<const int*, int *>);
static_assert(!std::indirectly_movable<int*, const int *>);
static_assert(!std::indirectly_movable<const int*, const int *>);
static_assert( std::indirectly_movable<int*, int[2]>);
static_assert(!std::indirectly_movable<int[2], int*>);
static_assert(!std::indirectly_movable<int[2], int[2]>);
static_assert(!std::indirectly_movable<int(&)[2], int(&)[2]>);
static_assert(!std::indirectly_movable<int, int*>);
static_assert(!std::indirectly_movable<int, int>);
static_assert( std::indirectly_movable<Empty*, Empty*>);
static_assert( std::indirectly_movable<int*, IndirectlyMovableWithInt>);
static_assert(!std::indirectly_movable<Empty*, IndirectlyMovableWithInt>);
static_assert( std::indirectly_movable<int*, IndirectlyMovableWithInt>);
static_assert( std::indirectly_movable<const int*, int*>);
static_assert(!std::indirectly_movable<int*, const int*>);
static_assert(!std::indirectly_movable<const int*, const int*>);
static_assert( std::indirectly_movable<MoveOnly*, MoveOnly*>);
static_assert(!std::indirectly_movable<const MoveOnly*, MoveOnly*>);
static_assert(!std::indirectly_movable<MoveOnly*, const MoveOnly*>);
static_assert(!std::indirectly_movable<const MoveOnly*, const MoveOnly*>);
static_assert(!std::indirectly_movable<const MoveOnly*, MoveOnly*>);
static_assert( std::indirectly_movable<PointerTo<MoveOnly>, PointerTo<MoveOnly>>);
static_assert( std::indirectly_movable<MoveOnly*, PointerTo<MoveOnly>>);
static_assert( std::indirectly_movable<int*, IndirectlyMovableFromIntPtr>);
static_assert(!std::indirectly_movable<const int*, IndirectlyMovableFromIntPtr>);
static_assert(!std::indirectly_movable<IndirectlyMovableFromIntPtr, int*>);
static_assert(!std::indirectly_movable<IndirectlyMovableFromIntPtr, const int*>);