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 // class std::ranges::subrange;
13 
14 #include <cassert>
15 #include <ranges>
16 #include <utility>
17 
18 #include "test_macros.h"
19 
test_sized_subrange()20 constexpr void test_sized_subrange()
21 {
22     int a[4] = {1,2,3,4};
23     auto r = std::ranges::subrange(a, a+4);
24     assert(std::ranges::sized_range<decltype(r)>);
25     {
26         auto [first, last] = r;
27         assert(first == a);
28         assert(last == a+4);
29     }
30     {
31         auto [first, last] = std::move(r);
32         assert(first == a);
33         assert(last == a+4);
34     }
35     {
36         auto [first, last] = std::as_const(r);
37         assert(first == a);
38         assert(last == a+4);
39     }
40     {
41         auto [first, last] = std::move(std::as_const(r));
42         assert(first == a);
43         assert(last == a+4);
44     }
45 }
46 
test_unsized_subrange()47 constexpr void test_unsized_subrange()
48 {
49     int a[4] = {1,2,3,4};
50     auto r = std::ranges::subrange(a, std::unreachable_sentinel);
51     assert(!std::ranges::sized_range<decltype(r)>);
52     {
53         auto [first, last] = r;
54         assert(first == a);
55         ASSERT_SAME_TYPE(decltype(last), std::unreachable_sentinel_t);
56     }
57     {
58         auto [first, last] = std::move(r);
59         assert(first == a);
60         ASSERT_SAME_TYPE(decltype(last), std::unreachable_sentinel_t);
61     }
62     {
63         auto [first, last] = std::as_const(r);
64         assert(first == a);
65         ASSERT_SAME_TYPE(decltype(last), std::unreachable_sentinel_t);
66     }
67     {
68         auto [first, last] = std::move(std::as_const(r));
69         assert(first == a);
70         ASSERT_SAME_TYPE(decltype(last), std::unreachable_sentinel_t);
71     }
72 }
73 
test_copies_not_originals()74 constexpr void test_copies_not_originals()
75 {
76     int a[4] = {1,2,3,4};
77     {
78         auto r = std::ranges::subrange(a, a+4);
79         auto&& [first, last] = r;
80         ASSERT_SAME_TYPE(decltype(first), int*);
81         ASSERT_SAME_TYPE(decltype(last), int*);
82         first = a+2;
83         last = a+2;
84         assert(r.begin() == a);
85         assert(r.end() == a+4);
86     }
87     {
88         const auto r = std::ranges::subrange(a, a+4);
89         auto&& [first, last] = r;
90         ASSERT_SAME_TYPE(decltype(first), int*);
91         ASSERT_SAME_TYPE(decltype(last), int*);
92         first = a+2;
93         last = a+2;
94         assert(r.begin() == a);
95         assert(r.end() == a+4);
96     }
97 }
98 
test()99 constexpr bool test()
100 {
101     test_sized_subrange();
102     test_unsized_subrange();
103     test_copies_not_originals();
104     return true;
105 }
106 
main(int,char **)107 int main(int, char**)
108 {
109     test();
110     static_assert(test());
111 
112     return 0;
113 }
114