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