xref: /llvm-project/libcxx/test/std/iterators/predef.iterators/counted.iterator/iter_move.pass.cpp (revision d2baefae6846765eef6a6dd69d4fdf1082ce29ad)
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