1*d8fad661SChristopher Di Bella //===----------------------------------------------------------------------===//
2*d8fad661SChristopher Di Bella //
3*d8fad661SChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*d8fad661SChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information.
5*d8fad661SChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*d8fad661SChristopher Di Bella //
7*d8fad661SChristopher Di Bella //===----------------------------------------------------------------------===//
8*d8fad661SChristopher Di Bella 
9*d8fad661SChristopher Di Bella // UNSUPPORTED: c++03, c++11, c++14, c++17
10*d8fad661SChristopher Di Bella // UNSUPPORTED: libcpp-no-concepts
11*d8fad661SChristopher Di Bella 
12*d8fad661SChristopher Di Bella // <ranges>
13*d8fad661SChristopher Di Bella 
14*d8fad661SChristopher Di Bella // template<class T>
15*d8fad661SChristopher Di Bella // concept view = ...;
16*d8fad661SChristopher Di Bella 
17*d8fad661SChristopher Di Bella #include <ranges>
18*d8fad661SChristopher Di Bella 
19*d8fad661SChristopher Di Bella #include "test_macros.h"
20*d8fad661SChristopher Di Bella 
21*d8fad661SChristopher Di Bella // The type would be a view, but it's not moveable.
22*d8fad661SChristopher Di Bella struct NotMoveable : std::ranges::view_base {
23*d8fad661SChristopher Di Bella   NotMoveable() = default;
24*d8fad661SChristopher Di Bella   NotMoveable(NotMoveable&&) = delete;
25*d8fad661SChristopher Di Bella   NotMoveable& operator=(NotMoveable&&) = delete;
26*d8fad661SChristopher Di Bella   friend int* begin(NotMoveable&);
27*d8fad661SChristopher Di Bella   friend int* begin(NotMoveable const&);
28*d8fad661SChristopher Di Bella   friend int* end(NotMoveable&);
29*d8fad661SChristopher Di Bella   friend int* end(NotMoveable const&);
30*d8fad661SChristopher Di Bella };
31*d8fad661SChristopher Di Bella static_assert(std::ranges::range<NotMoveable>);
32*d8fad661SChristopher Di Bella static_assert(!std::movable<NotMoveable>);
33*d8fad661SChristopher Di Bella static_assert(std::default_initializable<NotMoveable>);
34*d8fad661SChristopher Di Bella static_assert(std::ranges::enable_view<NotMoveable>);
35*d8fad661SChristopher Di Bella static_assert(!std::ranges::view<NotMoveable>);
36*d8fad661SChristopher Di Bella 
37*d8fad661SChristopher Di Bella // The type would be a view, but it's not default initializable
38*d8fad661SChristopher Di Bella struct NotDefaultInit : std::ranges::view_base {
39*d8fad661SChristopher Di Bella   NotDefaultInit() = delete;
40*d8fad661SChristopher Di Bella   friend int* begin(NotDefaultInit&);
41*d8fad661SChristopher Di Bella   friend int* begin(NotDefaultInit const&);
42*d8fad661SChristopher Di Bella   friend int* end(NotDefaultInit&);
43*d8fad661SChristopher Di Bella   friend int* end(NotDefaultInit const&);
44*d8fad661SChristopher Di Bella };
45*d8fad661SChristopher Di Bella static_assert(std::ranges::range<NotDefaultInit>);
46*d8fad661SChristopher Di Bella static_assert(std::movable<NotDefaultInit>);
47*d8fad661SChristopher Di Bella static_assert(!std::default_initializable<NotDefaultInit>);
48*d8fad661SChristopher Di Bella static_assert(std::ranges::enable_view<NotDefaultInit>);
49*d8fad661SChristopher Di Bella static_assert(!std::ranges::view<NotDefaultInit>);
50*d8fad661SChristopher Di Bella 
51*d8fad661SChristopher Di Bella // The type would be a view, but it doesn't enable it with enable_view
52*d8fad661SChristopher Di Bella struct NotExplicitlyEnabled {
53*d8fad661SChristopher Di Bella   NotExplicitlyEnabled() = default;
54*d8fad661SChristopher Di Bella   NotExplicitlyEnabled(NotExplicitlyEnabled&&) = default;
55*d8fad661SChristopher Di Bella   NotExplicitlyEnabled& operator=(NotExplicitlyEnabled&&) = default;
56*d8fad661SChristopher Di Bella   friend int* begin(NotExplicitlyEnabled&);
57*d8fad661SChristopher Di Bella   friend int* begin(NotExplicitlyEnabled const&);
58*d8fad661SChristopher Di Bella   friend int* end(NotExplicitlyEnabled&);
59*d8fad661SChristopher Di Bella   friend int* end(NotExplicitlyEnabled const&);
60*d8fad661SChristopher Di Bella };
61*d8fad661SChristopher Di Bella static_assert(std::ranges::range<NotExplicitlyEnabled>);
62*d8fad661SChristopher Di Bella static_assert(std::movable<NotExplicitlyEnabled>);
63*d8fad661SChristopher Di Bella static_assert(std::default_initializable<NotExplicitlyEnabled>);
64*d8fad661SChristopher Di Bella static_assert(!std::ranges::enable_view<NotExplicitlyEnabled>);
65*d8fad661SChristopher Di Bella static_assert(!std::ranges::view<NotExplicitlyEnabled>);
66*d8fad661SChristopher Di Bella 
67*d8fad661SChristopher Di Bella // The type has everything else, but it's not a range
68*d8fad661SChristopher Di Bella struct NotARange : std::ranges::view_base {
69*d8fad661SChristopher Di Bella   NotARange() = default;
70*d8fad661SChristopher Di Bella   NotARange(NotARange&&) = default;
71*d8fad661SChristopher Di Bella   NotARange& operator=(NotARange&&) = default;
72*d8fad661SChristopher Di Bella };
73*d8fad661SChristopher Di Bella static_assert(!std::ranges::range<NotARange>);
74*d8fad661SChristopher Di Bella static_assert(std::movable<NotARange>);
75*d8fad661SChristopher Di Bella static_assert(std::default_initializable<NotARange>);
76*d8fad661SChristopher Di Bella static_assert(std::ranges::enable_view<NotARange>);
77*d8fad661SChristopher Di Bella static_assert(!std::ranges::view<NotARange>);
78*d8fad661SChristopher Di Bella 
79*d8fad661SChristopher Di Bella // The type satisfies all requirements
80*d8fad661SChristopher Di Bella struct View : std::ranges::view_base {
81*d8fad661SChristopher Di Bella   View() = default;
82*d8fad661SChristopher Di Bella   View(View&&) = default;
83*d8fad661SChristopher Di Bella   View& operator=(View&&) = default;
84*d8fad661SChristopher Di Bella   friend int* begin(View&);
85*d8fad661SChristopher Di Bella   friend int* begin(View const&);
86*d8fad661SChristopher Di Bella   friend int* end(View&);
87*d8fad661SChristopher Di Bella   friend int* end(View const&);
88*d8fad661SChristopher Di Bella };
89*d8fad661SChristopher Di Bella static_assert(std::ranges::range<View>);
90*d8fad661SChristopher Di Bella static_assert(std::movable<View>);
91*d8fad661SChristopher Di Bella static_assert(std::default_initializable<View>);
92*d8fad661SChristopher Di Bella static_assert(std::ranges::enable_view<View>);
93*d8fad661SChristopher Di Bella static_assert(std::ranges::view<View>);
94