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 const iterator_t<Base>& inner-iterator::base() const& noexcept; 13 // 14 // constexpr iterator_t<Base> inner-iterator::base() && 15 // requires forward_range<View>; 16 17 #include <ranges> 18 19 #include <concepts> 20 #include <utility> 21 #include "../types.h" 22 23 static_assert( noexcept(std::declval<InnerIterForward&>().base())); 24 static_assert( noexcept(std::declval<InnerIterForward const &>().base())); 25 static_assert( noexcept(std::declval<InnerIterForward const &&>().base())); 26 static_assert( noexcept(std::declval<InnerIterInput&>().base())); 27 static_assert( noexcept(std::declval<InnerIterInput const &>().base())); 28 static_assert( noexcept(std::declval<InnerIterInput const &&>().base())); 29 30 constexpr bool test() { 31 // `base` works with a forward view (two different overloads based on ref-qualification of the `inner-iterator`). 32 { 33 using BaseIter = std::ranges::iterator_t<CopyableView>; 34 CopyableView input("abc def"); 35 std::ranges::lazy_split_view<CopyableView, ForwardView> v(input, " "); 36 auto i = (*v.begin()).begin(); 37 const auto ci = i; 38 39 // Note: some macOS platforms seem to have trouble deducing the type when using `std::same_as` -- use the equivalent 40 // `ASSERT_SAME_TYPE` instead. 41 { 42 decltype(auto) b = i.base(); 43 ASSERT_SAME_TYPE(decltype(b), const BaseIter&); 44 assert(b == input.begin()); 45 } 46 47 { 48 decltype(auto) b = ci.base(); 49 ASSERT_SAME_TYPE(decltype(b), const BaseIter&); 50 assert(b == input.begin()); 51 } 52 53 { 54 decltype(auto) b = std::move(i).base(); 55 ASSERT_SAME_TYPE(decltype(b), BaseIter); 56 assert(b == input.begin()); 57 } 58 59 { 60 decltype(auto) b = std::move(ci).base(); 61 ASSERT_SAME_TYPE(decltype(b), const BaseIter&); 62 assert(b == input.begin()); 63 } 64 } 65 66 // `base` works with an input view (no overloads). 67 { 68 using BaseIter = std::ranges::iterator_t<InputView>; 69 InputView input("abc def"); 70 std::ranges::lazy_split_view<InputView, ForwardTinyView> v(input, ' '); 71 auto i = (*v.begin()).begin(); 72 const auto ci = i; 73 74 { 75 decltype(auto) b = i.base(); 76 ASSERT_SAME_TYPE(decltype(b), const BaseIter&); 77 } 78 79 { 80 decltype(auto) b = ci.base(); 81 ASSERT_SAME_TYPE(decltype(b), const BaseIter&); 82 } 83 84 { 85 decltype(auto) b = std::move(i).base(); 86 ASSERT_SAME_TYPE(decltype(b), const BaseIter&); 87 } 88 89 { 90 decltype(auto) b = std::move(ci).base(); 91 ASSERT_SAME_TYPE(decltype(b), const BaseIter&); 92 } 93 } 94 95 return true; 96 } 97 98 int main(int, char**) { 99 test(); 100 static_assert(test()); 101 102 return 0; 103 } 104