xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.transform/end.pass.cpp (revision d2baefae6846765eef6a6dd69d4fdf1082ce29ad)
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 // constexpr sentinel<false> end();
13 // constexpr iterator<false> end() requires common_range<V>;
14 // constexpr sentinel<true> end() const
15 //   requires range<const V> &&
16 //            regular_invocable<const F&, range_reference_t<const V>>;
17 // constexpr iterator<true> end() const
18 //   requires common_range<const V> &&
19 //            regular_invocable<const F&, range_reference_t<const V>>;
20 
21 #include <ranges>
22 
23 #include "test_macros.h"
24 #include "types.h"
25 
26 template<class T>
27 concept HasConstQualifiedEnd = requires(const T& t) { t.end(); };
28 
29 constexpr bool test() {
30   {
31     using TransformView = std::ranges::transform_view<ForwardView, PlusOneMutable>;
32     static_assert(std::ranges::common_range<TransformView>);
33     TransformView tv;
34     auto it = tv.end();
35     using It = decltype(it);
36     ASSERT_SAME_TYPE(decltype(static_cast<It&>(it).base()), const forward_iterator<int*>&);
37     ASSERT_SAME_TYPE(decltype(static_cast<It&&>(it).base()), forward_iterator<int*>);
38     ASSERT_SAME_TYPE(decltype(static_cast<const It&>(it).base()), const forward_iterator<int*>&);
39     ASSERT_SAME_TYPE(decltype(static_cast<const It&&>(it).base()), const forward_iterator<int*>&);
40     assert(base(it.base()) == globalBuff + 8);
41     assert(base(std::move(it).base()) == globalBuff + 8);
42     static_assert(!HasConstQualifiedEnd<TransformView>);
43   }
44   {
45     using TransformView = std::ranges::transform_view<InputView, PlusOneMutable>;
46     static_assert(!std::ranges::common_range<TransformView>);
47     TransformView tv;
48     auto sent = tv.end();
49     using Sent = decltype(sent);
50     ASSERT_SAME_TYPE(decltype(static_cast<Sent&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
51     ASSERT_SAME_TYPE(decltype(static_cast<Sent&&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
52     ASSERT_SAME_TYPE(decltype(static_cast<const Sent&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
53     ASSERT_SAME_TYPE(decltype(static_cast<const Sent&&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
54     assert(base(base(sent.base())) == globalBuff + 8);
55     assert(base(base(std::move(sent).base())) == globalBuff + 8);
56     static_assert(!HasConstQualifiedEnd<TransformView>);
57   }
58   {
59     using TransformView = std::ranges::transform_view<InputView, PlusOne>;
60     static_assert(!std::ranges::common_range<TransformView>);
61     TransformView tv;
62     auto sent = tv.end();
63     using Sent = decltype(sent);
64     ASSERT_SAME_TYPE(decltype(static_cast<Sent&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
65     ASSERT_SAME_TYPE(decltype(static_cast<Sent&&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
66     ASSERT_SAME_TYPE(decltype(static_cast<const Sent&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
67     ASSERT_SAME_TYPE(decltype(static_cast<const Sent&&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
68     assert(base(base(sent.base())) == globalBuff + 8);
69     assert(base(base(std::move(sent).base())) == globalBuff + 8);
70 
71     auto csent = std::as_const(tv).end();
72     using CSent = decltype(csent);
73     ASSERT_SAME_TYPE(decltype(static_cast<CSent&>(csent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
74     ASSERT_SAME_TYPE(decltype(static_cast<CSent&&>(csent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
75     ASSERT_SAME_TYPE(decltype(static_cast<const CSent&>(csent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
76     ASSERT_SAME_TYPE(decltype(static_cast<const CSent&&>(csent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
77     assert(base(base(csent.base())) == globalBuff + 8);
78     assert(base(base(std::move(csent).base())) == globalBuff + 8);
79   }
80   {
81     using TransformView = std::ranges::transform_view<MoveOnlyView, PlusOneMutable>;
82     static_assert(std::ranges::common_range<TransformView>);
83     TransformView tv;
84     auto it = tv.end();
85     using It = decltype(it);
86     ASSERT_SAME_TYPE(decltype(static_cast<It&>(it).base()), int* const&);
87     ASSERT_SAME_TYPE(decltype(static_cast<It&&>(it).base()), int*);
88     ASSERT_SAME_TYPE(decltype(static_cast<const It&>(it).base()), int* const&);
89     ASSERT_SAME_TYPE(decltype(static_cast<const It&&>(it).base()), int* const&);
90     assert(base(it.base()) == globalBuff + 8);
91     assert(base(std::move(it).base()) == globalBuff + 8);
92     static_assert(!HasConstQualifiedEnd<TransformView>);
93   }
94   {
95     using TransformView = std::ranges::transform_view<MoveOnlyView, PlusOne>;
96     static_assert(std::ranges::common_range<TransformView>);
97     TransformView tv;
98     auto it = tv.end();
99     using It = decltype(it);
100     ASSERT_SAME_TYPE(decltype(static_cast<It&>(it).base()), int* const&);
101     ASSERT_SAME_TYPE(decltype(static_cast<It&&>(it).base()), int*);
102     ASSERT_SAME_TYPE(decltype(static_cast<const It&>(it).base()), int* const&);
103     ASSERT_SAME_TYPE(decltype(static_cast<const It&&>(it).base()), int* const&);
104     assert(base(it.base()) == globalBuff + 8);
105     assert(base(std::move(it).base()) == globalBuff + 8);
106 
107     auto csent = std::as_const(tv).end();
108     using CSent = decltype(csent);
109     ASSERT_SAME_TYPE(decltype(static_cast<CSent&>(csent).base()), int* const&);
110     ASSERT_SAME_TYPE(decltype(static_cast<CSent&&>(csent).base()), int*);
111     ASSERT_SAME_TYPE(decltype(static_cast<const CSent&>(csent).base()), int* const&);
112     ASSERT_SAME_TYPE(decltype(static_cast<const CSent&&>(csent).base()), int* const&);
113     assert(base(base(csent.base())) == globalBuff + 8);
114     assert(base(base(std::move(csent).base())) == globalBuff + 8);
115   }
116   return true;
117 }
118 
119 int main(int, char**) {
120   test();
121   static_assert(test());
122 
123   return 0;
124 }
125