- Implement https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2474r2.html
- Implement LWG3875(https://cplusplus.github.io/LWG/issue3875).
Depends on D151629
Reviewed By: #libc, Mordante, philnik, var-const
Differential Revision: https://reviews.llvm.org/D141699
--------------------------------------------------- -----------------
``__cpp_lib_ranges_join_with`` *unimplemented*
--------------------------------------------------- -----------------
+ ``__cpp_lib_ranges_repeat`` ``202207L``
+ --------------------------------------------------- -----------------
``__cpp_lib_ranges_slide`` *unimplemented*
--------------------------------------------------- -----------------
``__cpp_lib_ranges_starts_ends_with`` *unimplemented*
- P2494R2 - Relaxing range adaptors to allow for move only types
- P2585R0 - Improving default container formatting
- P0408R7 - Efficient Access to ``basic_stringbuf``'s Buffer
-
+- P2474R2 - ``views::repeat``
Improvements and New Features
-----------------------------
"`3870 <https://wg21.link/LWG3870>`__","Remove ``voidify``","February 2023","","",""
"`3871 <https://wg21.link/LWG3871>`__","Adjust note about ``terminate``","February 2023","","",""
"`3872 <https://wg21.link/LWG3872>`__","``basic_const_iterator`` should have custom ``iter_move``","February 2023","","",""
-"`3875 <https://wg21.link/LWG3875>`__","``std::ranges::repeat_view<T, IntegerClass>::iterator`` may be ill-formed","February 2023","","","|ranges|"
+"`3875 <https://wg21.link/LWG3875>`__","``std::ranges::repeat_view<T, IntegerClass>::iterator`` may be ill-formed","February 2023","|Complete|","17.0","|ranges|"
"`3876 <https://wg21.link/LWG3876>`__","Default constructor of ``std::layout_XX::mapping`` misses precondition","February 2023","","",""
"`3877 <https://wg21.link/LWG3877>`__","Incorrect constraints on ``const``-qualified monadic overloads for ``std::expected``","February 2023","|Complete|","17.0",""
"`3878 <https://wg21.link/LWG3878>`__","import ``std;`` should guarantee initialization of standard iostreams objects","February 2023","","",""
"`P2460R2 <https://wg21.link/P2460R2>`__","LWG","Relax requirements on ``wchar_t`` to match existing practices","July 2022","",""
"`P2465R3 <https://wg21.link/P2465R3>`__","LWG","Standard Library Modules ``std`` and ``std.compat``","July 2022","",""
"`P2467R1 <https://wg21.link/P2467R1>`__","LWG","Support exclusive mode for ``fstreams``","July 2022","",""
-"`P2474R2 <https://wg21.link/P2474R2>`__","LWG","``views::repeat``","July 2022","","","|ranges|"
+"`P2474R2 <https://wg21.link/P2474R2>`__","LWG","``views::repeat``","July 2022","|Complete|","17.0","|ranges|"
"`P2494R2 <https://wg21.link/P2494R2>`__","LWG","Relaxing range adaptors to allow for move only types","July 2022","|Complete|","17.0","|ranges|"
"`P2499R0 <https://wg21.link/P2499R0>`__","LWG","``string_view`` range constructor should be ``explicit``","July 2022","|Complete|","16.0","|ranges|"
"`P2502R2 <https://wg21.link/P2502R2>`__","LWG","``std::generator``: Synchronous Coroutine Generator for Ranges","July 2022","","","|ranges|"
,,,,
,,,,
,,,,
-C++23,`repeat <https://wg21.link/P2474R2>`_,Unassigned,No patch yet,Not started
+C++23,`repeat <https://wg21.link/P2474R2>`_,Yrong,`D141699 <https://llvm.org/D141699>`_,✅
C++23,`cartesian_product <https://wg21.link/P2374R4>`_,Unassigned,No patch yet,Not started
C++23,`zip <https://wg21.link/P2321R2>`_,Hui Xie,`D122806 <https://llvm.org/D122806>`_,✅
C++23,`zip_transform <https://wg21.link/P2321R2>`_,Hui Xie,No patch yet,Not started
__ranges/rbegin.h
__ranges/ref_view.h
__ranges/rend.h
+ __ranges/repeat_view.h
__ranges/reverse_view.h
__ranges/single_view.h
__ranges/size.h
#include <__ranges/iota_view.h>
#include <__ranges/non_propagating_cache.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/repeat_view.h>
#include <__ranges/size.h>
#include <__ranges/subrange.h>
#include <__ranges/view_interface.h>
ranges::end(__rng),
std::__to_unsigned_like(__dist - __clamped)
);}
+// clang-format off
+#if _LIBCPP_STD_VER >= 23
+ // [range.drop.overview]: the `repeat_view` "_RawRange models sized_range" case.
+ template <class _Range,
+ convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>,
+ class _Dist = range_difference_t<_Range>>
+ requires (__is_repeat_specialization<_RawRange> && sized_range<_RawRange>)
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
+ noexcept(noexcept(views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))))
+ -> decltype( views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))
+ { return views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); }
+
+ // [range.drop.overview]: the `repeat_view` "otherwise" case.
+ template <class _Range,
+ convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>,
+ class _Dist = range_difference_t<_Range>>
+ requires (__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>)
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Np&&) const
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
+ -> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))
+ { return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); }
+#endif
+// clang-format on
// [range.drop.overview]: the "otherwise" case.
template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
// Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
// overloads.
requires (!(__is_empty_view<_RawRange> ||
+#if _LIBCPP_STD_VER >= 23
+ __is_repeat_specialization<_RawRange> ||
+#endif
(__is_subrange_specialization_with_store_size<_RawRange> &&
sized_range<_RawRange> &&
random_access_range<_RawRange>) ||
--- /dev/null
+// -*- 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_REPEAT_VIEW_H
+#define _LIBCPP___RANGES_REPEAT_VIEW_H
+
+#include <__concepts/constructible.h>
+#include <__concepts/same_as.h>
+#include <__concepts/semiregular.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/unreachable_sentinel.h>
+#include <__memory/addressof.h>
+#include <__ranges/iota_view.h>
+#include <__ranges/movable_box.h>
+#include <__ranges/view_interface.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_cv.h>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <__utility/piecewise_construct.h>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template <class _Tp>
+concept __integer_like_with_usable_difference_type =
+ __signed_integer_like<_Tp> || (__integer_like<_Tp> && weakly_incrementable<_Tp>);
+
+template <class _Tp>
+struct __repeat_view_iterator_difference {
+ using type = _IotaDiffT<_Tp>;
+};
+
+template <__signed_integer_like _Tp>
+struct __repeat_view_iterator_difference<_Tp> {
+ using type = _Tp;
+};
+
+template <class _Tp>
+using __repeat_view_iterator_difference_t = typename __repeat_view_iterator_difference<_Tp>::type;
+
+namespace views::__drop {
+struct __fn;
+} // namespace views::__drop
+
+namespace views::__take {
+struct __fn;
+} // namespace views::__take
+
+template <move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
+ requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
+ (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
+class repeat_view : public view_interface<repeat_view<_Tp, _Bound>> {
+ friend struct views::__take::__fn;
+ friend struct views::__drop::__fn;
+ class __iterator;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI repeat_view()
+ requires default_initializable<_Tp>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(const _Tp& __value, _Bound __bound_sentinel = _Bound())
+ requires copy_constructible<_Tp>
+ : __value_(in_place, __value), __bound_(__bound_sentinel) {
+ if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+ _LIBCPP_ASSERT(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(_Tp&& __value, _Bound __bound_sentinel = _Bound())
+ : __value_(in_place, std::move(__value)), __bound_(__bound_sentinel) {
+ if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+ _LIBCPP_ASSERT(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
+ }
+
+ template <class... _TpArgs, class... _BoundArgs>
+ requires(constructible_from<_Tp, _TpArgs...> && constructible_from<_Bound, _BoundArgs...>)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(
+ piecewise_construct_t, tuple<_TpArgs...> __value_args, tuple<_BoundArgs...> __bound_args = tuple<>{})
+ : __value_(in_place, std::make_from_tuple<_Tp>(std::move(__value_args))),
+ __bound_(std::make_from_tuple<_Bound>(std::move(__bound_args))) {
+ if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+ _LIBCPP_ASSERT(
+ __bound_ >= 0, "The behavior is undefined if Bound is not unreachable_sentinel_t and bound is negative");
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator(std::addressof(*__value_)); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
+ requires(!same_as<_Bound, unreachable_sentinel_t>)
+ {
+ return __iterator(std::addressof(*__value_), __bound_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr unreachable_sentinel_t end() const noexcept { return unreachable_sentinel; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ requires(!same_as<_Bound, unreachable_sentinel_t>)
+ {
+ return std::__to_unsigned_like(__bound_);
+ }
+
+private:
+ __movable_box<_Tp> __value_;
+ _LIBCPP_NO_UNIQUE_ADDRESS _Bound __bound_ = _Bound();
+};
+
+template <class _Tp, class _Bound>
+repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
+
+// [range.repeat.iterator]
+template <move_constructible _Tp, semiregular _Bound>
+ requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
+ (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
+class repeat_view<_Tp, _Bound>::__iterator {
+ friend class repeat_view;
+
+ using _IndexT = conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(const _Tp* __value, _IndexT __bound_sentinel = _IndexT())
+ : __value_(__value), __current_(__bound_sentinel) {}
+
+public:
+ using iterator_concept = random_access_iterator_tag;
+ using iterator_category = random_access_iterator_tag;
+ using value_type = _Tp;
+ using difference_type = __repeat_view_iterator_difference_t<_IndexT>;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const noexcept { return *__value_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
+ ++__current_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() {
+ if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+ _LIBCPP_ASSERT(__current_ > 0, "The value of bound must be greater than or equal to 0");
+ --__current_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) {
+ if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+ _LIBCPP_ASSERT(__current_ + __n >= 0, "The value of bound must be greater than or equal to 0");
+ __current_ += __n;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) {
+ if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+ _LIBCPP_ASSERT(__current_ - __n >= 0, "The value of bound must be greater than or equal to 0");
+ __current_ -= __n;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](difference_type __n) const noexcept { return *(*this + __n); }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
+ return __x.__current_ == __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) {
+ return __x.__current_ <=> __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n) {
+ __i += __n;
+ return __i;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i) {
+ __i += __n;
+ return __i;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n) {
+ __i -= __n;
+ return __i;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) {
+ return static_cast<difference_type>(__x.__current_) - static_cast<difference_type>(__y.__current_);
+ }
+
+private:
+ const _Tp* __value_ = nullptr;
+ _IndexT __current_ = _IndexT();
+};
+
+// clang-format off
+namespace views {
+namespace __repeat {
+struct __fn {
+ template <class _Tp>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __value) const
+ noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value))))
+ -> decltype( ranges::repeat_view(std::forward<_Tp>(__value)))
+ { return ranges::repeat_view(std::forward<_Tp>(__value)); }
+
+
+ template <class _Tp, class _Bound>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) const
+ noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel))))
+ -> decltype( ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)))
+ { return ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)); }
+};
+} // namespace __repeat
+// clang-format on
+
+inline namespace __cpo {
+inline constexpr auto repeat = __repeat::__fn{};
+} // namespace __cpo
+} // namespace views
+
+template <class _Tp>
+inline constexpr bool __is_repeat_specialization = false;
+
+template <class _Tp, class _Bound>
+inline constexpr bool __is_repeat_specialization<repeat_view<_Tp, _Bound>> = true;
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_REPEAT_VIEW_H
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/iota_view.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/repeat_view.h>
#include <__ranges/size.h>
#include <__ranges/subrange.h>
#include <__ranges/view_interface.h>
*ranges::begin(__rng),
*ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
); }
+// clang-format off
+#if _LIBCPP_STD_VER >= 23
+ // [range.take.overview]: the `repeat_view` "_RawRange models sized_range" case.
+ template <class _Range,
+ convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>,
+ class _Dist = range_difference_t<_Range>>
+ requires(__is_repeat_specialization<_RawRange> && sized_range<_RawRange>)
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
+ noexcept(noexcept(views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))))
+ -> decltype( views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))
+ { return views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); }
+
+ // [range.take.overview]: the `repeat_view` "otherwise" case.
+ template <class _Range,
+ convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>,
+ class _Dist = range_difference_t<_Range>>
+ requires(__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>)
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
+ noexcept(noexcept(views::repeat(*__range.__value_, static_cast<_Dist>(__n))))
+ -> decltype( views::repeat(*__range.__value_, static_cast<_Dist>(__n)))
+ { return views::repeat(*__range.__value_, static_cast<_Dist>(__n)); }
+#endif
+// clang-format on
// [range.take.overview]: the "otherwise" case.
template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
// Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
// overloads.
requires (!(__is_empty_view<_RawRange> ||
+#if _LIBCPP_STD_VER >= 23
+ __is_repeat_specialization<_RawRange> ||
+#endif
(__is_iota_specialization<_RawRange> &&
sized_range<_RawRange> &&
random_access_range<_RawRange>) ||
module rbegin { private header "__ranges/rbegin.h" }
module ref_view { private header "__ranges/ref_view.h" }
module rend { private header "__ranges/rend.h" }
+ module repeat_view { private header "__ranges/repeat_view.h" }
module reverse_view { private header "__ranges/reverse_view.h" }
module single_view { private header "__ranges/single_view.h" }
module size {
template<class W, class Bound>
inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true;
+ // [range.repeat], repeat view
+ template<class T>
+ concept integer-like-with-usable-difference-type = // exposition only
+ is-signed-integer-like<T> || (is-integer-like<T> && weakly_incrementable<T>);
+
+ template<move_constructible T, semiregular Bound = unreachable_sentinel_t>
+ requires (is_object_v<T> && same_as<T, remove_cv_t<T>> &&
+ (integer-like-with-usable-difference-type<Bound> ||
+ same_as<Bound, unreachable_sentinel_t>))
+ class repeat_view;
+
+ namespace views { inline constexpr unspecified repeat = unspecified; }
+
// [range.join], join view
template<input_range V>
requires view<V> && input_range<range_reference_t<V>>
#include <__ranges/rbegin.h>
#include <__ranges/ref_view.h>
#include <__ranges/rend.h>
+#include <__ranges/repeat_view.h>
#include <__ranges/reverse_view.h>
#include <__ranges/single_view.h>
#include <__ranges/size.h>
__cpp_lib_ranges_chunk_by 202202L <ranges>
__cpp_lib_ranges_iota 202202L <numeric>
__cpp_lib_ranges_join_with 202202L <ranges>
+__cpp_lib_ranges_repeat 202207L <ranges>
__cpp_lib_ranges_slide 202202L <ranges>
__cpp_lib_ranges_starts_ends_with 202106L <algorithm>
__cpp_lib_ranges_to_container 202202L <deque> <forward_list> <list>
// # define __cpp_lib_ranges_chunk_by 202202L
// # define __cpp_lib_ranges_iota 202202L
// # define __cpp_lib_ranges_join_with 202202L
+# define __cpp_lib_ranges_repeat 202207L
// # define __cpp_lib_ranges_slide 202202L
// # define __cpp_lib_ranges_starts_ends_with 202106L
// # define __cpp_lib_ranges_to_container 202202L
} // namespace views
// [range.repeat], repeat view
-#if 0
using std::ranges::repeat_view;
namespace views {
using std::ranges::views::repeat;
} // namespace views
-#endif
+
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
// [range.istream], istream view
using std::ranges::basic_istream_view;
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
+// REQUIRES: has-unix-headers
+// XFAIL: availability-verbose_abort-missing
+
+// template<class... TArgs, class... BoundArgs>
+// requires constructible_from<T, TArgs...> &&
+// constructible_from<Bound, BoundArgs...>
+// constexpr explicit repeat_view(piecewise_construct_t,
+// tuple<TArgs...> value_args, tuple<BoundArgs...> bound_args = tuple<>{});
+
+#include <ranges>
+#include <tuple>
+
+#include "check_assertion.h"
+
+// clang-format off
+int main(int, char**) {
+ using Repeat = std::ranges::repeat_view<int, int>;
+ TEST_LIBCPP_ASSERT_FAILURE(Repeat(std::piecewise_construct, std::tuple{1}, std::tuple{-1}), "The behavior is undefined if Bound is not unreachable_sentinel_t and bound is negative");
+
+ return 0;
+}
+// clang-format on
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
+// REQUIRES: has-unix-headers
+// XFAIL: availability-verbose_abort-missing
+
+// constexpr explicit repeat_view(W&& value, Bound bound = Bound());
+// constexpr explicit repeat_view(const W& value, Bound bound = Bound());
+
+#include <ranges>
+
+#include "check_assertion.h"
+
+// clang-format off
+int main(int, char**) {
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::repeat_view(0, -1), "The value of bound must be greater than or equal to 0");
+ const int val = 0;
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::repeat_view(val, -1), "The value of bound must be greater than or equal to 0");
+
+ return 0;
+}
+// clang-format on
__cpp_lib_ranges_chunk 202202L [C++23]
__cpp_lib_ranges_chunk_by 202202L [C++23]
__cpp_lib_ranges_join_with 202202L [C++23]
+ __cpp_lib_ranges_repeat 202207L [C++23]
__cpp_lib_ranges_slide 202202L [C++23]
__cpp_lib_ranges_zip 202110L [C++23]
*/
# error "__cpp_lib_ranges_join_with should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should not be defined before c++23"
# endif
# error "__cpp_lib_ranges_join_with should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should not be defined before c++23"
# endif
# error "__cpp_lib_ranges_join_with should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should not be defined before c++23"
# endif
# error "__cpp_lib_ranges_join_with should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should not be defined before c++23"
# endif
# endif
# endif
+# ifndef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should be defined in c++23"
+# endif
+# if __cpp_lib_ranges_repeat != 202207L
+# error "__cpp_lib_ranges_repeat should have the value 202207L in c++23"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should be defined in c++23"
# endif
# endif
+# ifndef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should be defined in c++26"
+# endif
+# if __cpp_lib_ranges_repeat != 202207L
+# error "__cpp_lib_ranges_repeat should have the value 202207L in c++26"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should be defined in c++26"
__cpp_lib_ranges_chunk_by 202202L [C++23]
__cpp_lib_ranges_iota 202202L [C++23]
__cpp_lib_ranges_join_with 202202L [C++23]
+ __cpp_lib_ranges_repeat 202207L [C++23]
__cpp_lib_ranges_slide 202202L [C++23]
__cpp_lib_ranges_starts_ends_with 202106L [C++23]
__cpp_lib_ranges_to_container 202202L [C++23]
# error "__cpp_lib_ranges_join_with should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should not be defined before c++23"
# endif
# error "__cpp_lib_ranges_join_with should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should not be defined before c++23"
# endif
# error "__cpp_lib_ranges_join_with should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should not be defined before c++23"
# endif
# error "__cpp_lib_ranges_join_with should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should not be defined before c++23"
# endif
# endif
# endif
+# ifndef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should be defined in c++23"
+# endif
+# if __cpp_lib_ranges_repeat != 202207L
+# error "__cpp_lib_ranges_repeat should have the value 202207L in c++23"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should be defined in c++23"
# endif
# endif
+# ifndef __cpp_lib_ranges_repeat
+# error "__cpp_lib_ranges_repeat should be defined in c++26"
+# endif
+# if __cpp_lib_ranges_repeat != 202207L
+# error "__cpp_lib_ranges_repeat should have the value 202207L in c++26"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_ranges_slide
# error "__cpp_lib_ranges_slide should be defined in c++26"
test_small_range(std::views::iota(1, 8));
}
+#if TEST_STD_VER >= 23
+ // `views::drop(repeat_view, n)` returns a `repeat_view` when `repeat_view` models `sized_range`.
+ {
+ auto repeat = std::ranges::repeat_view<int, int>(1, 8);
+ using Result = std::ranges::repeat_view<int, int>;
+ std::same_as<Result> decltype(auto) result = repeat | std::views::drop(3);
+ static_assert(std::ranges::sized_range<Result>);
+ assert(result.size() == 5);
+ assert(*result.begin() == 1);
+ }
+
+ // `views::drop(repeat_view, n)` returns a `repeat_view` when `repeat_view` doesn't model `sized_range`.
+ {
+ auto repeat = std::ranges::repeat_view<int>(1);
+ using Result = std::ranges::repeat_view<int, std::unreachable_sentinel_t>;
+ std::same_as<Result> decltype(auto) result = repeat | std::views::drop(3);
+ static_assert(!std::ranges::sized_range<Result>);
+ static_assert(std::same_as<std::unreachable_sentinel_t, decltype(result.end())>);
+ }
+#endif
+
// Test that it's possible to call `std::views::drop` with any single argument as long as the resulting closure is
// never invoked. There is no good use case for it, but it's valid.
{
assert(result.size() == 3);
}
+#if TEST_STD_VER >= 23
+ // `views::take(repeat_view, n)` returns a `repeat_view` when `repeat_view` models `sized_range`.
+ {
+ auto repeat = std::ranges::repeat_view<int, int>(1, 8);
+ using Result = std::ranges::repeat_view<int, int>;
+ std::same_as<Result> decltype(auto) result = repeat | std::views::take(3);
+ static_assert(std::ranges::sized_range<Result>);
+ assert(result.size() == 3);
+ assert(*result.begin() == 1);
+ }
+
+ // `views::take(repeat_view, n)` returns a `repeat_view` when `repeat_view` doesn't model `sized_range`.
+ {
+ auto repeat = std::ranges::repeat_view<int>(1);
+ using Result = std::ranges::repeat_view<int, std::ranges::range_difference_t<decltype(repeat)>>;
+ std::same_as<Result> decltype(auto) result = repeat | std::views::take(3);
+ assert(result.size() == 3);
+ assert(*result.begin() == 1);
+ }
+#endif
+
// When the size of the input range `s` is shorter than `n`, only `s` elements are taken.
{
test_small_range(std::span(buf));
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr iterator begin() const;
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+
+constexpr bool test() {
+ // Test unbound && non-const view
+ {
+ std::ranges::repeat_view<int> rv(0);
+ std::same_as<std::ranges::iterator_t<decltype(rv)>> decltype(auto) iter = rv.begin();
+ assert(*iter == 0);
+ }
+
+ // Test unbound && const view
+ {
+ const std::ranges::repeat_view<int> rv(0);
+ std::same_as<std::ranges::iterator_t<decltype(rv)>> decltype(auto) iter = rv.begin();
+ assert(*iter == 0);
+ }
+
+ // Test bound && non-const view
+ {
+ std::ranges::repeat_view<int, int> rv(1024, 10);
+ std::same_as<std::ranges::iterator_t<decltype(rv)>> decltype(auto) iter = rv.begin();
+ assert(*iter == 1024);
+ }
+
+ // Test bound && const view
+ {
+ const std::ranges::repeat_view<int, long long> rv(1024, 10);
+ std::same_as<std::ranges::iterator_t<decltype(rv)>> decltype(auto) iter = rv.begin();
+ assert(*iter == 1024);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// template<class T, class Bound>
+// repeat_view(T, Bound) -> repeat_view<T, Bound>;
+
+#include <concepts>
+#include <ranges>
+#include <utility>
+
+struct Empty {};
+
+// clang-format off
+static_assert(std::same_as<decltype(std::ranges::repeat_view(Empty())), std::ranges::repeat_view<Empty>>);
+static_assert(std::same_as<decltype(std::ranges::repeat_view(std::declval<Empty&>())), std::ranges::repeat_view<Empty>>);
+static_assert(std::same_as<decltype(std::ranges::repeat_view(std::declval<Empty&&>())), std::ranges::repeat_view<Empty>>);
+static_assert(std::same_as<decltype(std::ranges::repeat_view(10, 1)), std::ranges::repeat_view<int, int>>);
+static_assert(std::same_as<decltype(std::ranges::repeat_view(10, 1U)), std::ranges::repeat_view<int, unsigned>>);
+static_assert(std::same_as<decltype(std::ranges::repeat_view(10, 1UL)), std::ranges::repeat_view<int, unsigned long>>);
+// clang-format on
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// repeat_view() requires default_initializable<T> = default;
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+
+struct DefaultInt42 {
+ int value = 42;
+};
+
+struct Int {
+ Int(int) {}
+};
+
+static_assert(std::default_initializable<std::ranges::repeat_view<DefaultInt42>>);
+static_assert(!std::default_initializable<std::ranges::repeat_view<Int>>);
+
+constexpr bool test() {
+ std::ranges::repeat_view<DefaultInt42> rv;
+ assert((*rv.begin()).value == 42);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// template<class... TArgs, class... BoundArgs>
+// requires constructible_from<T, TArgs...> &&
+// constructible_from<Bound, BoundArgs...>
+// constexpr explicit repeat_view(piecewise_construct_t,
+// tuple<TArgs...> value_args, tuple<BoundArgs...> bound_args = tuple<>{});
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+#include <tuple>
+#include <utility>
+
+struct C {};
+
+struct B {
+ int v;
+};
+
+struct A {
+ int x = 111;
+ int y = 222;
+
+ constexpr A() = default;
+ constexpr A(B b) : x(b.v), y(b.v + 1) {}
+ constexpr A(int _x, int _y) : x(_x), y(_y) {}
+};
+
+static_assert(std::constructible_from<std::ranges::repeat_view<A, int>,
+ std::piecewise_construct_t,
+ std::tuple<int, int>,
+ std::tuple<int>>);
+static_assert(std::constructible_from<std::ranges::repeat_view<A, int>,
+ std::piecewise_construct_t,
+ std::tuple<B>,
+ std::tuple<int>>);
+static_assert(std::constructible_from<std::ranges::repeat_view<A, int>,
+ std::piecewise_construct_t,
+ std::tuple<>,
+ std::tuple<int>>);
+static_assert(std::constructible_from<std::ranges::repeat_view<A>,
+ std::piecewise_construct_t,
+ std::tuple<int, int>,
+ std::tuple<std::unreachable_sentinel_t>>);
+static_assert(std::constructible_from<std::ranges::repeat_view<A>,
+ std::piecewise_construct_t,
+ std::tuple<B>,
+ std::tuple<std::unreachable_sentinel_t>>);
+static_assert(std::constructible_from<std::ranges::repeat_view<A>,
+ std::piecewise_construct_t,
+ std::tuple<>,
+ std::tuple<std::unreachable_sentinel_t>>);
+static_assert(!std::constructible_from<std::ranges::repeat_view<A, int>,
+ std::piecewise_construct_t,
+ std::tuple<C>,
+ std::tuple<int>>);
+static_assert(!std::constructible_from<std::ranges::repeat_view<A>,
+ std::piecewise_construct_t,
+ std::tuple<C>,
+ std::tuple<std::unreachable_sentinel_t>>);
+static_assert(!std::constructible_from<std::ranges::repeat_view<A, int>,
+ std::piecewise_construct_t,
+ std::tuple<int, int, int>,
+ std::tuple<int>>);
+static_assert(!std::constructible_from<std::ranges::repeat_view<A>,
+ std::piecewise_construct_t,
+ std::tuple<int, int, int>,
+ std::tuple<std::unreachable_sentinel_t>>);
+static_assert(
+ !std::constructible_from<std::ranges::repeat_view<A>, std::piecewise_construct_t, std::tuple<B>, std::tuple<int>>);
+
+constexpr bool test() {
+ {
+ std::ranges::repeat_view<A, int> rv(std::piecewise_construct, std::tuple{}, std::tuple{3});
+ assert(rv.size() == 3);
+ assert(rv[0].x == 111);
+ assert(rv[0].y == 222);
+ assert(rv.begin() + 3 == rv.end());
+ }
+ {
+ std::ranges::repeat_view<A> rv(std::piecewise_construct, std::tuple{}, std::tuple{std::unreachable_sentinel});
+ assert(rv[0].x == 111);
+ assert(rv[0].y == 222);
+ assert(rv.begin() + 300 != rv.end());
+ }
+ {
+ std::ranges::repeat_view<A, int> rv(std::piecewise_construct, std::tuple{1, 2}, std::tuple{3});
+ assert(rv.size() == 3);
+ assert(rv[0].x == 1);
+ assert(rv[0].y == 2);
+ assert(rv.begin() + 3 == rv.end());
+ }
+ {
+ std::ranges::repeat_view<A> rv(std::piecewise_construct, std::tuple{1, 2}, std::tuple{std::unreachable_sentinel});
+ assert(rv[0].x == 1);
+ assert(rv[0].y == 2);
+ assert(rv.begin() + 300 != rv.end());
+ }
+ {
+ std::ranges::repeat_view<A, int> rv(std::piecewise_construct, std::tuple{B{11}}, std::tuple{3});
+ assert(rv.size() == 3);
+ assert(rv[0].x == 11);
+ assert(rv[0].y == 12);
+ assert(rv.begin() + 3 == rv.end());
+ }
+ {
+ std::ranges::repeat_view<A> rv(std::piecewise_construct, std::tuple{B{10}}, std::tuple{std::unreachable_sentinel});
+ assert(rv[0].x == 10);
+ assert(rv[0].y == 11);
+ assert(rv.begin() + 300 != rv.end());
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr explicit repeat_view(const T& value, Bound bound = Bound()) requires copy_constructible<T>;
+// constexpr explicit repeat_view(T&& value, Bound bound = Bound());
+
+#include <ranges>
+#include <cassert>
+#include <iterator>
+#include <type_traits>
+
+#include "MoveOnly.h"
+
+struct Empty {};
+
+// Test explicit
+static_assert(std::is_constructible_v<std::ranges::repeat_view<Empty>, const Empty&>);
+static_assert(std::is_constructible_v<std::ranges::repeat_view<Empty>, Empty&&>);
+static_assert(std::is_constructible_v<std::ranges::repeat_view<Empty, int>, const Empty&>);
+static_assert(std::is_constructible_v<std::ranges::repeat_view<Empty, int>, Empty&&>);
+
+static_assert(!std::is_convertible_v<const Empty&, std::ranges::repeat_view<Empty>>);
+static_assert(!std::is_convertible_v<Empty&&, std::ranges::repeat_view<Empty>>);
+static_assert(!std::is_convertible_v<const Empty&, std::ranges::repeat_view<Empty, int>>);
+static_assert(!std::is_convertible_v<Empty&&, std::ranges::repeat_view<Empty, int>>);
+
+static_assert(!std::is_constructible_v<std::ranges::repeat_view<MoveOnly>, const MoveOnly&>);
+static_assert(std::is_constructible_v<std::ranges::repeat_view<MoveOnly>, MoveOnly&&>);
+
+constexpr bool test() {
+ // Move && unbound && default argument
+ {
+ std::ranges::repeat_view<Empty> rv(Empty{});
+ assert(rv.begin() + 10 != rv.end());
+ }
+
+ // Move && unbound && user-provided argument
+ {
+ std::ranges::repeat_view<Empty> rv(Empty{}, std::unreachable_sentinel);
+ assert(rv.begin() + 10 != rv.end());
+ }
+
+ // Move && bound && default argument
+ {
+ std::ranges::repeat_view<Empty, int> rv(Empty{});
+ assert(rv.begin() == rv.end());
+ }
+
+ // Move && bound && user-provided argument
+ {
+ std::ranges::repeat_view<Empty, int> rv(Empty{}, 10);
+ assert(rv.begin() + 10 == rv.end());
+ }
+
+ // Copy && unbound && default argument
+ {
+ Empty e;
+ std::ranges::repeat_view<Empty> rv(e);
+ assert(rv.begin() + 10 != rv.end());
+ }
+
+ // Copy && unbound && user-provided argument
+ {
+ Empty e;
+ std::ranges::repeat_view<Empty> rv(e, std::unreachable_sentinel);
+ assert(rv.begin() + 10 != rv.end());
+ }
+
+ // Copy && bound && default argument
+ {
+ Empty e;
+ std::ranges::repeat_view<Empty, int> rv(e);
+ assert(rv.begin() == rv.end());
+ }
+
+ // Copy && bound && user-provided argument
+ {
+ Empty e;
+ std::ranges::repeat_view<Empty, int> rv(e, 10);
+ assert(rv.begin() + 10 == rv.end());
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr unreachable_sentinel_t end() const noexcept;
+// constexpr iterator end() const requires (!same_as<Bound, unreachable_sentinel_t>);
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+#include <iterator>
+
+constexpr bool test() {
+ // bound
+ {
+ std::ranges::repeat_view<int, int> rv(0, 10);
+ assert(rv.begin() + 10 == rv.end());
+ std::same_as<std::ranges::iterator_t<decltype(rv)>> decltype(auto) iter = rv.end();
+ static_assert(std::same_as<decltype(*iter), const int&>);
+ for (const auto& i : rv) {
+ assert(i == 0);
+ }
+ }
+
+ // unbound
+ {
+ std::ranges::repeat_view<int> rv(0);
+ assert(rv.begin() + 10 != rv.end());
+ static_assert(std::same_as<decltype(rv.end()), std::unreachable_sentinel_t>);
+ static_assert(noexcept(rv.end()));
+ for (const auto& i : rv | std::views::take(10)) {
+ assert(i == 0);
+ }
+ }
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// repeat_view::<iterator>::operator{==,<=>}
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+
+constexpr bool test() {
+ // Test unbound
+ {
+ using R = std::ranges::repeat_view<int>;
+ static_assert(std::three_way_comparable<std::ranges::iterator_t<R>>);
+
+ std::ranges::repeat_view<int> r(42);
+ auto iter1 = r.begin();
+ auto iter2 = iter1 + 1;
+
+ static_assert(std::same_as<decltype(iter1 == iter2), bool>);
+
+ assert(iter1 == iter1);
+ assert(!(iter1 == iter2));
+ assert(iter2 == iter2);
+
+ assert(!(iter1 < iter1));
+ assert(iter1 < iter2);
+ assert(!(iter2 < iter1));
+ assert(iter1 <= iter1);
+ assert(iter1 <= iter2);
+ assert(!(iter2 <= iter1));
+ assert(!(iter1 > iter1));
+ assert(!(iter1 > iter2));
+ assert(iter2 > iter1);
+ assert(iter1 >= iter1);
+ assert(!(iter1 >= iter2));
+ assert(iter2 >= iter1);
+ assert(iter1 == iter1);
+ assert(!(iter1 == iter2));
+ assert(iter2 == iter2);
+ assert(!(iter1 != iter1));
+ assert(iter1 != iter2);
+ assert(!(iter2 != iter2));
+
+ assert((iter1 <=> iter2) == std::strong_ordering::less);
+ assert((iter1 <=> iter1) == std::strong_ordering::equal);
+ assert((iter2 <=> iter1) == std::strong_ordering::greater);
+
+ static_assert(std::same_as<decltype(iter1 <=> iter2), std::strong_ordering>);
+ }
+
+ // Test bound
+ {
+ using R = std::ranges::repeat_view<int, int>;
+ static_assert(std::three_way_comparable<std::ranges::iterator_t<R>>);
+
+ std::ranges::repeat_view<int, int> r(42, 10);
+ auto iter1 = r.begin();
+ auto iter2 = iter1 + 1;
+
+ static_assert(std::same_as<decltype(iter1 == iter2), bool>);
+
+ assert(iter1 == iter1);
+ assert(!(iter1 == iter2));
+ assert(iter2 == iter2);
+
+ assert(!(iter1 < iter1));
+ assert(iter1 < iter2);
+ assert(!(iter2 < iter1));
+ assert(iter1 <= iter1);
+ assert(iter1 <= iter2);
+ assert(!(iter2 <= iter1));
+ assert(!(iter1 > iter1));
+ assert(!(iter1 > iter2));
+ assert(iter2 > iter1);
+ assert(iter1 >= iter1);
+ assert(!(iter1 >= iter2));
+ assert(iter2 >= iter1);
+ assert(iter1 == iter1);
+ assert(!(iter1 == iter2));
+ assert(iter2 == iter2);
+ assert(!(iter1 != iter1));
+ assert(iter1 != iter2);
+ assert(!(iter2 != iter2));
+
+ assert((iter1 <=> iter2) == std::strong_ordering::less);
+ assert((iter1 <=> iter1) == std::strong_ordering::equal);
+ assert((iter2 <=> iter1) == std::strong_ordering::greater);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// iterator() = default;
+
+#include <ranges>
+#include <type_traits>
+
+constexpr bool test() {
+ using Iter = std::ranges::iterator_t<std::ranges::repeat_view<int>>;
+ static_assert(std::is_default_constructible_v<Iter>);
+ [[maybe_unused]] Iter iter;
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr iterator& operator--();
+// constexpr iterator operator--(int);
+
+#include <ranges>
+#include <cassert>
+
+constexpr bool test() {
+ using Iter = std::ranges::iterator_t<std::ranges::repeat_view<int>>;
+ std::ranges::repeat_view<int> rv(10);
+ auto iter = rv.begin() + 10;
+
+ assert(iter-- == rv.begin() + 10);
+ assert(--iter == rv.begin() + 8);
+
+ static_assert(std::same_as<decltype(iter--), Iter>);
+ static_assert(std::same_as<decltype(--iter), Iter&>);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr iterator& operator++();
+// constexpr void operator++(int);
+
+#include <ranges>
+#include <concepts>
+#include <cassert>
+
+constexpr bool test() {
+ using Iter = std::ranges::iterator_t<std::ranges::repeat_view<int>>;
+ std::ranges::repeat_view<int> rv(10);
+ using Iter = std::ranges::iterator_t<std::ranges::repeat_view<int>>;
+ auto iter = rv.begin();
+
+ assert(iter++ == rv.begin());
+ assert(++iter == rv.begin() + 2);
+
+ static_assert(std::same_as<decltype(iter++), Iter>);
+ static_assert(std::same_as<decltype(++iter), Iter&>);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// Test iterator category and iterator concepts.
+
+// using index-type = conditional_t<same_as<Bound, unreachable_sentinel_t>, ptrdiff_t, Bound>;
+// using iterator_concept = random_access_iterator_tag;
+// using iterator_category = random_access_iterator_tag;
+// using value_type = T;
+// using difference_type = see below:
+// If is-signed-integer-like<index-type> is true, the member typedef-name difference_type denotes
+// index-type. Otherwise, it denotes IOTA-DIFF-T(index-type).
+
+#include <cassert>
+#include <concepts>
+#include <cstdint>
+#include <ranges>
+#include <type_traits>
+
+constexpr bool test() {
+ // unbound
+ {
+ using Iter = std::ranges::iterator_t<std::ranges::repeat_view<int>>;
+ static_assert(std::same_as<Iter::iterator_concept, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::iterator_category, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::value_type, int>);
+ static_assert(std::same_as<Iter::difference_type, ptrdiff_t>);
+ static_assert(std::is_signed_v<Iter::difference_type>);
+ }
+
+ // bound
+ {
+ {
+ using Iter = std::ranges::iterator_t<const std::ranges::repeat_view<int, std::int8_t>>;
+ static_assert(std::same_as<Iter::iterator_concept, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::iterator_category, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::value_type, int>);
+ static_assert(std::is_signed_v<Iter::difference_type>);
+ static_assert(sizeof(Iter::difference_type) == sizeof(std::int8_t));
+ }
+
+ {
+ using Iter = std::ranges::iterator_t<const std::ranges::repeat_view<int, std::uint8_t>>;
+ static_assert(std::same_as<Iter::iterator_concept, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::iterator_category, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::value_type, int>);
+ static_assert(std::is_signed_v<Iter::difference_type>);
+ static_assert(sizeof(Iter::difference_type) > sizeof(std::uint8_t));
+ }
+
+ {
+ using Iter = std::ranges::iterator_t<const std::ranges::repeat_view<int, std::int16_t>>;
+ static_assert(std::same_as<Iter::iterator_concept, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::iterator_category, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::value_type, int>);
+ static_assert(std::is_signed_v<Iter::difference_type>);
+ static_assert(sizeof(Iter::difference_type) == sizeof(std::int16_t));
+ }
+
+ {
+ using Iter = std::ranges::iterator_t<const std::ranges::repeat_view<int, std::uint16_t>>;
+ static_assert(std::same_as<Iter::iterator_concept, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::iterator_category, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::value_type, int>);
+ static_assert(std::is_signed_v<Iter::difference_type>);
+ static_assert(sizeof(Iter::difference_type) > sizeof(std::uint16_t));
+ }
+
+ {
+ using Iter = std::ranges::iterator_t<const std::ranges::repeat_view<int, std::int32_t>>;
+ static_assert(std::same_as<Iter::iterator_concept, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::iterator_category, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::value_type, int>);
+ static_assert(std::is_signed_v<Iter::difference_type>);
+ static_assert(sizeof(Iter::difference_type) == sizeof(std::int32_t));
+ }
+
+ {
+ using Iter = std::ranges::iterator_t<const std::ranges::repeat_view<int, std::uint32_t>>;
+ static_assert(std::same_as<Iter::iterator_concept, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::iterator_category, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::value_type, int>);
+ static_assert(std::is_signed_v<Iter::difference_type>);
+ static_assert(sizeof(Iter::difference_type) > sizeof(std::uint32_t));
+ }
+
+ {
+ using Iter = std::ranges::iterator_t<const std::ranges::repeat_view<int, std::int64_t>>;
+ static_assert(std::same_as<Iter::iterator_concept, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::iterator_category, std::random_access_iterator_tag>);
+ static_assert(std::same_as<Iter::value_type, int>);
+ static_assert(std::is_signed_v<Iter::difference_type>);
+ static_assert(sizeof(Iter::difference_type) == sizeof(std::int64_t));
+ }
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// friend constexpr iterator operator-(iterator i, difference_type n);
+// friend constexpr difference_type operator-(const iterator& x, const iterator& y);
+
+#include <ranges>
+#include <cassert>
+#include <cstdint>
+#include <concepts>
+
+constexpr bool test() {
+ // <iterator> - difference_type
+ {
+ using Iter = std::ranges::iterator_t<std::ranges::repeat_view<int>>;
+ std::ranges::repeat_view<int> v(0);
+ Iter iter = v.begin() + 10;
+ assert(iter - 5 == v.begin() + 5);
+ static_assert(std::same_as<decltype(iter - 5), Iter>);
+ }
+
+ // <iterator> - <iterator>
+ {
+ // unbound
+ {
+ std::ranges::repeat_view<int> v(0);
+ auto iter1 = v.begin() + 10;
+ auto iter2 = v.begin() + 5;
+ assert(iter1 - iter2 == 5);
+ static_assert(std::same_as<decltype(iter1 - iter2), ptrdiff_t>);
+ }
+
+ // bound && signed bound sentinel
+ {
+ std::ranges::repeat_view<int, int> v(0, 20);
+ auto iter1 = v.begin() + 10;
+ auto iter2 = v.begin() + 5;
+ assert(iter1 - iter2 == 5);
+ static_assert(std::same_as<decltype(iter1 - iter2), int>);
+ }
+
+ // bound && unsigned bound sentinel
+ {
+ std::ranges::repeat_view<int, unsigned> v(0, 20);
+ auto iter1 = v.begin() + 10;
+ auto iter2 = v.begin() + 5;
+ assert(iter1 - iter2 == 5);
+ static_assert(sizeof(decltype(iter1 - iter2)) > sizeof(unsigned));
+ }
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr iterator& operator-=(difference_type n);
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+
+constexpr bool test() {
+ using Iter = std::ranges::iterator_t<std::ranges::repeat_view<int>>;
+ std::ranges::repeat_view<int> v(10);
+ auto iter = v.begin() + 10;
+ iter -= 5;
+ assert(iter == v.begin() + 5);
+
+ static_assert(std::same_as<decltype(iter -= 5), Iter&>);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// friend constexpr iterator operator+(iterator i, difference_type n);
+// friend constexpr iterator operator+(difference_type n, iterator i);
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+
+constexpr bool test() {
+ std::ranges::repeat_view<int> v(10);
+ using Iter = std::ranges::iterator_t<std::ranges::repeat_view<int>>;
+ auto iter = v.begin();
+ assert(iter + 5 == v.begin() + 5);
+ assert(5 + iter == v.begin() + 5);
+ assert(2 + iter == v.begin() + 2);
+ assert(3 + iter == v.begin() + 3);
+
+ static_assert(std::same_as<decltype(iter + 5), Iter>);
+ static_assert(std::same_as<decltype(5 + iter), Iter>);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr iterator& operator+=(difference_type n);
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+
+constexpr bool test() {
+ std::ranges::repeat_view<int> v(10);
+ using Iter = std::ranges::iterator_t<std::ranges::repeat_view<int>>;
+ auto iter1 = v.begin() + 10;
+ auto iter2 = v.begin() + 10;
+ assert(iter1 == iter2);
+ iter1 += 5;
+ assert(iter1 != iter2);
+ assert(iter1 == iter2 + 5);
+
+ static_assert(std::same_as<decltype(iter2 += 5), Iter&>);
+ assert(std::addressof(iter2) == std::addressof(iter2 += 5));
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr const W & operator*() const noexcept;
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+
+constexpr bool test() {
+ // unbound
+ {
+ std::ranges::repeat_view<int> v(31);
+ auto iter = v.begin();
+
+ const int& val = *iter;
+ for (int i = 0; i < 100; ++i, ++iter) {
+ assert(*iter == 31);
+ assert(&*iter == &val);
+ }
+
+ static_assert(noexcept(*iter));
+ static_assert(std::same_as<decltype(*iter), const int&>);
+ }
+
+ // bound && one element
+ {
+ std::ranges::repeat_view<int, int> v(31, 1);
+ auto iter = v.begin();
+ assert(*iter == 31);
+ static_assert(noexcept(*iter));
+ static_assert(std::same_as<decltype(*iter), const int&>);
+ }
+
+ // bound && several elements
+ {
+ std::ranges::repeat_view<int, int> v(31, 100);
+ auto iter = v.begin();
+
+ const int& val = *iter;
+ for (int i = 0; i < 100; ++i, ++iter) {
+ assert(*iter == 31);
+ assert(&*iter == &val);
+ }
+ }
+
+ // bound && foreach
+ {
+ for (const auto& val : std::views::repeat(31, 100))
+ assert(val == 31);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr const W & operator[](difference_type n) const noexcept;
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+#include <algorithm>
+
+constexpr bool test() {
+ // unbound
+ {
+ std::ranges::repeat_view<int> v(31);
+ auto iter = v.begin();
+ assert(std::ranges::all_of(std::views::iota(0, 100), [&v](int i) { return v[i] == 31; }));
+
+ static_assert(noexcept(iter[0]));
+ static_assert(std::same_as<decltype(iter[0]), const int&>);
+ }
+
+ // bound
+ {
+ std::ranges::repeat_view<int, int> v(32);
+ auto iter = v.begin();
+ assert(std::ranges::all_of(v, [](int i) { return i == 32; }));
+ static_assert(noexcept(iter[0]));
+ static_assert(std::same_as<decltype(iter[0]), const int&>);
+ }
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// constexpr auto size() const requires (!same_as<Bound, unreachable_sentinel_t>);
+
+#include <ranges>
+#include <numeric>
+#include <concepts>
+#include <cassert>
+#include <iterator>
+
+template <class T>
+concept has_size = requires(T&& view) {
+ { std::forward<T>(view).size() };
+};
+
+static_assert(has_size<std::ranges::repeat_view<int, int>>);
+static_assert(!has_size<std::ranges::repeat_view<int>>);
+static_assert(!has_size<std::ranges::repeat_view<int, std::unreachable_sentinel_t>>);
+
+constexpr bool test() {
+ {
+ std::ranges::repeat_view<int, int> rv(10, 20);
+ assert(rv.size() == 20);
+ }
+
+ {
+ std::ranges::repeat_view<int, int> rv(10, std::numeric_limits<int>::max());
+ assert(rv.size() == std::numeric_limits<int>::max());
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// template <class T>
+// views::repeat(T &&) requires constructible_from<ranges::repeat_view<T>, T>;
+
+// templaye <class T, class Bound>
+// views::repeat(T &&, Bound &&) requires constructible_from<ranges::repeat_view<T, Bound>, T, Bound>;
+
+#include <cassert>
+#include <concepts>
+#include <ranges>
+#include <tuple>
+#include <type_traits>
+
+#include "MoveOnly.h"
+
+struct NonCopyable {
+ NonCopyable(NonCopyable&) = delete;
+};
+
+struct NonDefaultCtor {
+ NonDefaultCtor(int) {}
+};
+
+struct Empty {};
+
+struct LessThan3 {
+ constexpr bool operator()(int i) const { return i < 3; }
+};
+
+struct EqualTo33 {
+ constexpr bool operator()(int i) const { return i == 33; }
+};
+
+struct Add3 {
+ constexpr int operator()(int i) const { return i + 3; }
+};
+
+// Tp is_object
+static_assert(std::is_invocable_v<decltype(std::views::repeat), int>);
+static_assert(!std::is_invocable_v<decltype(std::views::repeat), void>);
+
+// _Bound is semiregular, integer like or std::unreachable_sentinel_t
+static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, Empty>);
+static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, NonCopyable>);
+static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, NonDefaultCtor>);
+static_assert(std::is_invocable_v<decltype(std::views::repeat), int, std::unreachable_sentinel_t>);
+
+// Tp is copy_constructible
+static_assert(!std::is_invocable_v<decltype(std::views::repeat), NonCopyable>);
+
+// Tp is move_constructible
+static_assert(std::is_invocable_v<decltype(std::views::repeat), MoveOnly>);
+
+constexpr bool test() {
+ assert(*std::views::repeat(33).begin() == 33);
+ assert(*std::views::repeat(33, 10).begin() == 33);
+ static_assert(std::same_as<decltype(std::views::repeat(42)), std::ranges::repeat_view<int>>);
+ static_assert(std::same_as<decltype(std::views::repeat(42, 3)), std::ranges::repeat_view<int, int>>);
+ static_assert(std::same_as<decltype(std::views::repeat), decltype(std::ranges::views::repeat)>);
+
+ // unbound && drop_view
+ {
+ auto r = std::views::repeat(33) | std::views::drop(3);
+ static_assert(!std::ranges::sized_range<decltype(r)>);
+ assert(*r.begin() == 33);
+ }
+
+ // bound && drop_view
+ {
+ auto r = std::views::repeat(33, 8) | std::views::drop(3);
+ static_assert(std::ranges::sized_range<decltype(r)>);
+ assert(*r.begin() == 33);
+ assert(r.size() == 5);
+ }
+
+ // unbound && take_view
+ {
+ auto r = std::views::repeat(33) | std::views::take(3);
+ static_assert(std::ranges::sized_range<decltype(r)>);
+ assert(*r.begin() == 33);
+ assert(r.size() == 3);
+ }
+
+ // bound && take_view
+ {
+ auto r = std::views::repeat(33, 8) | std::views::take(3);
+ static_assert(std::ranges::sized_range<decltype(r)>);
+ assert(*r.begin() == 33);
+ assert(r.size() == 3);
+ }
+
+ // bound && transform_view
+ {
+ auto r = std::views::repeat(33, 8) | std::views::transform(Add3{});
+ assert(*r.begin() == 36);
+ assert(r.size() == 8);
+ }
+
+ // unbound && transform_view
+ {
+ auto r = std::views::repeat(33) | std::views::transform(Add3{});
+ assert(*r.begin() == 36);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
"unimplemented": True,
},
{
+ "name": "__cpp_lib_ranges_repeat",
+ "values": { "c++23": 202207},
+ "headers": ["ranges"],
+ },
+ {
"name": "__cpp_lib_ranges_slide",
"values": {"c++23": 202202},
"headers": ["ranges"],