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, c++20
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 <utility>
17
18 #include "MoveOnly.h"
19
20 struct SimpleView : std::ranges::view_base {
21 int i;
22 int* begin() const;
23 int* end() const;
24 };
25
26 struct MoveOnlyView : SimpleView {
27 MoveOnly m;
28 };
29
30 template <class T>
31 concept HasBase = requires(T&& t) { std::forward<T>(t).base(); };
32
33 static_assert(HasBase<std::ranges::as_rvalue_view<SimpleView> const&>);
34 static_assert(HasBase<std::ranges::as_rvalue_view<SimpleView>&&>);
35
36 static_assert(!HasBase<std::ranges::as_rvalue_view<MoveOnlyView> const&>);
37 static_assert(HasBase<std::ranges::as_rvalue_view<MoveOnlyView>&&>);
38
test()39 constexpr bool test() {
40 { // const &
41 const std::ranges::as_rvalue_view<SimpleView> view(SimpleView{{}, 5});
42 std::same_as<SimpleView> decltype(auto) v = view.base();
43 assert(v.i == 5);
44 }
45
46 { // &
47 std::ranges::as_rvalue_view<SimpleView> view(SimpleView{{}, 5});
48 std::same_as<SimpleView> decltype(auto) v = view.base();
49 assert(v.i == 5);
50 }
51
52 { // &&
53 std::ranges::as_rvalue_view<SimpleView> view(SimpleView{{}, 5});
54 std::same_as<SimpleView> decltype(auto) v = std::move(view).base();
55 assert(v.i == 5);
56 }
57
58 { // const &&
59 const std::ranges::as_rvalue_view<SimpleView> view(SimpleView{{}, 5});
60 std::same_as<SimpleView> decltype(auto) v = std::move(view).base();
61 assert(v.i == 5);
62 }
63
64 { // move only
65 std::ranges::as_rvalue_view<MoveOnlyView> view(MoveOnlyView{{}, 5});
66 std::same_as<MoveOnlyView> decltype(auto) v = std::move(view).base();
67 assert(v.m.get() == 5);
68 }
69
70 return true;
71 }
72
main(int,char **)73 int main(int, char**) {
74 test();
75 static_assert(test());
76
77 return 0;
78 }
79