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// <iterator>
12//
13// friend constexpr iter_rvalue_reference_t<Iterator>
14// iter_move(const move_iterator& i)
15// noexcept(noexcept(ranges::iter_move(i.current))); // Since C++20
16
17#include <iterator>
18
19#include <cassert>
20#include <type_traits>
21#include <utility>
22#include "test_iterators.h"
23#include "test_macros.h"
24
25int global;
26
27template <bool IsNoexcept>
28struct MaybeNoexceptMove {
29 int x;
30 using value_type = int;
31 using difference_type = std::ptrdiff_t;
32
33 constexpr friend value_type&& iter_move(MaybeNoexceptMove) noexcept(IsNoexcept) {
34 return std::move(global);
35 }
36
37 int& operator*() const { static int a; return a; }
38
39 MaybeNoexceptMove& operator++();
40 MaybeNoexceptMove operator++(int);
41};
42using ThrowingBase = MaybeNoexceptMove<false>;
43using NoexceptBase = MaybeNoexceptMove<true>;
44static_assert(std::input_iterator<ThrowingBase>);
45ASSERT_NOT_NOEXCEPT(std::ranges::iter_move(std::declval<ThrowingBase>()));
46ASSERT_NOEXCEPT(std::ranges::iter_move(std::declval<NoexceptBase>()));
47
48constexpr bool test() {
49 // Can use `iter_move` with a regular array.
50 {
51 int a[] = {0, 1, 2};
52
53 std::move_iterator<int*> i(a);
54 static_assert(std::same_as<decltype(iter_move(i)), int&&>);
55 assert(iter_move(i) == 0);
56
57 ++i;
58 assert(iter_move(i) == 1);
59 }
60
61 // Check that the `iter_move` customization point is being used.
62 {
63 int a[] = {0, 1, 2};
64
65 int iter_move_invocations = 0;
66 adl::Iterator base = adl::Iterator::TrackMoves(a, iter_move_invocations);
67 std::move_iterator<adl::Iterator> i(base);
68 int x = iter_move(i);
69 assert(x == 0);
70 assert(iter_move_invocations == 1);
71 }
72
73 // Check the `noexcept` specification.
74 {
75 using ThrowingIter = std::move_iterator<ThrowingBase>;
76 ASSERT_NOT_NOEXCEPT(iter_move(std::declval<ThrowingIter>()));
77 using NoexceptIter = std::move_iterator<NoexceptBase>;
78 ASSERT_NOEXCEPT(iter_move(std::declval<NoexceptIter>()));
79 }
80
81 return true;
82}
83
84int main(int, char**) {
85 test();
86 static_assert(test());
87
88 return 0;
89}
90

source code of libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.nonmember/iter_move.pass.cpp