1*94075551SLouis Dionne //===----------------------------------------------------------------------===//
2*94075551SLouis Dionne //
3*94075551SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*94075551SLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5*94075551SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*94075551SLouis Dionne //
7*94075551SLouis Dionne //===----------------------------------------------------------------------===//
8*94075551SLouis Dionne
9*94075551SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14, c++17
10*94075551SLouis Dionne // UNSUPPORTED: libcpp-has-no-incomplete-ranges
11*94075551SLouis Dionne
12*94075551SLouis Dionne // std::views::common
13*94075551SLouis Dionne
14*94075551SLouis Dionne #include <ranges>
15*94075551SLouis Dionne
16*94075551SLouis Dionne #include <array>
17*94075551SLouis Dionne #include <cassert>
18*94075551SLouis Dionne #include <concepts>
19*94075551SLouis Dionne #include <utility>
20*94075551SLouis Dionne
21*94075551SLouis Dionne #include "test_iterators.h"
22*94075551SLouis Dionne #include "types.h"
23*94075551SLouis Dionne
24*94075551SLouis Dionne template <class View, class T>
25*94075551SLouis Dionne concept CanBePiped = requires (View&& view, T&& t) {
26*94075551SLouis Dionne { std::forward<View>(view) | std::forward<T>(t) };
27*94075551SLouis Dionne };
28*94075551SLouis Dionne
test()29*94075551SLouis Dionne constexpr bool test() {
30*94075551SLouis Dionne int buf[] = {1, 2, 3};
31*94075551SLouis Dionne
32*94075551SLouis Dionne // views::common(r) is equivalent to views::all(r) if r is a common_range
33*94075551SLouis Dionne {
34*94075551SLouis Dionne {
35*94075551SLouis Dionne CommonView view(buf, buf + 3);
36*94075551SLouis Dionne std::same_as<CommonView> auto result = std::views::common(view);
37*94075551SLouis Dionne assert(result.begin_ == buf);
38*94075551SLouis Dionne assert(result.end_ == buf + 3);
39*94075551SLouis Dionne }
40*94075551SLouis Dionne {
41*94075551SLouis Dionne using NotAView = std::array<int, 3>;
42*94075551SLouis Dionne NotAView arr = {1, 2, 3};
43*94075551SLouis Dionne std::same_as<std::ranges::ref_view<NotAView>> auto result = std::views::common(arr);
44*94075551SLouis Dionne assert(result.begin() == arr.begin());
45*94075551SLouis Dionne assert(result.end() == arr.end());
46*94075551SLouis Dionne }
47*94075551SLouis Dionne }
48*94075551SLouis Dionne
49*94075551SLouis Dionne // Otherwise, views::common(r) is equivalent to ranges::common_view{r}
50*94075551SLouis Dionne {
51*94075551SLouis Dionne NonCommonView view(buf, buf + 3);
52*94075551SLouis Dionne std::same_as<std::ranges::common_view<NonCommonView>> auto result = std::views::common(view);
53*94075551SLouis Dionne assert(result.base().begin_ == buf);
54*94075551SLouis Dionne assert(result.base().end_ == buf + 3);
55*94075551SLouis Dionne }
56*94075551SLouis Dionne
57*94075551SLouis Dionne // Test that std::views::common is a range adaptor
58*94075551SLouis Dionne {
59*94075551SLouis Dionne using SomeView = NonCommonView;
60*94075551SLouis Dionne
61*94075551SLouis Dionne // Test `v | views::common`
62*94075551SLouis Dionne {
63*94075551SLouis Dionne SomeView view(buf, buf + 3);
64*94075551SLouis Dionne std::same_as<std::ranges::common_view<SomeView>> auto result = view | std::views::common;
65*94075551SLouis Dionne assert(result.base().begin_ == buf);
66*94075551SLouis Dionne assert(result.base().end_ == buf + 3);
67*94075551SLouis Dionne }
68*94075551SLouis Dionne
69*94075551SLouis Dionne // Test `adaptor | views::common`
70*94075551SLouis Dionne {
71*94075551SLouis Dionne SomeView view(buf, buf + 3);
72*94075551SLouis Dionne auto f = [](int i) { return i; };
73*94075551SLouis Dionne auto const partial = std::views::transform(f) | std::views::common;
74*94075551SLouis Dionne using Result = std::ranges::common_view<std::ranges::transform_view<SomeView, decltype(f)>>;
75*94075551SLouis Dionne std::same_as<Result> auto result = partial(view);
76*94075551SLouis Dionne assert(result.base().base().begin_ == buf);
77*94075551SLouis Dionne assert(result.base().base().end_ == buf + 3);
78*94075551SLouis Dionne }
79*94075551SLouis Dionne
80*94075551SLouis Dionne // Test `views::common | adaptor`
81*94075551SLouis Dionne {
82*94075551SLouis Dionne SomeView view(buf, buf + 3);
83*94075551SLouis Dionne auto f = [](int i) { return i; };
84*94075551SLouis Dionne auto const partial = std::views::common | std::views::transform(f);
85*94075551SLouis Dionne using Result = std::ranges::transform_view<std::ranges::common_view<SomeView>, decltype(f)>;
86*94075551SLouis Dionne std::same_as<Result> auto result = partial(view);
87*94075551SLouis Dionne assert(result.base().base().begin_ == buf);
88*94075551SLouis Dionne assert(result.base().base().end_ == buf + 3);
89*94075551SLouis Dionne }
90*94075551SLouis Dionne
91*94075551SLouis Dionne // Check SFINAE friendliness
92*94075551SLouis Dionne {
93*94075551SLouis Dionne struct NotAView { };
94*94075551SLouis Dionne static_assert(!std::is_invocable_v<decltype(std::views::common)>);
95*94075551SLouis Dionne static_assert(!std::is_invocable_v<decltype(std::views::common), NotAView>);
96*94075551SLouis Dionne static_assert( CanBePiped<SomeView&, decltype(std::views::common)>);
97*94075551SLouis Dionne static_assert( CanBePiped<int(&)[10], decltype(std::views::common)>);
98*94075551SLouis Dionne static_assert(!CanBePiped<int(&&)[10], decltype(std::views::common)>);
99*94075551SLouis Dionne static_assert(!CanBePiped<NotAView, decltype(std::views::common)>);
100*94075551SLouis Dionne }
101*94075551SLouis Dionne }
102*94075551SLouis Dionne
103*94075551SLouis Dionne {
104*94075551SLouis Dionne static_assert(std::same_as<decltype(std::views::common), decltype(std::ranges::views::common)>);
105*94075551SLouis Dionne }
106*94075551SLouis Dionne
107*94075551SLouis Dionne return true;
108*94075551SLouis Dionne }
109*94075551SLouis Dionne
main(int,char **)110*94075551SLouis Dionne int main(int, char**) {
111*94075551SLouis Dionne test();
112*94075551SLouis Dionne static_assert(test());
113*94075551SLouis Dionne
114*94075551SLouis Dionne return 0;
115*94075551SLouis Dionne }
116