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 | #include "test_macros.h" |
12 | |
13 | TEST_CLANG_DIAGNOSTIC_IGNORED("-Wsign-compare" ) |
14 | TEST_GCC_DIAGNOSTIC_IGNORED("-Wsign-compare" ) |
15 | TEST_MSVC_DIAGNOSTIC_IGNORED(4018 4389) // various "signed/unsigned mismatch" |
16 | |
17 | // constexpr iota_view(type_identity_t<W> value, type_identity_t<Bound> bound); // explicit since C++23 |
18 | |
19 | #include <ranges> |
20 | #include <cassert> |
21 | |
22 | #include "test_convertible.h" |
23 | #include "types.h" |
24 | |
25 | // SFINAE tests. |
26 | |
27 | #if TEST_STD_VER >= 23 |
28 | |
29 | static_assert(!test_convertible<std::ranges::iota_view<SomeInt, SomeInt>, |
30 | decltype(std::ranges::iota_view<SomeInt, SomeInt>{}.begin()), |
31 | decltype(std::ranges::iota_view<SomeInt, SomeInt>{}.end())>(), |
32 | "This constructor must be explicit" ); |
33 | |
34 | static_assert(!test_convertible<std::ranges::iota_view<SomeInt>, |
35 | decltype(std::ranges::iota_view<SomeInt>{}.begin()), |
36 | decltype(std::unreachable_sentinel)>(), |
37 | "This constructor must be explicit" ); |
38 | |
39 | static_assert(!test_convertible<std::ranges::iota_view<SomeInt, IntComparableWith<SomeInt>>, |
40 | decltype(std::ranges::iota_view{SomeInt(0), IntComparableWith(SomeInt(10))}.begin()), |
41 | decltype(std::ranges::iota_view{SomeInt(0), IntComparableWith(SomeInt(10))}.end())>(), |
42 | "This constructor must be explicit" ); |
43 | |
44 | #else |
45 | |
46 | static_assert( test_convertible<std::ranges::iota_view<SomeInt, SomeInt>, |
47 | decltype(std::ranges::iota_view<SomeInt, SomeInt>{}.begin()), |
48 | decltype(std::ranges::iota_view<SomeInt, SomeInt>{}.end())>(), |
49 | "This constructor must not be explicit" ); |
50 | |
51 | static_assert( test_convertible<std::ranges::iota_view<SomeInt>, |
52 | decltype(std::ranges::iota_view<SomeInt>{}.begin()), |
53 | decltype(std::unreachable_sentinel)>(), |
54 | "This constructor must not be explicit" ); |
55 | |
56 | static_assert( test_convertible<std::ranges::iota_view<SomeInt, IntComparableWith<SomeInt>>, |
57 | decltype(std::ranges::iota_view{SomeInt(0), IntComparableWith(SomeInt(10))}.begin()), |
58 | decltype(std::ranges::iota_view{SomeInt(0), IntComparableWith(SomeInt(10))}.end())>(), |
59 | "This constructor must not be explicit" ); |
60 | |
61 | #endif // TEST_STD_VER >= 23 |
62 | |
63 | constexpr bool test() { |
64 | { |
65 | std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(0), SomeInt(10)); |
66 | assert(std::ranges::next(io.begin(), 10) == io.end()); |
67 | } |
68 | |
69 | { |
70 | std::ranges::iota_view<SomeInt> io(SomeInt(0), std::unreachable_sentinel); |
71 | assert(std::ranges::next(io.begin(), 10) != io.end()); |
72 | } |
73 | |
74 | { |
75 | std::ranges::iota_view<SomeInt, IntComparableWith<SomeInt>> io(SomeInt(0), IntComparableWith(SomeInt(10))); |
76 | assert(std::ranges::next(io.begin(), 10) == io.end()); |
77 | } |
78 | |
79 | { |
80 | // This is allowed only when using the constructor (not the deduction guide). |
81 | std::ranges::iota_view<int, unsigned> signedUnsigned(0, 10); |
82 | assert(std::ranges::next(signedUnsigned.begin(), 10) == signedUnsigned.end()); |
83 | } |
84 | |
85 | { |
86 | // This is allowed only when using the constructor (not the deduction guide). |
87 | std::ranges::iota_view<unsigned, int> signedUnsigned(0, 10); |
88 | assert(std::ranges::next(signedUnsigned.begin(), 10) == signedUnsigned.end()); |
89 | } |
90 | |
91 | return true; |
92 | } |
93 | |
94 | int main(int, char**) { |
95 | test(); |
96 | static_assert(test()); |
97 | |
98 | return 0; |
99 | } |
100 | |