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 // move_iterator
12 
13 // constexpr auto operator++(int); // Return type was move_iterator until C++20
14 
15 #include <iterator>
16 #include <cassert>
17 #include <utility>
18 
19 #include "test_macros.h"
20 #include "test_iterators.h"
21 
22 #if TEST_STD_VER > 17
23 template <class It>
test_single_pass(It i,It x)24 void test_single_pass(It i, It x) {
25   std::move_iterator<It> r(std::move(i));
26   r++;
27   assert(std::move(r).base() == x);
28 }
29 #endif
30 
31 template <class It>
test(It i,It x)32 void test(It i, It x) {
33     std::move_iterator<It> r(i);
34     std::move_iterator<It> rr = r++;
35     assert(r.base() == x);
36     assert(rr.base() == i);
37 }
38 
main(int,char **)39 int main(int, char**) {
40   char s[] = "123";
41 #if TEST_STD_VER > 17
42   test_single_pass(cpp17_input_iterator<char*>(s), cpp17_input_iterator<char*>(s + 1));
43 #else
44   test(cpp17_input_iterator<char*>(s), cpp17_input_iterator<char*>(s+1));
45 #endif
46   test(forward_iterator<char*>(s), forward_iterator<char*>(s+1));
47   test(bidirectional_iterator<char*>(s), bidirectional_iterator<char*>(s+1));
48   test(random_access_iterator<char*>(s), random_access_iterator<char*>(s+1));
49   test(s, s+1);
50 
51 #if TEST_STD_VER > 14
52   {
53     constexpr const char *p = "123456789";
54     typedef std::move_iterator<const char *> MI;
55     constexpr MI it1 = std::make_move_iterator(p);
56     constexpr MI it2 = std::make_move_iterator(p+1);
57     static_assert(it1 != it2, "");
58     constexpr MI it3 = std::make_move_iterator(p) ++;
59     static_assert(it1 == it3, "");
60     static_assert(it2 != it3, "");
61   }
62 #endif
63 
64 #if TEST_STD_VER > 17
65   // Forward iterators return a copy.
66   {
67     int a[] = {1, 2, 3};
68     using MoveIter = std::move_iterator<forward_iterator<int*>>;
69 
70     MoveIter i = MoveIter(forward_iterator<int*>(a));
71     ASSERT_SAME_TYPE(decltype(i++), MoveIter);
72     auto j = i++;
73     assert(base(j.base()) == a);
74     assert(base(i.base()) == a + 1);
75   }
76 
77   // Non-forward iterators return void.
78   {
79     int a[] = {1, 2, 3};
80     using MoveIter = std::move_iterator<cpp20_input_iterator<int*>>;
81 
82     MoveIter i = MoveIter(cpp20_input_iterator<int*>(a));
83     ASSERT_SAME_TYPE(decltype(i++), void);
84     i++;
85     assert(base(i.base()) == a + 1);
86   }
87 #endif
88 
89   return 0;
90 }
91