1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <iterator>
10 
11 // reverse_iterator
12 
13 // template <class U>
14 // reverse_iterator& operator=(const reverse_iterator<U>& u); // constexpr since C++17
15 
16 #include <iterator>
17 #include <cassert>
18 
19 #include "test_macros.h"
20 #include "test_iterators.h"
21 
22 template <class It, class U>
23 TEST_CONSTEXPR_CXX17 void test(U u) {
24     const std::reverse_iterator<U> r2(u);
25     std::reverse_iterator<It> r1;
26     std::reverse_iterator<It>& rr = r1 = r2;
27     assert(base(r1.base()) == base(u));
28     assert(&rr == &r1);
29 }
30 
31 struct Base { };
32 struct Derived : Base { };
33 
34 struct ToIter {
35     typedef std::bidirectional_iterator_tag iterator_category;
36     typedef char *pointer;
37     typedef char &reference;
38     typedef char value_type;
39     typedef value_type difference_type;
40 
41     explicit TEST_CONSTEXPR_CXX17 ToIter() : m_value(0) {}
42     TEST_CONSTEXPR_CXX17 ToIter(const ToIter &src) : m_value(src.m_value) {}
43     // Intentionally not defined, must not be called.
44     ToIter(char *src);
45     TEST_CONSTEXPR_CXX17 ToIter &operator=(char *src) {
46         m_value = src;
47         return *this;
48     }
49     TEST_CONSTEXPR_CXX17 ToIter &operator=(const ToIter &src) {
50         m_value = src.m_value;
51         return *this;
52     }
53     char *m_value;
54 
55     reference operator*() const;
56 };
57 
58 TEST_CONSTEXPR_CXX17 bool tests() {
59     Derived d;
60     test<bidirectional_iterator<Base*> >(bidirectional_iterator<Derived*>(&d));
61     test<random_access_iterator<const Base*> >(random_access_iterator<Derived*>(&d));
62 #if TEST_STD_VER >= 20
63     test<cpp20_random_access_iterator<const Base*> >(cpp20_random_access_iterator<Derived*>(&d));
64 #endif
65     test<Base*>(&d);
66 
67     char c = '\0';
68     char *fi = &c;
69     const std::reverse_iterator<char *> rev_fi(fi);
70     std::reverse_iterator<ToIter> rev_ti;
71     rev_ti = rev_fi;
72     assert(rev_ti.base().m_value == fi);
73 
74     return true;
75 }
76 
77 int main(int, char**) {
78     tests();
79 #if TEST_STD_VER > 14
80     static_assert(tests(), "");
81 #endif
82     return 0;
83 }
84