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 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
11
12 // template<range R>
13 // constexpr range_difference_t<R> ranges::distance(R&& r);
14
15 #include <iterator>
16 #include <cassert>
17 #include <ranges>
18
19 #include "test_iterators.h"
20 #include "test_macros.h"
21
22 template<class It, class Sent>
test_ordinary()23 constexpr void test_ordinary() {
24 struct R {
25 mutable int a[3] = {1, 2, 3};
26 constexpr It begin() const { return It(a); }
27 constexpr Sent end() const { return Sent(It(a + 3)); }
28 };
29 R r;
30 assert(std::ranges::distance(r) == 3);
31 assert(std::ranges::distance(static_cast<R&&>(r)) == 3);
32 assert(std::ranges::distance(static_cast<const R&>(r)) == 3);
33 assert(std::ranges::distance(static_cast<const R&&>(r)) == 3);
34 ASSERT_SAME_TYPE(decltype(std::ranges::distance(r)), std::ranges::range_difference_t<R>);
35 }
36
test()37 constexpr bool test() {
38 {
39 using R = int[3];
40 int a[] = {1, 2, 3};
41 assert(std::ranges::distance(static_cast<R&>(a)) == 3);
42 assert(std::ranges::distance(static_cast<R&&>(a)) == 3);
43 assert(std::ranges::distance(static_cast<const R&>(a)) == 3);
44 assert(std::ranges::distance(static_cast<const R&&>(a)) == 3);
45 ASSERT_SAME_TYPE(decltype(std::ranges::distance(a)), std::ptrdiff_t);
46 ASSERT_SAME_TYPE(decltype(std::ranges::distance(a)), std::ranges::range_difference_t<R>);
47 }
48 {
49 // Unsized range, non-copyable iterator type, rvalue-ref-qualified begin()
50 using It = cpp20_input_iterator<int*>;
51 using Sent = sentinel_wrapper<cpp20_input_iterator<int*>>;
52 using R = std::ranges::subrange<It, Sent, std::ranges::subrange_kind::unsized>;
53
54 int a[] = {1, 2, 3};
55 auto r = R(It(a), Sent(It(a + 3)));
56 assert(std::ranges::distance(r) == 3);
57 assert(std::ranges::distance(static_cast<R&&>(r)) == 3);
58 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), const R&>);
59 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), const R&&>);
60 }
61 {
62 // Sized range (unsized sentinel type), non-copyable iterator type, rvalue-ref-qualified begin()
63 using It = cpp20_input_iterator<int*>;
64 using Sent = sentinel_wrapper<cpp20_input_iterator<int*>>;
65 using R = std::ranges::subrange<It, Sent, std::ranges::subrange_kind::sized>;
66
67 int a[] = {1, 2, 3};
68 auto r = R(It(a), Sent(It(a + 3)), 3);
69 assert(std::ranges::distance(r) == 3);
70 assert(std::ranges::distance(static_cast<R&&>(r)) == 3);
71 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), const R&>);
72 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), const R&&>);
73 }
74 {
75 // Sized range (sized sentinel type), non-copyable iterator type
76 test_ordinary<cpp20_input_iterator<int*>, sized_sentinel<cpp20_input_iterator<int*>>>();
77 }
78 test_ordinary<cpp17_input_iterator<int*>, sentinel_wrapper<cpp17_input_iterator<int*>>>();
79 test_ordinary<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>();
80 test_ordinary<cpp17_output_iterator<int*>, sentinel_wrapper<cpp17_output_iterator<int*>>>();
81 test_ordinary<forward_iterator<int*>, sentinel_wrapper<forward_iterator<int*>>>();
82 test_ordinary<bidirectional_iterator<int*>, sentinel_wrapper<bidirectional_iterator<int*>>>();
83 test_ordinary<random_access_iterator<int*>, sentinel_wrapper<random_access_iterator<int*>>>();
84 test_ordinary<contiguous_iterator<int*>, sentinel_wrapper<contiguous_iterator<int*>>>();
85 test_ordinary<int*, sentinel_wrapper<int*>>();
86
87 test_ordinary<cpp17_input_iterator<int*>, sized_sentinel<cpp17_input_iterator<int*>>>();
88 test_ordinary<cpp20_input_iterator<int*>, sized_sentinel<cpp20_input_iterator<int*>>>();
89 test_ordinary<cpp17_output_iterator<int*>, sized_sentinel<cpp17_output_iterator<int*>>>();
90 test_ordinary<forward_iterator<int*>, sized_sentinel<forward_iterator<int*>>>();
91 test_ordinary<bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>();
92 test_ordinary<random_access_iterator<int*>, sized_sentinel<random_access_iterator<int*>>>();
93 test_ordinary<contiguous_iterator<int*>, sized_sentinel<contiguous_iterator<int*>>>();
94 test_ordinary<int*, sized_sentinel<int*>>();
95 test_ordinary<int*, int*>();
96
97 // Calling it on a non-range isn't allowed.
98 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), int>);
99 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), int*>);
100
101 return true;
102 }
103
main(int,char **)104 int main(int, char**) {
105 test();
106 static_assert(test());
107
108 return 0;
109 }
110