diff --git a/libcxx/docs/ReleaseNotes/24.rst b/libcxx/docs/ReleaseNotes/24.rst index d71a24c66b0c4..6c0b837074ea2 100644 --- a/libcxx/docs/ReleaseNotes/24.rst +++ b/libcxx/docs/ReleaseNotes/24.rst @@ -39,6 +39,7 @@ Implemented Papers ------------------ - P0493R5: Atomic minimum/maximum (`Github `__) +- P3059R2: Making user-defined constructors of view iterators/sentinels private (`Github `__) - P0792R14: ``function_ref`` : a type-erased callable reference (`Github `__) - P3948R1: ``constant_wrapper`` is the only tool needed for passing constant expressions via function arguments (`Github `__) - P3961R1: Less double indirection in ``function_ref`` (RU-220) (`Github `__) diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv index 855ac2533a282..1832ec915a06a 100644 --- a/libcxx/docs/Status/Cxx26Papers.csv +++ b/libcxx/docs/Status/Cxx26Papers.csv @@ -188,7 +188,7 @@ "`P4140R0 `__","Proposed resolution for US70-126: allow incomplete types in type_order","2026-03 (Croydon)","","","`#189595 `__","" "`P3373R4 `__","Of Operation States and Their Lifetimes","2026-03 (Croydon)","","","`#189597 `__","" "`P3986R1 `__","A Wording Strategy for Inlinable Receivers","2026-03 (Croydon)","","","`#189598 `__","" -"`P3059R2 `__","Making user-defined constructors of view iterators/sentinels private","2026-03 (Croydon)","","","`#189599 `__","" +"`P3059R2 `__","Making user-defined constructors of view iterators/sentinels private","2026-03 (Croydon)","|Complete|","24","`#189599 `__","" "`P3725R3 `__","Filter View Extensions for Safer Use, Rev 3","2026-03 (Croydon)","","","`#189601 `__","" "`P3828R1 `__","Rename the to_input view to as_input","2026-03 (Croydon)","","","`#189602 `__","" "`P3795R2 `__","Miscellaneous Reflection Cleanup","2026-03 (Croydon)","","","`#189603 `__","" diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h index 33c152bbd03b4..706744ae652e1 100644 --- a/libcxx/include/__ranges/elements_view.h +++ b/libcxx/include/__ranges/elements_view.h @@ -165,6 +165,8 @@ template template class elements_view<_View, _Np>::__iterator : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> { + friend class elements_view<_View, _Np>; + template friend class __iterator; @@ -175,6 +177,8 @@ class elements_view<_View, _Np>::__iterator iterator_t<_Base> __current_ = iterator_t<_Base>(); + _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {} + _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_element(const iterator_t<_Base>& __i) { if constexpr (is_reference_v>) { return std::get<_Np>(*__i); @@ -205,8 +209,6 @@ class elements_view<_View, _Np>::__iterator requires default_initializable> = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {} - _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator __i) requires _Const && convertible_to, iterator_t<_Base>> : __current_(std::move(__i.__current_)) {} @@ -339,6 +341,10 @@ class elements_view<_View, _Np>::__sentinel { using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} + + friend class elements_view<_View, _Np>; + template friend class __sentinel; @@ -350,8 +356,6 @@ class elements_view<_View, _Np>::__sentinel { public: _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} - _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel __other) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__other.__end_)) {} diff --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h index 7ec53dac4a84f..3004e830173f1 100644 --- a/libcxx/include/__ranges/filter_view.h +++ b/libcxx/include/__ranges/filter_view.h @@ -127,10 +127,16 @@ struct __filter_iterator_category<_View> { template > _Pred> requires view<_View> && is_object_v<_Pred> class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> { -public: +private: _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>(); _LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr; + _LIBCPP_HIDE_FROM_ABI constexpr __iterator(filter_view& __parent, iterator_t<_View> __current) + : __current_(std::move(__current)), __parent_(std::addressof(__parent)) {} + + friend class filter_view<_View, _Pred>; + +public: using iterator_concept = _If, bidirectional_iterator_tag, @@ -145,9 +151,6 @@ class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category< requires default_initializable> = default; - _LIBCPP_HIDE_FROM_ABI constexpr __iterator(filter_view& __parent, iterator_t<_View> __current) - : __current_(std::move(__current)), __parent_(std::addressof(__parent)) {} - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> const& base() const& noexcept { return __current_; } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() && { return std::move(__current_); } @@ -211,13 +214,16 @@ class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category< template > _Pred> requires view<_View> && is_object_v<_Pred> class filter_view<_View, _Pred>::__sentinel { -public: +private: sentinel_t<_View> __end_ = sentinel_t<_View>(); - _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(filter_view& __parent) : __end_(ranges::end(__parent.__base_)) {} + friend class filter_view<_View, _Pred>; + +public: + _LIBCPP_HIDE_FROM_ABI __sentinel() = default; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_View> base() const { return __end_; } _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) { diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h index 38e0ccaf2849e..9d87138d29e23 100644 --- a/libcxx/include/__ranges/iota_view.h +++ b/libcxx/include/__ranges/iota_view.h @@ -110,6 +110,12 @@ template && copyable<_Start> class iota_view : public view_interface> { struct __iterator : public __iota_iterator_category<_Start> { + private: + _Start __value_ = _Start(); + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {} + + public: friend class iota_view; using iterator_concept = @@ -124,14 +130,10 @@ class iota_view : public view_interface> { using value_type = _Start; using difference_type = _IotaDiffT<_Start>; - _Start __value_ = _Start(); - _LIBCPP_HIDE_FROM_ABI __iterator() requires default_initializable<_Start> = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {} - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) { return __value_; @@ -282,11 +284,12 @@ class iota_view : public view_interface> { private: _BoundSentinel __bound_sentinel_ = _BoundSentinel(); - public: - _LIBCPP_HIDE_FROM_ABI __sentinel() = default; _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {} + public: + _LIBCPP_HIDE_FROM_ABI __sentinel() = default; + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) { return __x.__value_ == __y.__bound_sentinel_; } diff --git a/libcxx/include/__ranges/istream_view.h b/libcxx/include/__ranges/istream_view.h index 7c64463108e1a..1bee6e69f2186 100644 --- a/libcxx/include/__ranges/istream_view.h +++ b/libcxx/include/__ranges/istream_view.h @@ -66,9 +66,6 @@ class basic_istream_view<_Val, _CharT, _Traits>::__iterator { using difference_type = ptrdiff_t; using value_type = _Val; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept - : __parent_(std::addressof(__parent)) {} - __iterator(const __iterator&) = delete; _LIBCPP_HIDE_FROM_ABI __iterator(__iterator&&) = default; @@ -91,9 +88,14 @@ class basic_istream_view<_Val, _CharT, _Traits>::__iterator { private: basic_istream_view<_Val, _CharT, _Traits>* __parent_; + _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept + : __parent_(std::addressof(__parent)) {} + _LIBCPP_HIDE_FROM_ABI constexpr basic_istream<_CharT, _Traits>* __get_parent_stream() const { return __parent_->__stream_; } + + friend class basic_istream_view<_Val, _CharT, _Traits>; }; template diff --git a/libcxx/include/__ranges/join_view.h b/libcxx/include/__ranges/join_view.h index f80b75c839d4a..4f3f8d1c1e5b4 100644 --- a/libcxx/include/__ranges/join_view.h +++ b/libcxx/include/__ranges/join_view.h @@ -160,11 +160,13 @@ struct join_view<_View>::__sentinel { using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; sentinel_t<_Base> __end_ = sentinel_t<_Base>(); + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_Parent& __parent) : __end_(ranges::end(__parent.__base_)) {} + + friend class join_view<_View>; + public: _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_Parent& __parent) : __end_(ranges::end(__parent.__base_)) {} - _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel __s) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__s.__end_)) {} diff --git a/libcxx/include/__ranges/lazy_split_view.h b/libcxx/include/__ranges/lazy_split_view.h index be2b86772fa0d..9c44d26faf1e7 100644 --- a/libcxx/include/__ranges/lazy_split_view.h +++ b/libcxx/include/__ranges/lazy_split_view.h @@ -143,6 +143,8 @@ class lazy_split_view : public view_interface> template struct __outer_iterator : __outer_iterator_category<__maybe_const<_Const, _View>> { private: + friend class lazy_split_view<_View, _Pattern>; + template friend struct __inner_iterator; friend __outer_iterator; @@ -155,6 +157,14 @@ class lazy_split_view : public view_interface> _LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent(); bool __trailing_empty_ = false; + _LIBCPP_HIDE_FROM_ABI constexpr explicit __outer_iterator(_Parent& __parent) + requires(!forward_range<_Base>) + : __parent_(std::addressof(__parent)) {} + + _LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator(_Parent& __parent, iterator_t<_Base> __current) + requires forward_range<_Base> + : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {} + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto& __current() noexcept { if constexpr (forward_range<_View>) { return __current_; @@ -196,14 +206,6 @@ class lazy_split_view : public view_interface> _LIBCPP_HIDE_FROM_ABI __outer_iterator() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __outer_iterator(_Parent& __parent) - requires(!forward_range<_Base>) - : __parent_(std::addressof(__parent)) {} - - _LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator(_Parent& __parent, iterator_t<_Base> __current) - requires forward_range<_Base> - : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {} - _LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator(__outer_iterator __i) requires _Const && convertible_to, iterator_t<_Base>> : __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {} @@ -286,12 +288,16 @@ class lazy_split_view : public view_interface> template struct __inner_iterator : __inner_iterator_category<__maybe_const<_Const, _View>> { private: + friend class lazy_split_view<_View, _Pattern>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; // Workaround for a GCC issue. static constexpr bool _OuterConst = _Const; __outer_iterator<_Const> __i_ = __outer_iterator<_OuterConst>(); bool __incremented_ = false; + _LIBCPP_HIDE_FROM_ABI constexpr explicit __inner_iterator(__outer_iterator<_Const> __i) : __i_(std::move(__i)) {} + // Note: these private functions are necessary because GCC doesn't allow calls to private members of `__i_` from // free functions that are friends of `inner-iterator`. @@ -342,8 +348,6 @@ class lazy_split_view : public view_interface> _LIBCPP_HIDE_FROM_ABI __inner_iterator() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __inner_iterator(__outer_iterator<_Const> __i) : __i_(std::move(__i)) {} - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __i_.__current(); } diff --git a/libcxx/include/__ranges/split_view.h b/libcxx/include/__ranges/split_view.h index 10148e0e64764..7295e33a282f0 100644 --- a/libcxx/include/__ranges/split_view.h +++ b/libcxx/include/__ranges/split_view.h @@ -127,6 +127,12 @@ struct split_view<_View, _Pattern>::__iterator { _LIBCPP_NO_UNIQUE_ADDRESS subrange> __next_ = subrange>(); bool __trailing_empty_ = false; + _LIBCPP_HIDE_FROM_ABI constexpr __iterator( + split_view<_View, _Pattern>& __parent, iterator_t<_View> __current, subrange> __next) + : __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {} + + friend class split_view<_View, _Pattern>; + friend struct __sentinel; public: @@ -137,10 +143,6 @@ struct split_view<_View, _Pattern>::__iterator { _LIBCPP_HIDE_FROM_ABI __iterator() = default; - _LIBCPP_HIDE_FROM_ABI constexpr __iterator( - split_view<_View, _Pattern>& __parent, iterator_t<_View> __current, subrange> __next) - : __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {} - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() const { return __cur_; } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { return {__cur_, __next_.begin()}; } @@ -179,16 +181,18 @@ struct split_view<_View, _Pattern>::__sentinel { private: _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_View> __end_ = sentinel_t<_View>(); + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(split_view<_View, _Pattern>& __parent) + : __end_(ranges::end(__parent.__base_)) {} + _LIBCPP_HIDE_FROM_ABI static constexpr bool __equals(const __iterator& __x, const __sentinel& __y) { return __x.__cur_ == __y.__end_ && !__x.__trailing_empty_; } + friend class split_view<_View, _Pattern>; + public: _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(split_view<_View, _Pattern>& __parent) - : __end_(ranges::end(__parent.__base_)) {} - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) { return __equals(__x, __y); } diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h index 999f686537f2c..ee62d49f71d8b 100644 --- a/libcxx/include/__ranges/take_view.h +++ b/libcxx/include/__ranges/take_view.h @@ -165,14 +165,16 @@ class take_view<_View>::__sentinel { using _Iter _LIBCPP_NODEBUG = counted_iterator>>; _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} + + friend class take_view<_View>; + template friend class take_view<_View>::__sentinel; public: _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} - _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel __s) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__s.__end_)) {} diff --git a/libcxx/include/__ranges/take_while_view.h b/libcxx/include/__ranges/take_while_view.h index 0aee306807c8b..e77b79665d1f6 100644 --- a/libcxx/include/__ranges/take_while_view.h +++ b/libcxx/include/__ranges/take_while_view.h @@ -108,14 +108,16 @@ class take_while_view<_View, _Pred>::__sentinel { sentinel_t<_Base> __end_ = sentinel_t<_Base>(); const _Pred* __pred_ = nullptr; + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end, const _Pred* __pred) + : __end_(std::move(__end)), __pred_(__pred) {} + + friend class take_while_view<_View, _Pred>; + friend class __sentinel; public: _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end, const _Pred* __pred) - : __end_(std::move(__end)), __pred_(__pred) {} - _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel __s) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__s.__end_)), __pred_(__s.__pred_) {} diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h index 06ace86bbfafa..807f1cf19a0ac 100644 --- a/libcxx/include/__ranges/transform_view.h +++ b/libcxx/include/__ranges/transform_view.h @@ -192,6 +192,11 @@ class transform_view<_View, _Fn>::__iterator _Parent* __parent_ = nullptr; + _LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current) + : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {} + + friend class transform_view<_View, _Fn>; + template friend class transform_view<_View, _Fn>::__iterator; @@ -209,9 +214,6 @@ class transform_view<_View, _Fn>::__iterator requires default_initializable> = default; - _LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current) - : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {} - // Note: `__i` should always be `__iterator`, but directly using // `__iterator` is ill-formed when `_Const` is false // (see http://wg21.link/class.copy.ctor#5). @@ -354,6 +356,10 @@ class transform_view<_View, _Fn>::__sentinel { sentinel_t<_Base> __end_ = sentinel_t<_Base>(); + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {} + + friend class transform_view<_View, _Fn>; + template friend class transform_view<_View, _Fn>::__iterator; @@ -363,8 +369,6 @@ class transform_view<_View, _Fn>::__sentinel { public: _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {} - // Note: `__i` should always be `__sentinel`, but directly using // `__sentinel` is ill-formed when `_Const` is false // (see http://wg21.link/class.copy.ctor#5). diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp index a77e98f845a06..f6514d6fe696b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp @@ -37,17 +37,19 @@ LIBCPP_STATIC_ASSERT(!IsBaseNoexcept); constexpr bool test() { std::tuple t{5}; + std::ranges::elements_view ev{BaseView{&t, &t + 1}}; + // const & { - const ElementsIter it{&t}; - decltype(auto) base = it.base(); + const ElementsIter it = ev.begin(); + decltype(auto) base = it.base(); static_assert(std::is_same_v* const&>); assert(base == &t); } // & { - ElementsIter it{&t}; + ElementsIter it = ev.begin(); decltype(auto) base = it.base(); static_assert(std::is_same_v* const&>); assert(base == &t); @@ -55,7 +57,7 @@ constexpr bool test() { // && { - ElementsIter it{&t}; + ElementsIter it = ev.begin(); decltype(auto) base = std::move(it).base(); static_assert(std::is_same_v*>); assert(base == &t); @@ -63,8 +65,8 @@ constexpr bool test() { // const && { - const ElementsIter it{&t}; - decltype(auto) base = std::move(it).base(); + const ElementsIter it = ev.begin(); + decltype(auto) base = std::move(it).base(); static_assert(std::is_same_v* const&>); assert(base == &t); } @@ -78,10 +80,10 @@ constexpr bool test() { constexpr bool operator==(const MoveOnlyIter&) const { return true; } }; - using MoveOnlyElemIter = - std::ranges::iterator_t, 0>>; + std::ranges::elements_view, 0> mev{ + std::ranges::subrange{MoveOnlyIter{{}, MoveOnly{5}}, Sent{}}}; + auto it = mev.begin(); - MoveOnlyElemIter it{MoveOnlyIter{{}, MoveOnly{5}}}; decltype(auto) base = std::move(it).base(); static_assert(std::is_same_v); assert(base.mo.get() == 5); diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.compile.pass.cpp new file mode 100644 index 0000000000000..b43a60276e280 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.compile.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr explicit iterator(iterator_t current); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include +#include +#include + +using BaseIter = std::tuple*; +using ElementsIter = std::ranges::iterator_t, 0>>; + +static_assert(!std::is_constructible_v); +static_assert(!std::is_convertible_v); diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.pass.cpp deleted file mode 100644 index 5a280d294aecc..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.pass.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// constexpr explicit iterator(iterator_t current); - -#include -#include -#include - -#include "../types.h" - -// Test explicit -using BaseIter = std::tuple*; -using ElementsIter = std::ranges::iterator_t, 0>>; - -static_assert(std::is_constructible_v); -static_assert(!std::is_convertible_v); - -struct TracedMoveIter : IterBase{ - bool moved = false; - - constexpr TracedMoveIter() = default; - constexpr TracedMoveIter(const TracedMoveIter&) = default; - constexpr TracedMoveIter(TracedMoveIter&&) : moved{true} {} - constexpr TracedMoveIter& operator=(TracedMoveIter&&) = default; - constexpr TracedMoveIter& operator=(const TracedMoveIter&) = default; -}; - -struct TracedMoveView : std::ranges::view_base { - TracedMoveIter begin() const; - TracedMoveIter end() const; -}; - -constexpr bool test() { - using Iter = std::ranges::iterator_t>; - Iter iter{TracedMoveIter{}}; - assert(iter.base().moved); - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp index 4c94cd5edf62e..df0d63ed38c96 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp @@ -57,8 +57,16 @@ static_assert(!std::is_constructible_v, ElemIt static_assert(!std::is_constructible_v, ConstElemIter>); constexpr bool test() { - ElemIter iter{ConvertibleIter{5}}; - ConstElemIter constIter = iter; // implicit + struct TestRange : std::ranges::view_base { + constexpr auto begin() { return ConvertibleIter{5}; } + constexpr auto end() { return ConvertibleIter{5}; } + constexpr auto begin() const { return ConvertibleIter{5}; } + constexpr auto end() const { return ConvertibleIter{5}; } + }; + + std::ranges::elements_view ev{TestRange{}}; + ElemIter iter = ev.begin(); + ConstElemIter constIter = iter; // implicit assert(constIter.base().movedFromOtherConst); assert(constIter.base().i == 5); diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp index d4d0156fdb5be..114b7fc1f1b71 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp @@ -17,7 +17,7 @@ #include struct Sent { - int i; + int i = 5; friend constexpr bool operator==(std::tuple*, const Sent&) { return true; } }; @@ -27,7 +27,8 @@ constexpr bool test() { using EleRange = std::ranges::elements_view; using EleSent = std::ranges::sentinel_t; - const EleSent st{Sent{5}}; + const EleRange ev; + const EleSent st = ev.end(); std::same_as decltype(auto) base = st.base(); assert(base.i == 5); diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.compile.pass.cpp similarity index 54% rename from libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.pass.cpp rename to libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.compile.pass.cpp index 13fef1d53f121..bbdc797b03e9c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.compile.pass.cpp @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++20 // constexpr explicit sentinel(sentinel_t end); -#include +// The constructor is now `private` (exposition-only) per P3059R2. + #include -#include -#include +#include struct Sent { int i; @@ -26,27 +26,7 @@ struct Range : std::ranges::view_base { Sent end(); }; -// Test explicit - -static_assert(std::is_constructible_v>, Sent>); -static_assert(!std::is_convertible_v>>); - -constexpr bool test() { - // base is init correctly - { - using R = std::ranges::elements_view; - using Sentinel = std::ranges::sentinel_t; - - Sentinel s1(Sent{5}); - assert(s1.base().i == 5); - } - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); +using ElementsView = std::ranges::elements_view; - return 0; -} +static_assert(!std::is_constructible_v, Sent>); +static_assert(!std::is_convertible_v>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp index a8bc817ced291..25d1413b2fa16 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp @@ -67,12 +67,19 @@ static_assert( constexpr bool test() { // base is init correctly { - using R = std::ranges::elements_view; + struct TestRange : std::ranges::view_base { + constexpr std::tuple* begin() const { return nullptr; } + constexpr Sent end() { return Sent{5}; } + constexpr ConstSent end() const { return ConstSent{5}; } + }; + + using R = std::ranges::elements_view; using Sentinel = std::ranges::sentinel_t; using ConstSentinel = std::ranges::sentinel_t; static_assert(!std::same_as); - Sentinel s1(Sent{5}); + R r{TestRange{}}; + Sentinel s1 = r.end(); ConstSentinel s2 = s1; assert(s2.base().i == 5); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp index 8a12b1694ca2f..284a22d218bf0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp @@ -87,7 +87,9 @@ constexpr void test() { for (std::ptrdiff_t n = 0; n != 5; ++n) { FilterView view = make_filter_view(array.data(), array.data() + array.size(), AlwaysTrue{}); - FilterIterator const iter(view, Iter(array.data() + n)); + FilterIterator iter = view.begin(); + for (std::ptrdiff_t i = 0; i < n; ++i) + ++iter; std::same_as decltype(auto) result = iter.operator->(); assert(base(result) == array.data() + n); assert(iter->x == n); diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/base.pass.cpp index 813cd892c64e6..9f193ddbc1a2d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/base.pass.cpp @@ -37,7 +37,7 @@ constexpr void test() { // Test the const& version { - FilterIterator const iter(view, Iter(array.data())); + FilterIterator const iter = view.begin(); Iter const& result = iter.base(); ASSERT_SAME_TYPE(Iter const&, decltype(iter.base())); ASSERT_NOEXCEPT(iter.base()); @@ -46,7 +46,7 @@ constexpr void test() { // Test the && version { - FilterIterator iter(view, Iter(array.data())); + FilterIterator iter = view.begin(); Iter result = std::move(iter).base(); ASSERT_SAME_TYPE(Iter, decltype(std::move(iter).base())); assert(base(result) == array.data()); diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp new file mode 100644 index 0000000000000..47deabb7136c6 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr std::ranges::filter_view::(filter_view&, iterator_t); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include + +#include "test_iterators.h" +#include "../types.h" + +using View = minimal_view>; +using ViewIter = std::ranges::iterator_t; +using FilterView = std::ranges::filter_view; +using FilterIterator = std::ranges::iterator_t; + +static_assert(!std::constructible_from); diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent_iter.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent_iter.pass.cpp deleted file mode 100644 index 761ef2d8ee493..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent_iter.pass.cpp +++ /dev/null @@ -1,51 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// constexpr std::ranges::filter_view::(filter_view&, iterator_t); - -#include - -#include -#include -#include -#include "test_iterators.h" -#include "../types.h" - -template > -constexpr void test() { - using View = minimal_view; - using FilterView = std::ranges::filter_view; - using FilterIterator = std::ranges::iterator_t; - - std::array array{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - View view(Iter(array.data()), Sent(Iter(array.data() + array.size()))); - Iter iter = view.begin(); - - FilterView filter_view(std::move(view), AlwaysTrue{}); - FilterIterator filter_iter(filter_view, std::move(iter)); - assert(base(filter_iter.base()) == array.data()); -} - -constexpr bool tests() { - test>(); - test>(); - test>(); - test>(); - test>(); - test>(); - test(); - return true; -} - -int main(int, char**) { - tests(); - static_assert(tests()); - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp index f4f4982bb9d5d..42b0f1816d8a1 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp @@ -36,7 +36,9 @@ constexpr void test() { FilterView view = make_filter_view(array.data(), array.data() + array.size(), AlwaysTrue{}); for (std::size_t n = 0; n != array.size(); ++n) { - FilterIterator const iter(view, Iter(array.data() + n)); + FilterIterator iter = view.begin(); + for (std::size_t i = 0; i < n; ++i) + ++iter; ValueType& result = *iter; ASSERT_SAME_TYPE(ValueType&, decltype(*iter)); assert(&result == array.data() + n); diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.compile.pass.cpp new file mode 100644 index 0000000000000..06e06aeb6db6e --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.compile.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr explicit sentinel(filter_view&); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include + +#include "test_iterators.h" +#include "../types.h" + +using View = minimal_view>; +using FilterView = std::ranges::filter_view; +using FilterSentinel = std::ranges::sentinel_t; + +static_assert(!std::constructible_from); +static_assert(!std::convertible_to); diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.pass.cpp deleted file mode 100644 index 9896bf80c31e1..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.pass.cpp +++ /dev/null @@ -1,60 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// constexpr explicit sentinel(filter_view&); - -#include - -#include -#include -#include -#include -#include "test_iterators.h" -#include "../types.h" - -template > -constexpr void test() { - using View = minimal_view; - using FilterView = std::ranges::filter_view; - using FilterSentinel = std::ranges::sentinel_t; - - auto make_filter_view = [](auto begin, auto end, auto pred) { - View view{Iter(begin), Sent(Iter(end))}; - return FilterView(std::move(view), pred); - }; - - std::array array{0, 1, 2, 3, 4}; - FilterView view = make_filter_view(array.data(), array.data() + array.size(), AlwaysTrue{}); - - FilterSentinel sent(view); - assert(base(base(sent.base())) == base(base(view.end().base()))); - - static_assert(!std::is_constructible_v); - static_assert(!std::is_constructible_v); - static_assert( std::is_constructible_v && - !std::is_convertible_v); -} - -constexpr bool tests() { - test>(); - test>(); - test>(); - test>(); - test>(); - test>(); - test(); - return true; -} - -int main(int, char**) { - tests(); - static_assert(tests()); - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.compile.pass.cpp new file mode 100644 index 0000000000000..504c945e3d918 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.compile.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr explicit sentinel(Parent& parent); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include + +#include "../types.h" + +using Parent = std::ranges::join_view>; +static_assert(!std::is_constructible_v, Parent&>); +static_assert(!std::is_convertible_v, Parent&>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp deleted file mode 100644 index 1ac68277338fe..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp +++ /dev/null @@ -1,43 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// constexpr explicit sentinel(Parent& parent); - -#include -#include - -#include "test_macros.h" -#include "../types.h" - -constexpr bool test() { - int buffer[4][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; - - CopyableChild children[4] = {CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]), CopyableChild(buffer[3])}; - CopyableParent parent{children}; - std::ranges::join_view jv(parent); - std::ranges::sentinel_t sent(jv); - assert(sent == std::ranges::next(jv.begin(), 16)); - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - { - // Test explicitness. - using Parent = std::ranges::join_view>; - static_assert( std::is_constructible_v, Parent&>); - static_assert(!std::is_convertible_v, Parent&>); - } - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.compile.pass.cpp new file mode 100644 index 0000000000000..37fe2fadfd41a --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.compile.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr explicit inner-iterator::inner-iterator(outer-iterator i); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include + +#include "../types.h" + +static_assert(!std::is_constructible_v); +static_assert(!std::is_convertible_v); + +static_assert(!std::is_constructible_v); +static_assert(!std::is_convertible_v); diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.pass.cpp deleted file mode 100644 index 4981510be52d6..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.pass.cpp +++ /dev/null @@ -1,43 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// constexpr explicit inner-iterator::inner-iterator(outer-iterator i); - -#include - -#include "../types.h" - -static_assert(!std::is_constructible_v); - -template -constexpr void test_impl() { - [[maybe_unused]] Inner i(Outer{}); - // Verify that the constructor is `explicit`. - static_assert(!std::is_convertible_v); -} - -constexpr bool test() { - test_impl(); - test_impl(); -// Is only constructible if both the outer and the inner iterators have the same constness. - test_impl(); -// Note: this works because of an implicit conversion (`OuterIterNonConst` is converted to `OuterIterConst`). - test_impl(); - test_impl(); - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent_base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.base.compile.pass.cpp similarity index 53% rename from libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent_base.pass.cpp rename to libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.base.compile.pass.cpp index 9fc0ce3748b1f..70e97ea04f5c0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent_base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.base.compile.pass.cpp @@ -6,31 +6,17 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++20 // constexpr outer-iterator(Parent& parent, iterator_t current); // requires forward_range -#include +// The constructor is now `private` (exposition-only) per P3059R2. +#include #include -#include -#include "../types.h" - -static_assert(!std::ranges::forward_range); -static_assert(!std::is_constructible_v>); -constexpr bool test() { - ForwardView input("abc"); - SplitViewForward v(std::move(input), " "); - [[maybe_unused]] OuterIterForward i(v, input.begin()); - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); +#include "../types.h" - return 0; -} +static_assert(std::ranges::forward_range); +static_assert(!std::is_constructible_v>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.compile.pass.cpp similarity index 57% rename from libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.pass.cpp rename to libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.compile.pass.cpp index aacf6eabc290a..b838970718c8a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.compile.pass.cpp @@ -6,34 +6,18 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++20 // explicit std::ranges::lazy_split_view::outer-iterator::outer-iterator(Parent& parent) // requires (!forward_range) -#include +// The constructor is now `private` (exposition-only) per P3059R2. +#include #include -#include + #include "../types.h" -// Verify that the constructor is `explicit`. +static_assert(!std::ranges::forward_range); +static_assert(!std::is_constructible_v); static_assert(!std::is_convertible_v); - -static_assert( std::ranges::forward_range); -static_assert(!std::is_constructible_v); - -constexpr bool test() { - InputView input; - SplitViewInput v(input, ForwardTinyView()); - [[maybe_unused]] OuterIterInput i(v); - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp index 325189a0e521e..8e8eff8a12b97 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp @@ -16,9 +16,20 @@ #include "../types.h" struct Iter : ForwardIterBase { - int i; + int i = 0; constexpr Iter() = default; constexpr Iter(int ii) : i(ii) {} + constexpr int operator*() const { return i; } + constexpr Iter& operator++() { + ++i; + return *this; + } + constexpr Iter operator++(int) { + Iter tmp = *this; + ++*this; + return tmp; + } + friend constexpr bool operator==(const Iter& x, const Iter& y) { return x.i == y.i; } }; constexpr bool test() { @@ -26,34 +37,32 @@ constexpr bool test() { using SplitView = std::ranges::split_view, std::ranges::subrange>; using SplitIter = std::ranges::iterator_t; + SplitView sv{std::ranges::subrange{Iter{5}, Iter{8}}, std::ranges::subrange{Iter{8}, Iter{9}}}; + // const & { - SplitView sv; - const SplitIter it{sv, Iter{5}, {}}; + const SplitIter it = sv.begin(); std::same_as decltype(auto) base = it.base(); assert(base.i == 5); } // & { - SplitView sv; - SplitIter it{sv, Iter{5}, {}}; + SplitIter it = sv.begin(); std::same_as decltype(auto) base = it.base(); assert(base.i == 5); } // && { - SplitView sv; - SplitIter it{sv, Iter{5}, {}}; + SplitIter it = sv.begin(); std::same_as decltype(auto) base = std::move(it).base(); assert(base.i == 5); } // const && { - SplitView sv; - const SplitIter it{sv, Iter{5}, {}}; + const SplitIter it = sv.begin(); std::same_as decltype(auto) base = std::move(it).base(); assert(base.i == 5); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.parent.iter.subrange.compile.pass.cpp similarity index 64% rename from libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp rename to libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.parent.iter.subrange.compile.pass.cpp index 20b3c19611bd0..9f4e9a13e0447 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.parent.iter.subrange.compile.pass.cpp @@ -6,12 +6,14 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++20 // constexpr iterator(split_view& parent, iterator_t current, subrange> next); -#include +// The constructor is now `private` (exposition-only) per P3059R2. + #include +#include #include "../types.h" @@ -30,24 +32,7 @@ struct TracedMoveView : std::ranges::view_base { constexpr TracedMoveIter end() const { return {}; } }; -constexpr bool test() { - using SplitView = std::ranges::split_view; - using SplitIter = std::ranges::iterator_t; - - SplitView sv{TracedMoveView{}, TracedMoveView{}}; - SplitIter iter = {sv, sv.base().begin(), std::ranges::subrange{sv.base().begin(), sv.base().end()}}; - assert(iter.base().moved); - - auto subRange = *iter; - assert(subRange.begin().moved); - assert(subRange.end().moved); - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); +using SplitView = std::ranges::split_view; +using SplitIter = std::ranges::iterator_t; - return 0; -} +static_assert(!std::is_constructible_v>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp index 721a1cc0da3d4..0e9812020fb38 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp @@ -17,24 +17,31 @@ #include "../types.h" struct Iter : ForwardIterBase { - int i; + int i = 0; constexpr Iter() = default; constexpr Iter(int ii) : i(ii) {} + constexpr int operator*() const { return i; } + constexpr Iter& operator++() { + ++i; + return *this; + } + constexpr Iter operator++(int) { + Iter tmp = *this; + ++*this; + return tmp; + } + friend constexpr bool operator==(const Iter& x, const Iter& y) { return x.i == y.i; } }; constexpr bool test() { using SplitView = std::ranges::split_view, std::ranges::subrange>; using SplitIter = std::ranges::iterator_t; - { - SplitView sv; - Iter current{5}; - std::ranges::subrange next{Iter{6}, Iter{7}}; - const SplitIter it{sv, current, next}; - std::same_as> decltype(auto) value = *it; - assert(value.begin().i == 5); - assert(value.end().i == 6); - } + SplitView sv{std::ranges::subrange{Iter{5}, Iter{8}}, std::ranges::subrange{Iter{7}, Iter{8}}}; + const SplitIter it = sv.begin(); + std::same_as> decltype(auto) value = *it; + assert(value.begin().i == 5); + assert(value.end().i == 7); return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp similarity index 56% rename from libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp rename to libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp index c89b1ee2bdfce..e0e8029c4c538 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp @@ -6,44 +6,19 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++20 // constexpr explicit sentinel(split_view& parent); -#include +// The constructor is now `private` (exposition-only) per P3059R2. + #include -#include -#include "test_iterators.h" +#include "../types.h" -// test explicit using Range = std::ranges::subrange>; using SplitView = std::ranges::split_view>; using SplitSent = std::ranges::sentinel_t; -static_assert(std::is_constructible_v); +static_assert(!std::is_constructible_v); static_assert(!std::is_convertible_v); - -constexpr bool test() { - { - int buffer[] = {0, 1, 2}; - Range input{buffer, sentinel_wrapper(buffer + 3)}; - SplitView sv(input, -1); - auto it = sv.begin(); - - SplitSent sent(sv); - assert(sent != it); - - ++it; - assert(sent == it); - } - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pass.cpp deleted file mode 100644 index b952534d1c966..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pass.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// constexpr explicit sentinel(sentinel_t end, const Pred* pred); - -#include -#include -#include - -#include "../types.h" - -struct Sent { - int i; - - friend constexpr bool operator==(int* iter, const Sent& s) { return s.i > *iter; } -}; - -struct Range : std::ranges::view_base { - int* begin() const; - Sent end(); -}; - -struct Pred { - bool operator()(int i) const; -}; - -// Test explicit -template -void conversion_test(T); - -template -concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test({std::forward(args)...}); }; -static_assert(ImplicitlyConstructible); - -static_assert(std::is_constructible_v>, - std::ranges::sentinel_t, - const Pred*>); -static_assert(!ImplicitlyConstructible>, - std::ranges::sentinel_t, - const Pred*>); - -constexpr bool test() { - // base is init correctly - { - using R = std::ranges::take_while_view; - using Sentinel = std::ranges::sentinel_t; - - Sentinel s1(Sent{5}, nullptr); - assert(s1.base().i == 5); - } - - // pred is init correctly - { - bool called = false; - auto pred = [&](int) { - called = true; - return false; - }; - - using R = std::ranges::take_while_view; - using Sentinel = std::ranges::sentinel_t; - - int i = 10; - int* iter = &i; - Sentinel s(Sent{0}, &pred); - - bool b = iter == s; - assert(called); - assert(b); - } - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pred.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pred.compile.pass.cpp new file mode 100644 index 0000000000000..a66e3d1e84c6e --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pred.compile.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr explicit sentinel(sentinel_t end, const Pred* pred); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include +#include + +struct Sent { + int i; + + friend constexpr bool operator==(int* iter, const Sent& s) { return s.i > *iter; } +}; + +struct Range : std::ranges::view_base { + int* begin() const; + Sent end(); +}; + +struct Pred { + bool operator()(int i) const; +}; + +using Sentinel = std::ranges::sentinel_t>; + +static_assert(!std::is_constructible_v, const Pred*>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp index 865a3d45710fb..1808545422498 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp @@ -70,34 +70,48 @@ static_assert(!std::is_constructible_v< constexpr bool test() { // base is init correctly { - using R = std::ranges::take_while_view; + struct TestRng : std::ranges::view_base { + constexpr int* begin() const { return nullptr; } + constexpr Sent end() { return Sent{5}; } + constexpr ConstSent end() const { return ConstSent{5}; } + }; + + using R = std::ranges::take_while_view; using Sentinel = std::ranges::sentinel_t; using ConstSentinel = std::ranges::sentinel_t; static_assert(!std::same_as); - Sentinel s1(Sent{5}, nullptr); + R r{TestRng{}, nullptr}; + Sentinel s1 = r.end(); ConstSentinel s2 = s1; assert(s2.base().i == 5); } // pred is init correctly { + struct TestRng : std::ranges::view_base { + constexpr int* begin() const { return nullptr; } + constexpr Sent end() { return Sent{0}; } + constexpr ConstSent end() const { return ConstSent{0}; } + }; + bool called = false; auto pred = [&](int) { called = true; return false; }; - using R = std::ranges::take_while_view; + using R = std::ranges::take_while_view; using Sentinel = std::ranges::sentinel_t; using ConstSentinel = std::ranges::sentinel_t; static_assert(!std::same_as); - int i = 10; - int* iter = &i; - Sentinel s1(Sent{0}, &pred); + R r{TestRng{}, pred}; + Sentinel s1 = r.end(); ConstSentinel s2 = s1; + int i = 10; + int* iter = &i; [[maybe_unused]] bool b = iter == s2; assert(called); } @@ -111,20 +125,25 @@ constexpr bool test() { constexpr bool operator==(int* iter) const { return i > *iter; } }; + struct TestPred { + constexpr bool operator()(int) const { return false; } + }; + struct Rng : std::ranges::view_base { - int* begin() const; - Sent end(); - MoveOnlyConvert end() const; + constexpr int* begin() const { return nullptr; } + constexpr Sent end() { return Sent{0}; } + constexpr MoveOnlyConvert end() const { return MoveOnlyConvert(Sent{0}); } }; - using R = std::ranges::take_while_view; + using R = std::ranges::take_while_view; using Sentinel = std::ranges::sentinel_t; using ConstSentinel = std::ranges::sentinel_t; static_assert(!std::same_as); - Sentinel s1(Sent{5}, nullptr); + R r{Rng{}, TestPred{}}; + Sentinel s1 = r.end(); ConstSentinel s2 = s1; - assert(s2.base().i == 5); + assert(s2.base().i == 0); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.base.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.base.compile.pass.cpp new file mode 100644 index 0000000000000..9383508165609 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.base.compile.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr explicit sentinel(sentinel_t end); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include +#include + +#include "test_iterators.h" +#include "../types.h" + +using TakeView = std::ranges::take_view; +using Sentinel = std::ranges::sentinel_t; + +static_assert(!std::is_constructible_v>); +static_assert(!std::is_convertible_v, Sentinel>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.pass.cpp index 61d33760c71d7..3710be563c15b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.pass.cpp @@ -9,7 +9,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17 // sentinel() = default; -// constexpr explicit sentinel(sentinel_t end); // constexpr sentinel(sentinel s) // requires Const && convertible_to, sentinel_t>; @@ -49,18 +48,6 @@ constexpr bool test() { assert(std::as_const(tv).begin() + 4 == cs); } - { - // Test the constructor from "base-sentinel" to "sentinel". - using TakeView = std::ranges::take_view; - using Sentinel = std::ranges::sentinel_t; - sentinel_wrapper sw1 = MoveOnlyView(buffer).end(); - static_assert(std::is_constructible_v>); - static_assert(!std::is_convertible_v, Sentinel>); - auto s = Sentinel(sw1); - std::same_as> auto sw2 = s.base(); - assert(base(sw2) == base(sw1)); - } - return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/ctor.parent.iter.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/ctor.parent.iter.compile.pass.cpp new file mode 100644 index 0000000000000..37b6016e439fb --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/ctor.parent.iter.compile.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr iterator(Parent& parent, iterator_t current); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include + +#include "../types.h" + +using TransformView = std::ranges::transform_view; +using TransformViewBaseIter = std::ranges::iterator_t; +using TransformIter = std::ranges::iterator_t; + +static_assert(!std::is_constructible_v); diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp new file mode 100644 index 0000000000000..b5f134528fef0 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr explicit sentinel(sentinel_t end); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include + +#include "test_iterators.h" +#include "../types.h" + +using BaseSent = std::ranges::sentinel_t; +using TransformView = std::ranges::transform_view; +using TransformSent = std::ranges::sentinel_t; + +static_assert(!std::is_constructible_v); +static_assert(!std::is_convertible_v); diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp new file mode 100644 index 0000000000000..fc3384e191d1d --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr explicit iterator(W value); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include +#include + +#include "../types.h" + +static_assert(!std::is_constructible_v>, int>); + +using Iter = std::ranges::iterator_t>; +static_assert(!std::is_constructible_v); +static_assert(!std::is_convertible_v); diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.pass.cpp deleted file mode 100644 index a84cb91f7e9b3..0000000000000 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.pass.cpp +++ /dev/null @@ -1,45 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// constexpr explicit iterator(W value); - -#include -#include -#include - -#include "test_macros.h" -#include "../types.h" - -constexpr bool test() { - { - using Iter = std::ranges::iterator_t>; - auto iter = Iter(42); - assert(*iter == 42); - } - { - using Iter = std::ranges::iterator_t>; - auto iter = Iter(SomeInt(42)); - assert(*iter == SomeInt(42)); - } - { - using Iter = std::ranges::iterator_t>; - static_assert(!std::is_convertible_v); - static_assert( std::is_constructible_v); - } - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp new file mode 100644 index 0000000000000..b0bcdb6c60ce7 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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: std-at-least-c++20 + +// constexpr explicit sentinel(Bound bound); + +// The constructor is now `private` (exposition-only) per P3059R2. + +#include +#include + +#include "../types.h" + +using Sent = std::ranges::sentinel_t>>; +static_assert(!std::is_constructible_v>); +static_assert(!std::is_convertible_v, Sent>); diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.pass.cpp deleted file mode 100644 index a56369b046dc1..0000000000000 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.pass.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// constexpr explicit sentinel(Bound bound); - -#include -#include -#include - -#include "test_macros.h" -#include "../types.h" - -constexpr bool test() { - { - using Sent = std::ranges::sentinel_t>>; - using Iter = std::ranges::iterator_t>>; - auto sent = Sent(IntSentinelWith(42)); - assert(sent == Iter(42)); - } - { - using Sent = std::ranges::sentinel_t>>; - using Iter = std::ranges::iterator_t>>; - auto sent = Sent(IntSentinelWith(SomeInt(42))); - assert(sent == Iter(SomeInt(42))); - } - { - using Sent = std::ranges::sentinel_t>>; - static_assert(!std::is_convertible_v>); - static_assert( std::is_constructible_v>); - } - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp index ff60fbff1d73b..beeeea4c1bbe1 100644 --- a/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp @@ -39,10 +39,9 @@ void test() { // LWG 3568. basic_istream_view needs to initialize value_ { - auto iss = make_string_stream("123"); + auto iss = make_string_stream(""); std::ranges::basic_istream_view isv{iss}; - using Iter = std::ranges::iterator_t; - Iter iter{isv}; + auto iter = isv.begin(); assert(*iter == 0); } } diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp similarity index 54% rename from libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.pass.cpp rename to libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp index e180d12924084..04ff9ac24d731 100644 --- a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp @@ -6,18 +6,18 @@ // //===----------------------------------------------------------------------===// +// REQUIRES: std-at-least-c++20 // UNSUPPORTED: no-localization -// UNSUPPORTED: c++03, c++11, c++14, c++17 // constexpr explicit iterator(basic_istream_view& parent) noexcept; -#include +// The constructor is now `private` (exposition-only) per P3059R2. + #include #include #include #include "test_macros.h" -#include "../utils.h" // test that the constructor is explicit template @@ -25,34 +25,10 @@ using IstreamView = std::ranges::basic_istream_view; template using Iter = std::ranges::iterator_t>; -static_assert(std::constructible_from, IstreamView&>); +static_assert(!std::constructible_from, IstreamView&>); static_assert(!std::convertible_to&, Iter>); #ifndef TEST_HAS_NO_WIDE_CHARACTERS -static_assert(std::constructible_from, IstreamView&>); +static_assert(!std::constructible_from, IstreamView&>); static_assert(!std::convertible_to&, Iter>); #endif - -// test that the constructor is noexcept -static_assert(std::is_nothrow_constructible_v, IstreamView&>); -#ifndef TEST_HAS_NO_WIDE_CHARACTERS -static_assert(std::is_nothrow_constructible_v, IstreamView&>); -#endif - -template -void test() { - auto iss = make_string_stream("123"); - std::ranges::basic_istream_view isv{iss}; - Iter it{isv}; - ++it; - assert(*it == 123); -} - -int main(int, char**) { - test(); -#ifndef TEST_HAS_NO_WIDE_CHARACTERS - test(); -#endif - - return 0; -} diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp index 1cf05f0ac4cbe..5df730410a4ad 100644 --- a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp @@ -35,8 +35,8 @@ void test() { std::ranges::basic_istream_view isv{iss}; using Iter = std::ranges::iterator_t; - Iter it1{isv}; - Iter it2{isv}; + Iter it1 = isv.begin(); + Iter it2 = isv.begin(); assert(&*it1 == &*it2); } }