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// move_iterator
14
15// template<sized_sentinel_for<Iterator> S>
16// friend constexpr iter_difference_t<Iterator>
17// operator-(const move_sentinel<S>& x, const move_iterator& y); // Since C++20
18// template<sized_sentinel_for<Iterator> S>
19// friend constexpr iter_difference_t<Iterator>
20// operator-(const move_iterator& x, const move_sentinel<S>& y); // Since C++20
21
22#include <iterator>
23#include <cassert>
24
25#include "test_macros.h"
26#include "test_iterators.h"
27
28// The `operator-` calls the underlying iterator and sentinel's `operator-`.
29
30struct CustomIt {
31 using value_type = int;
32 using difference_type = int;
33 using reference = int&;
34 using pointer = int*;
35 using iterator_category = std::input_iterator_tag;
36
37 CustomIt() = default;
38 TEST_CONSTEXPR_CXX17 explicit CustomIt(int* p) : p_(p) {}
39 int& operator*() const;
40 CustomIt& operator++();
41 CustomIt operator++(int);
42 constexpr friend difference_type operator-(const CustomIt& a, const CustomIt& b) { return a.p_ - b.p_; }
43 int *p_ = nullptr;
44};
45
46template <class It, class Sent = sized_sentinel<It>>
47constexpr void test_one() {
48 int arr[] = {3, 1, 4};
49
50 const std::move_iterator<It> it_a{It(arr)};
51 const std::move_iterator<It> it_b{It(arr + 1)};
52
53 const std::move_sentinel<Sent> sent_a{Sent(It(arr))};
54 const std::move_sentinel<Sent> sent_b{Sent(It(arr + 1))};
55 const std::move_sentinel<Sent> sent_c{Sent(It(arr + 2))};
56
57 ASSERT_SAME_TYPE(decltype(it_a - sent_a), std::iter_difference_t<It>);
58 ASSERT_SAME_TYPE(decltype(sent_a - it_a), std::iter_difference_t<It>);
59
60 // it_a
61 assert(it_a - sent_a == 0);
62 assert(sent_a - it_a == 0);
63
64 assert(it_a - sent_b == -1);
65 assert(sent_b - it_a == 1);
66
67 assert(it_a - sent_c == -2);
68 assert(sent_c - it_a == 2);
69
70 // it_b
71 assert(it_b - sent_a == 1);
72 assert(sent_a - it_b == -1);
73
74 assert(it_b - sent_b == 0);
75 assert(sent_b - it_b == 0);
76
77 assert(it_b - sent_c == -1);
78 assert(sent_c - it_b == 1);
79}
80
81constexpr bool test() {
82 test_one<CustomIt>();
83 test_one<cpp17_input_iterator<int*>>();
84 test_one<forward_iterator<int*>>();
85 test_one<bidirectional_iterator<int*>>();
86 test_one<random_access_iterator<int*>>();
87 test_one<int*>();
88 test_one<const int*>();
89 test_one<contiguous_iterator<int*>>();
90
91 return true;
92}
93
94int main(int, char**) {
95 test();
96 static_assert(test());
97
98 return 0;
99}
100

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