10e09a41bSzoecarver //===----------------------------------------------------------------------===//
20e09a41bSzoecarver //
30e09a41bSzoecarver // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40e09a41bSzoecarver // See https://llvm.org/LICENSE.txt for license information.
50e09a41bSzoecarver // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60e09a41bSzoecarver //
70e09a41bSzoecarver //===----------------------------------------------------------------------===//
80e09a41bSzoecarver
90e09a41bSzoecarver // UNSUPPORTED: c++03, c++11, c++14, c++17
100e09a41bSzoecarver
110e09a41bSzoecarver // constexpr sentinel<false> end();
120e09a41bSzoecarver // constexpr iterator<false> end() requires common_range<V>;
130e09a41bSzoecarver // constexpr sentinel<true> end() const
140e09a41bSzoecarver // requires range<const V> &&
150e09a41bSzoecarver // regular_invocable<const F&, range_reference_t<const V>>;
160e09a41bSzoecarver // constexpr iterator<true> end() const
170e09a41bSzoecarver // requires common_range<const V> &&
180e09a41bSzoecarver // regular_invocable<const F&, range_reference_t<const V>>;
190e09a41bSzoecarver
200e09a41bSzoecarver #include <ranges>
210e09a41bSzoecarver
220e09a41bSzoecarver #include "test_macros.h"
230e09a41bSzoecarver #include "types.h"
240e09a41bSzoecarver
250e09a41bSzoecarver template<class T>
261fe897dfSArthur O'Dwyer concept HasConstQualifiedEnd = requires(const T& t) { t.end(); };
270e09a41bSzoecarver
test()280e09a41bSzoecarver constexpr bool test() {
290e09a41bSzoecarver {
301fe897dfSArthur O'Dwyer using TransformView = std::ranges::transform_view<ForwardView, PlusOneMutable>;
311fe897dfSArthur O'Dwyer static_assert(std::ranges::common_range<TransformView>);
321fe897dfSArthur O'Dwyer TransformView tv;
33*4b3e0d2aSArthur O'Dwyer auto it = tv.end();
34*4b3e0d2aSArthur O'Dwyer using It = decltype(it);
35*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<It&>(it).base()), const forward_iterator<int*>&);
36*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<It&&>(it).base()), forward_iterator<int*>);
37*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const It&>(it).base()), const forward_iterator<int*>&);
38*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const It&&>(it).base()), const forward_iterator<int*>&);
39*4b3e0d2aSArthur O'Dwyer assert(base(it.base()) == globalBuff + 8);
40*4b3e0d2aSArthur O'Dwyer assert(base(std::move(it).base()) == globalBuff + 8);
411fe897dfSArthur O'Dwyer static_assert(!HasConstQualifiedEnd<TransformView>);
420e09a41bSzoecarver }
430e09a41bSzoecarver {
441fe897dfSArthur O'Dwyer using TransformView = std::ranges::transform_view<InputView, PlusOneMutable>;
451fe897dfSArthur O'Dwyer static_assert(!std::ranges::common_range<TransformView>);
461fe897dfSArthur O'Dwyer TransformView tv;
47*4b3e0d2aSArthur O'Dwyer auto sent = tv.end();
48*4b3e0d2aSArthur O'Dwyer using Sent = decltype(sent);
49*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<Sent&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
50*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<Sent&&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
51*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const Sent&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
52*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const Sent&&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
53*4b3e0d2aSArthur O'Dwyer assert(base(base(sent.base())) == globalBuff + 8);
54*4b3e0d2aSArthur O'Dwyer assert(base(base(std::move(sent).base())) == globalBuff + 8);
551fe897dfSArthur O'Dwyer static_assert(!HasConstQualifiedEnd<TransformView>);
560e09a41bSzoecarver }
570e09a41bSzoecarver {
581fe897dfSArthur O'Dwyer using TransformView = std::ranges::transform_view<InputView, PlusOne>;
591fe897dfSArthur O'Dwyer static_assert(!std::ranges::common_range<TransformView>);
601fe897dfSArthur O'Dwyer TransformView tv;
61*4b3e0d2aSArthur O'Dwyer auto sent = tv.end();
62*4b3e0d2aSArthur O'Dwyer using Sent = decltype(sent);
63*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<Sent&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
64*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<Sent&&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
65*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const Sent&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
66*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const Sent&&>(sent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
67*4b3e0d2aSArthur O'Dwyer assert(base(base(sent.base())) == globalBuff + 8);
68*4b3e0d2aSArthur O'Dwyer assert(base(base(std::move(sent).base())) == globalBuff + 8);
69*4b3e0d2aSArthur O'Dwyer
70*4b3e0d2aSArthur O'Dwyer auto csent = std::as_const(tv).end();
71*4b3e0d2aSArthur O'Dwyer using CSent = decltype(csent);
72*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<CSent&>(csent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
73*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<CSent&&>(csent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
74*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const CSent&>(csent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
75*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const CSent&&>(csent).base()), sentinel_wrapper<cpp20_input_iterator<int*>>);
76*4b3e0d2aSArthur O'Dwyer assert(base(base(csent.base())) == globalBuff + 8);
77*4b3e0d2aSArthur O'Dwyer assert(base(base(std::move(csent).base())) == globalBuff + 8);
780e09a41bSzoecarver }
790e09a41bSzoecarver {
801fe897dfSArthur O'Dwyer using TransformView = std::ranges::transform_view<MoveOnlyView, PlusOneMutable>;
811fe897dfSArthur O'Dwyer static_assert(std::ranges::common_range<TransformView>);
821fe897dfSArthur O'Dwyer TransformView tv;
83*4b3e0d2aSArthur O'Dwyer auto it = tv.end();
84*4b3e0d2aSArthur O'Dwyer using It = decltype(it);
85*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<It&>(it).base()), int* const&);
86*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<It&&>(it).base()), int*);
87*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const It&>(it).base()), int* const&);
88*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const It&&>(it).base()), int* const&);
89*4b3e0d2aSArthur O'Dwyer assert(base(it.base()) == globalBuff + 8);
90*4b3e0d2aSArthur O'Dwyer assert(base(std::move(it).base()) == globalBuff + 8);
911fe897dfSArthur O'Dwyer static_assert(!HasConstQualifiedEnd<TransformView>);
920e09a41bSzoecarver }
931fe897dfSArthur O'Dwyer {
941fe897dfSArthur O'Dwyer using TransformView = std::ranges::transform_view<MoveOnlyView, PlusOne>;
951fe897dfSArthur O'Dwyer static_assert(std::ranges::common_range<TransformView>);
961fe897dfSArthur O'Dwyer TransformView tv;
97*4b3e0d2aSArthur O'Dwyer auto it = tv.end();
98*4b3e0d2aSArthur O'Dwyer using It = decltype(it);
99*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<It&>(it).base()), int* const&);
100*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<It&&>(it).base()), int*);
101*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const It&>(it).base()), int* const&);
102*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const It&&>(it).base()), int* const&);
103*4b3e0d2aSArthur O'Dwyer assert(base(it.base()) == globalBuff + 8);
104*4b3e0d2aSArthur O'Dwyer assert(base(std::move(it).base()) == globalBuff + 8);
105*4b3e0d2aSArthur O'Dwyer
106*4b3e0d2aSArthur O'Dwyer auto csent = std::as_const(tv).end();
107*4b3e0d2aSArthur O'Dwyer using CSent = decltype(csent);
108*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<CSent&>(csent).base()), int* const&);
109*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<CSent&&>(csent).base()), int*);
110*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const CSent&>(csent).base()), int* const&);
111*4b3e0d2aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(static_cast<const CSent&&>(csent).base()), int* const&);
112*4b3e0d2aSArthur O'Dwyer assert(base(base(csent.base())) == globalBuff + 8);
113*4b3e0d2aSArthur O'Dwyer assert(base(base(std::move(csent).base())) == globalBuff + 8);
1141fe897dfSArthur O'Dwyer }
1150e09a41bSzoecarver return true;
1160e09a41bSzoecarver }
1170e09a41bSzoecarver
main(int,char **)1180e09a41bSzoecarver int main(int, char**) {
1190e09a41bSzoecarver test();
1200e09a41bSzoecarver static_assert(test());
1210e09a41bSzoecarver
1220e09a41bSzoecarver return 0;
1230e09a41bSzoecarver }
124