xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp (revision 8b37ec1f7bda40c240f7bfda6737df5043860103)
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 // constexpr auto begin() requires (!simple-view<V>);
12 // constexpr auto begin() const requires range<const V>;
13 
14 #include <cassert>
15 #include <ranges>
16 #include <utility>
17 
18 #include "test_macros.h"
19 #include "test_iterators.h"
20 #include "test_range.h"
21 #include "types.h"
22 
23 struct NonCommonSimpleView : std::ranges::view_base {
24   int* begin() const;
25   sentinel_wrapper<int*> end() const;
sizeNonCommonSimpleView26   std::size_t size() { return 0; }  // deliberately non-const
27 };
28 static_assert(std::ranges::sized_range<NonCommonSimpleView>);
29 static_assert(!std::ranges::sized_range<const NonCommonSimpleView>);
30 
31 using CommonInputIterPtrConstInt        = common_input_iterator<const int*>;
32 using CountedCommonInputIterPtrConstInt = std::counted_iterator<CommonInputIterPtrConstInt>;
33 
test()34 constexpr bool test() {
35   int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
36 
37   // simple-view<V> && sized_range<V> && random_access_range<V>
38   {
39     using ViewTested = SizedRandomAccessView;
40     static_assert(simple_view<ViewTested>);
41     static_assert(std::ranges::sized_range<ViewTested>);
42     static_assert(std::ranges::random_access_range<ViewTested>);
43 
44     std::ranges::take_view<ViewTested> tv(ViewTested(buffer), 4);
45     assert(tv.begin() == ViewTested(buffer).begin());
46     ASSERT_SAME_TYPE(decltype(tv.begin()), RandomAccessIter);
47 
48     const std::ranges::take_view<ViewTested> ctv(ViewTested(buffer), 4);
49     assert(ctv.begin() == ViewTested(buffer).begin());
50     ASSERT_SAME_TYPE(decltype(ctv.begin()), RandomAccessIter);
51   }
52 
53   // simple-view<V> && sized_range<V> && !random_access_range<V>
54   {
55     using ViewTested = SizedForwardView;
56     static_assert(simple_view<ViewTested>);
57     static_assert(std::ranges::sized_range<ViewTested>);
58     static_assert(!std::ranges::random_access_range<ViewTested>);
59 
60     std::ranges::take_view<ViewTested> tv(ViewTested{buffer}, 16);                    // underlying size is 8
61     assert(tv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 8)); // expect min(8, 16)
62     ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<ForwardIter>);
63 
64     const std::ranges::take_view<ViewTested> ctv(ViewTested{buffer}, 4);
65     assert(ctv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 4));
66     ASSERT_SAME_TYPE(decltype(ctv.begin()), std::counted_iterator<ForwardIter>);
67   }
68 
69   // simple-view<V> && !sized_range<V>
70   {
71     using ViewTested = MoveOnlyView;
72     static_assert(simple_view<ViewTested>);
73     std::ranges::take_view<ViewTested> tv(ViewTested{buffer}, 4);
74     assert(tv.begin() == std::counted_iterator<int*>(buffer, 4));
75     ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);
76 
77     const std::ranges::take_view<ViewTested> ctv(ViewTested{buffer}, 4);
78     assert(ctv.begin() == std::counted_iterator<int*>(buffer, 4));
79     ASSERT_SAME_TYPE(decltype(ctv.begin()), std::counted_iterator<int*>);
80   }
81 
82   // simple-view<V> && sized_range<V> && !sized_range<const V>
83   {
84     using ViewTested = NonCommonSimpleView;
85     static_assert(simple_view<ViewTested>);
86     static_assert(std::ranges::sized_range<ViewTested>);
87     static_assert(!std::ranges::sized_range<const ViewTested>);
88 
89     std::ranges::take_view<ViewTested> tv{};
90     ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);
91     ASSERT_SAME_TYPE(decltype(std::as_const(tv).begin()), std::counted_iterator<int*>);
92   }
93 
94   //  !simple-view<V> && !sized_range<V>
95   {
96     using ViewTested = NonSimpleNonSizedView;
97     static_assert(!simple_view<ViewTested>);
98     static_assert(!std::ranges::sized_range<ViewTested>);
99 
100     std::ranges::take_view<ViewTested> tv{ViewTested{buffer, buffer + 2}, 4};
101     // The count for the counted iterator is the count of the take_view (i.e., 4)
102     assert(tv.begin() == CountedCommonInputIterPtrConstInt(CommonInputIterPtrConstInt(buffer), 4));
103     ASSERT_SAME_TYPE(decltype(tv.begin()), CountedCommonInputIterPtrConstInt);
104   }
105 
106   // !simple-view<V> && sized_range<V>
107   {
108     using ViewTested = NonSimpleSizedView;
109     static_assert(!simple_view<ViewTested>);
110     static_assert(std::ranges::sized_range<ViewTested>);
111 
112     std::ranges::take_view<ViewTested> tv{ViewTested{buffer, buffer + 2}, 4};
113     // The count for the counted iterator is the min(2, 4) (i.e., 2).
114     assert(tv.begin() == CountedCommonInputIterPtrConstInt(CommonInputIterPtrConstInt(buffer), 2));
115     ASSERT_SAME_TYPE(decltype(tv.begin()), CountedCommonInputIterPtrConstInt);
116   }
117 
118   // !simple-view<V> && sized_range<V> && random_access_range<V>
119   {
120     using ViewTested = NonSimpleSizedRandomView;
121     static_assert(!simple_view<ViewTested>);
122     static_assert(std::ranges::sized_range<ViewTested>);
123     static_assert(std::ranges::random_access_range<ViewTested>);
124 
125     std::ranges::take_view<ViewTested> tv{ViewTested{buffer, buffer + 2}, 4};
126     assert(tv.begin() == random_access_iterator<const int*>(buffer));
127     ASSERT_SAME_TYPE(decltype(tv.begin()), random_access_iterator<const int*>);
128   }
129   return true;
130 }
131 
main(int,char **)132 int main(int, char**) {
133   test();
134   static_assert(test());
135 
136   return 0;
137 }
138