xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.elements/base.pass.cpp (revision 94461822c75d5080bf648f86552f7a59b76905c9)
1*94461822SHui Xie //===----------------------------------------------------------------------===//
2*94461822SHui Xie //
3*94461822SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*94461822SHui Xie // See https://llvm.org/LICENSE.txt for license information.
5*94461822SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*94461822SHui Xie //
7*94461822SHui Xie //===----------------------------------------------------------------------===//
8*94461822SHui Xie 
9*94461822SHui Xie // UNSUPPORTED: c++03, c++11, c++14, c++17
10*94461822SHui Xie 
11*94461822SHui Xie // constexpr V base() const & requires copy_constructible<V> { return base_; }
12*94461822SHui Xie // constexpr V base() && { return std::move(base_); }
13*94461822SHui Xie 
14*94461822SHui Xie #include <cassert>
15*94461822SHui Xie #include <ranges>
16*94461822SHui Xie #include <tuple>
17*94461822SHui Xie #include <type_traits>
18*94461822SHui Xie #include <utility>
19*94461822SHui Xie 
20*94461822SHui Xie #include "MoveOnly.h"
21*94461822SHui Xie 
22*94461822SHui Xie struct View : std::ranges::view_base {
23*94461822SHui Xie   int i;
24*94461822SHui Xie   std::tuple<int>* begin() const;
25*94461822SHui Xie   std::tuple<int>* end() const;
26*94461822SHui Xie };
27*94461822SHui Xie 
28*94461822SHui Xie struct MoveOnlyView : View {
29*94461822SHui Xie   MoveOnly mo;
30*94461822SHui Xie };
31*94461822SHui Xie 
32*94461822SHui Xie template <class T>
33*94461822SHui Xie concept HasBase = requires(T&& t) { std::forward<T>(t).base(); };
34*94461822SHui Xie 
35*94461822SHui Xie static_assert(HasBase<std::ranges::elements_view<View, 0> const&>);
36*94461822SHui Xie static_assert(HasBase<std::ranges::elements_view<View, 0>&&>);
37*94461822SHui Xie 
38*94461822SHui Xie static_assert(!HasBase<std::ranges::elements_view<MoveOnlyView, 0> const&>);
39*94461822SHui Xie static_assert(HasBase<std::ranges::elements_view<MoveOnlyView, 0>&&>);
40*94461822SHui Xie 
test()41*94461822SHui Xie constexpr bool test() {
42*94461822SHui Xie   // const &
43*94461822SHui Xie   {
44*94461822SHui Xie     const std::ranges::elements_view<View, 0> ev{View{{}, 5}};
45*94461822SHui Xie     std::same_as<View> decltype(auto) v = ev.base();
46*94461822SHui Xie     assert(v.i == 5);
47*94461822SHui Xie   }
48*94461822SHui Xie 
49*94461822SHui Xie   // &
50*94461822SHui Xie   {
51*94461822SHui Xie     std::ranges::elements_view<View, 0> ev{View{{}, 5}};
52*94461822SHui Xie     std::same_as<View> decltype(auto) v = ev.base();
53*94461822SHui Xie     assert(v.i == 5);
54*94461822SHui Xie   }
55*94461822SHui Xie 
56*94461822SHui Xie   // &&
57*94461822SHui Xie   {
58*94461822SHui Xie     std::ranges::elements_view<View, 0> ev{View{{}, 5}};
59*94461822SHui Xie     std::same_as<View> decltype(auto) v = std::move(ev).base();
60*94461822SHui Xie     assert(v.i == 5);
61*94461822SHui Xie   }
62*94461822SHui Xie 
63*94461822SHui Xie   // const &&
64*94461822SHui Xie   {
65*94461822SHui Xie     const std::ranges::elements_view<View, 0> ev{View{{}, 5}};
66*94461822SHui Xie     std::same_as<View> decltype(auto) v = std::move(ev).base();
67*94461822SHui Xie     assert(v.i == 5);
68*94461822SHui Xie   }
69*94461822SHui Xie 
70*94461822SHui Xie   // move only
71*94461822SHui Xie   {
72*94461822SHui Xie     std::ranges::elements_view<MoveOnlyView, 0> ev{MoveOnlyView{{}, 5}};
73*94461822SHui Xie     std::same_as<MoveOnlyView> decltype(auto) v = std::move(ev).base();
74*94461822SHui Xie     assert(v.mo.get() == 5);
75*94461822SHui Xie   }
76*94461822SHui Xie 
77*94461822SHui Xie   return true;
78*94461822SHui Xie }
79*94461822SHui Xie 
main(int,char **)80*94461822SHui Xie int main(int, char**) {
81*94461822SHui Xie   test();
82*94461822SHui Xie   static_assert(test());
83*94461822SHui Xie   return 0;
84*94461822SHui Xie }
85