1111#include < ranges>
1212
1313#include " test_macros.h"
14+ #include " test_iterators.h"
15+ #include " check_assertion.h"
1416#include " ../types.h"
1517
1618int globalBuff[8 ] = {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 };
@@ -64,6 +66,18 @@ struct IterNoDefaultInitView : std::ranges::view_base {
6466 int * end ();
6567};
6668
69+ struct ThrowOnCopyView : std::ranges::view_base {
70+ int start_;
71+ int * ptr_;
72+ constexpr explicit ThrowOnCopyView (int * ptr = globalBuff, int start = 0 ) : start_(start), ptr_(ptr) {}
73+ constexpr ThrowOnCopyView (ThrowOnCopyView&&) = default;
74+ constexpr ThrowOnCopyView (const ThrowOnCopyView&) { throw 42 ; };
75+ constexpr ThrowOnCopyView& operator =(ThrowOnCopyView&&) = default ;
76+ constexpr ThrowOnCopyView& operator =(const ThrowOnCopyView&) { throw 42 ; };
77+ constexpr int * begin () const { return ptr_ + start_; }
78+ constexpr int * end () const { return ptr_ + 8 ; }
79+ };
80+
6781constexpr bool test () {
6882 std::ranges::concat_view<MoveOnlyView> concatView;
6983 auto iter = std::move (concatView).begin ();
@@ -75,6 +89,23 @@ constexpr bool test() {
7589 static_assert (std::default_initializable<std::ranges::iterator_t <std::ranges::concat_view<MoveOnlyView>>>);
7690 static_assert (!std::default_initializable<std::ranges::iterator_t <std::ranges::concat_view<IterNoDefaultInitView>>>);
7791
92+ {
93+ // valueless by exception test
94+ std::ranges::concat_view<ThrowOnCopyView> concatView;
95+ std::ranges::iterator_t <std::ranges::concat_view<ThrowOnCopyView>> it1;
96+ std::ranges::iterator_t <std::ranges::concat_view<ThrowOnCopyView>> it2;
97+ try {
98+ it1 = concatView.begin ();
99+ } catch (...) {
100+ TEST_LIBCPP_ASSERT_FAILURE (
101+ [&] {
102+ it2 = it1;
103+ (void )it2;
104+ }(),
105+ " valueless by exception" );
106+ }
107+ }
108+
78109 return true ;
79110}
80111
0 commit comments