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