xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.elements/base.pass.cpp (revision 94461822c75d5080bf648f86552f7a59b76905c9)
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 V base() const & requires copy_constructible<V> { return base_; }
12 // constexpr V base() && { return std::move(base_); }
13 
14 #include <cassert>
15 #include <ranges>
16 #include <tuple>
17 #include <type_traits>
18 #include <utility>
19 
20 #include "MoveOnly.h"
21 
22 struct View : std::ranges::view_base {
23   int i;
24   std::tuple<int>* begin() const;
25   std::tuple<int>* end() const;
26 };
27 
28 struct MoveOnlyView : View {
29   MoveOnly mo;
30 };
31 
32 template <class T>
33 concept HasBase = requires(T&& t) { std::forward<T>(t).base(); };
34 
35 static_assert(HasBase<std::ranges::elements_view<View, 0> const&>);
36 static_assert(HasBase<std::ranges::elements_view<View, 0>&&>);
37 
38 static_assert(!HasBase<std::ranges::elements_view<MoveOnlyView, 0> const&>);
39 static_assert(HasBase<std::ranges::elements_view<MoveOnlyView, 0>&&>);
40 
test()41 constexpr bool test() {
42   // const &
43   {
44     const std::ranges::elements_view<View, 0> ev{View{{}, 5}};
45     std::same_as<View> decltype(auto) v = ev.base();
46     assert(v.i == 5);
47   }
48 
49   // &
50   {
51     std::ranges::elements_view<View, 0> ev{View{{}, 5}};
52     std::same_as<View> decltype(auto) v = ev.base();
53     assert(v.i == 5);
54   }
55 
56   // &&
57   {
58     std::ranges::elements_view<View, 0> ev{View{{}, 5}};
59     std::same_as<View> decltype(auto) v = std::move(ev).base();
60     assert(v.i == 5);
61   }
62 
63   // const &&
64   {
65     const std::ranges::elements_view<View, 0> ev{View{{}, 5}};
66     std::same_as<View> decltype(auto) v = std::move(ev).base();
67     assert(v.i == 5);
68   }
69 
70   // move only
71   {
72     std::ranges::elements_view<MoveOnlyView, 0> ev{MoveOnlyView{{}, 5}};
73     std::same_as<MoveOnlyView> decltype(auto) v = std::move(ev).base();
74     assert(v.mo.get() == 5);
75   }
76 
77   return true;
78 }
79 
main(int,char **)80 int main(int, char**) {
81   test();
82   static_assert(test());
83   return 0;
84 }
85