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>
test(U 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 
ToIterToIter41     explicit TEST_CONSTEXPR_CXX17 ToIter() : m_value(0) {}
ToIterToIter42     TEST_CONSTEXPR_CXX17 ToIter(const ToIter &src) : m_value(src.m_value) {}
43     // Intentionally not defined, must not be called.
44     ToIter(char *src);
operator =ToIter45     TEST_CONSTEXPR_CXX17 ToIter &operator=(char *src) {
46         m_value = src;
47         return *this;
48     }
operator =ToIter49     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 
tests()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     test<Base*>(&d);
63 
64     char c = '\0';
65     char *fi = &c;
66     const std::reverse_iterator<char *> rev_fi(fi);
67     std::reverse_iterator<ToIter> rev_ti;
68     rev_ti = rev_fi;
69     assert(rev_ti.base().m_value == fi);
70 
71     return true;
72 }
73 
main(int,char **)74 int main(int, char**) {
75     tests();
76 #if TEST_STD_VER > 14
77     static_assert(tests(), "");
78 #endif
79     return 0;
80 }
81