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 // UNSUPPORTED: c++03, c++11, c++14, c++17
10
11 // friend constexpr iter_rvalue_reference_t<I>
12 // iter_move(const counted_iterator& i)
13 // noexcept(noexcept(ranges::iter_move(i.current)))
14 // requires input_iterator<I>;
15
16 #include <iterator>
17
18 #include "test_macros.h"
19 #include "test_iterators.h"
20
21 template<bool IsNoexcept>
22 class HasNoexceptIterMove
23 {
24 int *it_;
25
26 public:
27 typedef std::input_iterator_tag iterator_category;
28 typedef int value_type;
29 typedef typename std::iterator_traits<int *>::difference_type difference_type;
30 typedef int * pointer;
31 typedef int & reference;
32
base() const33 constexpr int *base() const {return it_;}
34
35 HasNoexceptIterMove() = default;
HasNoexceptIterMove(int * it)36 explicit constexpr HasNoexceptIterMove(int *it) : it_(it) {}
37
operator *() const38 constexpr reference operator*() const noexcept(IsNoexcept) { return *it_; }
39
operator ++()40 constexpr HasNoexceptIterMove& operator++() {++it_; return *this;}
operator ++(int)41 constexpr HasNoexceptIterMove operator++(int)
42 {HasNoexceptIterMove tmp(*this); ++(*this); return tmp;}
43 };
44
45
test()46 constexpr bool test() {
47 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
48
49 {
50 auto iter1 = cpp17_input_iterator<int*>(buffer);
51 auto commonIter1 = std::counted_iterator<decltype(iter1)>(iter1, 8);
52 assert(std::ranges::iter_move(commonIter1) == 1);
53 ASSERT_SAME_TYPE(decltype(std::ranges::iter_move(commonIter1)), int&&);
54 }
55 {
56 auto iter1 = forward_iterator<int*>(buffer);
57 auto commonIter1 = std::counted_iterator<decltype(iter1)>(iter1, 8);
58 assert(std::ranges::iter_move(commonIter1) == 1);
59 ASSERT_SAME_TYPE(decltype(std::ranges::iter_move(commonIter1)), int&&);
60 }
61 {
62 auto iter1 = random_access_iterator<int*>(buffer);
63 auto commonIter1 = std::counted_iterator<decltype(iter1)>(iter1, 8);
64 assert(std::ranges::iter_move(commonIter1) == 1);
65 ASSERT_SAME_TYPE(decltype(std::ranges::iter_move(commonIter1)), int&&);
66 }
67
68 // Test noexceptness.
69 {
70 static_assert( noexcept(std::ranges::iter_move(std::declval<std::counted_iterator<HasNoexceptIterMove<true>>>())));
71 static_assert(!noexcept(std::ranges::iter_move(std::declval<std::counted_iterator<HasNoexceptIterMove<false>>>())));
72 }
73
74 return true;
75 }
76
main(int,char **)77 int main(int, char**) {
78 test();
79 static_assert(test());
80
81 return 0;
82 }
83