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