1919#include " test_iterators.h"
2020
2121int globalArray[8 ] = {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 };
22-
22+ bool already_moved = false ;
2323
2424template <class It , class ItTraits = It >
25- class ThrowOnMoveIterator
26- {
27- typedef std::iterator_traits<ItTraits> Traits ;
28- It it_ ;
29- support::double_move_tracker tracker_;
30- bool moved = false ;
31-
32- template < class U , class T > friend class ThrowOnMoveIterator ;
25+ class ThrowOnMoveIterator {
26+ typedef std::iterator_traits<ItTraits> Traits;
27+ It it_ ;
28+ support::double_move_tracker tracker_ ;
29+
30+ template < class U , class T >
31+ friend class ThrowOnMoveIterator ;
32+
3333public:
34- typedef std::input_iterator_tag iterator_category;
35- typedef typename Traits::value_type value_type;
36- typedef typename Traits::difference_type difference_type;
37- typedef It pointer;
38- typedef typename Traits::reference reference;
34+ typedef std::input_iterator_tag iterator_category;
35+ typedef typename Traits::value_type value_type;
36+ typedef typename Traits::difference_type difference_type;
37+ typedef It pointer;
38+ typedef typename Traits::reference reference;
3939
40- constexpr ThrowOnMoveIterator () {}
40+ constexpr ThrowOnMoveIterator () {}
4141
42- constexpr ThrowOnMoveIterator (It it) : it_(it) {}
42+ constexpr ThrowOnMoveIterator (It it) : it_(it) {}
4343
44- template <class U , class T >
45- constexpr ThrowOnMoveIterator (const ThrowOnMoveIterator<U, T>& u) : it_(u.it_), tracker_(u.tracker_), moved(u.moved ) {}
44+ template <class U , class T >
45+ constexpr ThrowOnMoveIterator (const ThrowOnMoveIterator<U, T>& u) : it_(u.it_), tracker_(u.tracker_) {}
4646
47- constexpr ThrowOnMoveIterator (const ThrowOnMoveIterator& other): moved(other.moved) {}
47+ constexpr ThrowOnMoveIterator (const ThrowOnMoveIterator&) {}
4848
49- constexpr ThrowOnMoveIterator (ThrowOnMoveIterator&& other){
49+ constexpr ThrowOnMoveIterator (ThrowOnMoveIterator&&) {
50+ std::cout << " moved ctor called with: " << already_moved << std::endl;
51+ if (!already_moved) {
52+ already_moved = true ;
5053 throw std::runtime_error (" Move failed in iter" );
51- other.moved = true ;
52- moved = other.moved ;
5354 }
55+ }
5456
55- ThrowOnMoveIterator& operator =(ThrowOnMoveIterator&& other) {
56- if (other.moved ) {
57- throw std::runtime_error (" Move assignment failed in iter" );
58- }
59- other.moved = true ;
60- moved = other.moved ;
61- return *this ;
57+ ThrowOnMoveIterator& operator =(ThrowOnMoveIterator&&) {
58+ if (!already_moved) {
59+ already_moved = true ;
60+ throw std::runtime_error (" Move assignment failed in iter" );
6261 }
62+ return *this ;
63+ }
6364
64- constexpr reference operator *() const {return *it_;}
65+ constexpr reference operator *() const { return *it_; }
6566
66- constexpr ThrowOnMoveIterator& operator ++() {++it_; return *this ;}
67- constexpr ThrowOnMoveIterator operator ++(int ) {return ThrowOnMoveIterator (it_++);}
67+ constexpr ThrowOnMoveIterator& operator ++() {
68+ ++it_;
69+ return *this ;
70+ }
71+ constexpr ThrowOnMoveIterator operator ++(int ) { return ThrowOnMoveIterator (it_++); }
6872
69- friend constexpr bool operator ==(const ThrowOnMoveIterator& x, const ThrowOnMoveIterator& y) {return x.it_ == y.it_ ;}
70- friend constexpr bool operator !=(const ThrowOnMoveIterator& x, const ThrowOnMoveIterator& y) {return x.it_ != y.it_ ;}
73+ friend constexpr bool operator ==(const ThrowOnMoveIterator& x, const ThrowOnMoveIterator& y) {
74+ return x.it_ == y.it_ ;
75+ }
76+ friend constexpr bool operator !=(const ThrowOnMoveIterator& x, const ThrowOnMoveIterator& y) {
77+ return x.it_ != y.it_ ;
78+ }
7179
72- friend constexpr It base (const ThrowOnMoveIterator& i) { return i.it_ ; }
80+ friend constexpr It base (const ThrowOnMoveIterator& i) { return i.it_ ; }
7381
74- template <class T >
75- void operator ,(T const &) = delete ;
82+ template <class T >
83+ void operator ,(T const &) = delete ;
7684};
7785
7886template <class T >
@@ -87,12 +95,12 @@ struct BufferView : std::ranges::view_base {
8795using IntBufferView = BufferView<int >;
8896
8997template <bool Simple>
90- struct Common : IntBufferView {
98+ struct Common : IntBufferView {
9199 using IntBufferView::IntBufferView;
92- using Iter = ThrowOnMoveIterator<int *>;
93- using ConstIter = ThrowOnMoveIterator<const int *>;
94- using Sent = sentinel_wrapper<Iter>;
95- using ConstSent = sentinel_wrapper<ConstIter>;
100+ using Iter = ThrowOnMoveIterator<int *>;
101+ using ConstIter = ThrowOnMoveIterator<const int *>;
102+ using Sent = sentinel_wrapper<Iter>;
103+ using ConstSent = sentinel_wrapper<ConstIter>;
96104
97105 constexpr Iter begin ()
98106 requires(!Simple)
@@ -108,30 +116,32 @@ struct Common : IntBufferView {
108116 constexpr ConstSent end () const { return ConstSent (buffer_ + size_); }
109117};
110118
111- using SimpleCommon = Common<true >;
119+ using SimpleCommon = Common<true >;
112120using NonSimpleCommon = Common<false >;
113121
114122int main () {
115-
116123 {
117- int buffer[3 ] = {1 , 2 , 3 };
124+ int buffer[3 ] = {1 , 2 , 3 };
118125 int buffer2[3 ] = {1 , 2 , 3 };
119- NonSimpleCommon view (buffer);
120- NonSimpleCommon view2 (buffer2);
126+ NonSimpleCommon view (buffer);
127+ NonSimpleCommon view2 (buffer2);
121128 std::ranges::concat_view v (view, view2);
122129 std::ranges::iterator_t <std::ranges::concat_view<decltype (view), decltype (view2)>> it1;
123130 try {
124131 it1 = v.begin ();
125132 } catch (...) {
133+ std::cout << " hit catch" << std::endl;
134+ // ASSERT_SAME_TYPE(std::ranges::iterator_t<const decltype(v)>, int);
135+ std::ranges::iterator_t <const decltype (v)> it2 (it1);
126136 TEST_LIBCPP_ASSERT_FAILURE (
127137 [=] {
128- std::ranges::iterator_t <const decltype (v)> it2 (v. begin () );
138+ std::ranges::iterator_t <const decltype (v)> it2 (it1 );
129139 (void )it2;
130140 }(),
131141 " valueless by exception" );
132142 }
133143 }
134- /*
144+ /*
135145 {
136146 //valueless by exception test operator==
137147 ThrowingRange<int*> throwing{3, 5};
0 commit comments