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 iterator operator-(iterator i, difference_type n)
12// requires advanceable<W>;
13// friend constexpr difference_type operator-(const iterator& x, const iterator& y)
14// requires advanceable<W>;
15
16#include <cassert>
17#include <cstdint>
18#include <ranges>
19#include <type_traits>
20
21#include "test_macros.h"
22#include "../types.h"
23
24// If we're compiling for 32 bit or windows, int and long are the same size, so long long is the correct difference type.
25#if INTPTR_MAX == INT32_MAX || defined(_WIN32)
26using IntDiffT = long long;
27#else
28using IntDiffT = long;
29#endif
30
31constexpr bool test() {
32 // <iterator> - difference_type
33 {
34 // When "_Start" is signed integer like.
35 {
36 std::ranges::iota_view<int> io(0);
37 auto iter1 = std::next(io.begin(), 10);
38 auto iter2 = std::next(io.begin(), 10);
39 assert(iter1 == iter2);
40 assert(iter1 - 5 != iter2);
41 assert(iter1 - 5 == std::ranges::prev(iter2, 5));
42
43 static_assert(!std::is_reference_v<decltype(iter2 - 5)>);
44 }
45
46 // When "_Start" is not integer like.
47 {
48 std::ranges::iota_view io(SomeInt(0));
49 auto iter1 = std::next(io.begin(), 10);
50 auto iter2 = std::next(io.begin(), 10);
51 assert(iter1 == iter2);
52 assert(iter1 - 5 != iter2);
53 assert(iter1 - 5 == std::ranges::prev(iter2, 5));
54
55 static_assert(!std::is_reference_v<decltype(iter2 - 5)>);
56 }
57
58 // When "_Start" is unsigned integer like and n is greater than or equal to zero.
59 {
60 std::ranges::iota_view<unsigned> io(0);
61 auto iter1 = std::next(io.begin(), 10);
62 auto iter2 = std::next(io.begin(), 10);
63 assert(iter1 == iter2);
64 assert(iter1 - 5 != iter2);
65 assert(iter1 - 5 == std::ranges::prev(iter2, 5));
66
67 static_assert(!std::is_reference_v<decltype(iter2 - 5)>);
68 }
69 {
70 std::ranges::iota_view<unsigned> io(0);
71 auto iter1 = std::next(io.begin(), 10);
72 auto iter2 = std::next(io.begin(), 10);
73 assert(iter1 - 0 == iter2);
74 }
75
76 // When "_Start" is unsigned integer like and n is less than zero.
77 {
78 std::ranges::iota_view<unsigned> io(0);
79 auto iter1 = std::next(io.begin(), 10);
80 auto iter2 = std::next(io.begin(), 10);
81 assert(iter1 - 5 != iter2);
82 assert(iter1 - 5 == std::ranges::prev(iter2, 5));
83
84 static_assert(!std::is_reference_v<decltype(iter2 - 5)>);
85 }
86 }
87
88 // <iterator> - <iterator>
89 {
90 // When "_Start" is signed integer like.
91 {
92 std::ranges::iota_view<int> io(0);
93 auto iter1 = std::next(io.begin(), 10);
94 auto iter2 = std::next(io.begin(), 5);
95 assert(iter1 - iter2 == 5);
96
97 LIBCPP_STATIC_ASSERT(std::same_as<decltype(iter1 - iter2), IntDiffT>);
98 }
99 {
100 std::ranges::iota_view<int> io(0);
101 auto iter1 = std::next(io.begin(), 10);
102 auto iter2 = std::next(io.begin(), 10);
103 assert(iter1 - iter2 == 0);
104
105 LIBCPP_STATIC_ASSERT(std::same_as<decltype(iter1 - iter2), IntDiffT>);
106 }
107 {
108 std::ranges::iota_view<int> io(0);
109 auto iter1 = std::next(io.begin(), 5);
110 auto iter2 = std::next(io.begin(), 10);
111 assert(iter1 - iter2 == -5);
112
113 LIBCPP_STATIC_ASSERT(std::same_as<decltype(iter1 - iter2), IntDiffT>);
114 }
115
116 // When "_Start" is unsigned integer like and y > x.
117 {
118 std::ranges::iota_view<unsigned> io(0);
119 auto iter1 = std::next(io.begin(), 5);
120 auto iter2 = std::next(io.begin(), 10);
121 assert(iter1 - iter2 == -5);
122
123 LIBCPP_STATIC_ASSERT(std::same_as<decltype(iter1 - iter2), IntDiffT>);
124 }
125
126 // When "_Start" is unsigned integer like and x >= y.
127 {
128 std::ranges::iota_view<unsigned> io(0);
129 auto iter1 = std::next(io.begin(), 10);
130 auto iter2 = std::next(io.begin(), 5);
131 assert(iter1 - iter2 == 5);
132
133 LIBCPP_STATIC_ASSERT(std::same_as<decltype(iter1 - iter2), IntDiffT>);
134 }
135 {
136 std::ranges::iota_view<unsigned> io(0);
137 auto iter1 = std::next(io.begin(), 10);
138 auto iter2 = std::next(io.begin(), 10);
139 assert(iter1 - iter2 == 0);
140
141 LIBCPP_STATIC_ASSERT(std::same_as<decltype(iter1 - iter2), IntDiffT>);
142 }
143
144 // When "_Start" is not integer like.
145 {
146 std::ranges::iota_view io(SomeInt(0));
147 auto iter1 = std::next(io.begin(), 10);
148 auto iter2 = std::next(io.begin(), 5);
149 assert(iter1 - iter2 == 5);
150
151 static_assert(std::same_as<decltype(iter1 - iter2), int>);
152 }
153 {
154 std::ranges::iota_view io(SomeInt(0));
155 auto iter1 = std::next(io.begin(), 10);
156 auto iter2 = std::next(io.begin(), 10);
157 assert(iter1 - iter2 == 0);
158
159 static_assert(std::same_as<decltype(iter1 - iter2), int>);
160 }
161 {
162 std::ranges::iota_view io(SomeInt(0));
163 auto iter1 = std::next(io.begin(), 5);
164 auto iter2 = std::next(io.begin(), 10);
165 assert(iter1 - iter2 == -5);
166
167 static_assert(std::same_as<decltype(iter1 - iter2), int>);
168 }
169 }
170
171 return true;
172}
173
174int main(int, char**) {
175 test();
176 static_assert(test());
177
178 return 0;
179}
180

source code of libcxx/test/std/ranges/range.factories/range.iota.view/iterator/minus.pass.cpp