xref: /llvm-project/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/minus.pass.cpp (revision 0a4aa8a122aa097499c498b639a75b5e9a73e9f0)
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)
26 using IntDiffT = long long;
27 #else
28 using IntDiffT = long;
29 #endif
30 
test()31 constexpr 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 
main(int,char **)174 int main(int, char**) {
175   test();
176   static_assert(test());
177 
178   return 0;
179 }
180