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// constexpr iterator_type base() const; // Until C++20
12// constexpr const Iterator& base() const & noexcept; // From C++20
13// constexpr Iterator base() &&; // From C++20
14
15#include <iterator>
16
17#include <utility>
18#include "test_iterators.h"
19#include "test_macros.h"
20
21struct MoveOnlyIterator {
22 using It = int*;
23
24 It it_;
25
26 using iterator_category = std::input_iterator_tag;
27 using value_type = int;
28 using difference_type = std::ptrdiff_t;
29 using reference = int&;
30
31 TEST_CONSTEXPR explicit MoveOnlyIterator(It it) : it_(it) {}
32 MoveOnlyIterator(MoveOnlyIterator&&) = default;
33 MoveOnlyIterator& operator=(MoveOnlyIterator&&) = default;
34 MoveOnlyIterator(const MoveOnlyIterator&) = delete;
35 MoveOnlyIterator& operator=(const MoveOnlyIterator&) = delete;
36
37 TEST_CONSTEXPR reference operator*() const { return *it_; }
38
39 TEST_CONSTEXPR_CXX14 MoveOnlyIterator& operator++() { ++it_; return *this; }
40 TEST_CONSTEXPR_CXX14 MoveOnlyIterator operator++(int) { return MoveOnlyIterator(it_++); }
41
42 friend TEST_CONSTEXPR bool operator==(const MoveOnlyIterator& x, const MoveOnlyIterator& y) {return x.it_ == y.it_;}
43 friend TEST_CONSTEXPR bool operator!=(const MoveOnlyIterator& x, const MoveOnlyIterator& y) {return x.it_ != y.it_;}
44
45 friend TEST_CONSTEXPR It base(const MoveOnlyIterator& i) { return i.it_; }
46};
47
48#if TEST_STD_VER > 17
49static_assert( std::input_iterator<MoveOnlyIterator>);
50#endif
51static_assert(!std::is_copy_constructible<MoveOnlyIterator>::value, "");
52
53template <class It>
54TEST_CONSTEXPR_CXX14 void test_one() {
55 // Non-const lvalue.
56 {
57 int a[] = {1, 2, 3};
58
59 auto i = std::move_iterator<It>(It(a));
60#if TEST_STD_VER > 17
61 ASSERT_SAME_TYPE(decltype(i.base()), const It&);
62 ASSERT_NOEXCEPT(i.base());
63#else
64 ASSERT_SAME_TYPE(decltype(i.base()), It);
65#endif
66 assert(i.base() == It(a));
67
68 ++i;
69 assert(i.base() == It(a + 1));
70 }
71
72 // Const lvalue.
73 {
74 int a[] = {1, 2, 3};
75
76 const auto i = std::move_iterator<It>(It(a));
77#if TEST_STD_VER > 17
78 ASSERT_SAME_TYPE(decltype(i.base()), const It&);
79 ASSERT_NOEXCEPT(i.base());
80#else
81 ASSERT_SAME_TYPE(decltype(i.base()), It);
82#endif
83 assert(i.base() == It(a));
84 }
85
86 // Rvalue.
87 {
88 int a[] = {1, 2, 3};
89
90 auto i = std::move_iterator<It>(It(a));
91 ASSERT_SAME_TYPE(decltype(std::move(i).base()), It);
92 assert(std::move(i).base() == It(a));
93 }
94}
95
96TEST_CONSTEXPR_CXX14 bool test() {
97 test_one<cpp17_input_iterator<int*> >();
98 test_one<forward_iterator<int*> >();
99 test_one<bidirectional_iterator<int*> >();
100 test_one<random_access_iterator<int*> >();
101 test_one<int*>();
102 test_one<const int*>();
103#if TEST_STD_VER > 17
104 test_one<contiguous_iterator<int*>>();
105#endif
106
107 return true;
108}
109
110int main(int, char**) {
111 test();
112#if TEST_STD_VER > 14
113 static_assert(test());
114#endif
115
116 return 0;
117}
118

source code of libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.conv/base.pass.cpp