xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.common.view/adaptor.pass.cpp (revision ba2236d3000645d3127f972aa7ac1844c47e299c)
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 // std::views::common
12 
13 #include <ranges>
14 
15 #include <array>
16 #include <cassert>
17 #include <concepts>
18 #include <utility>
19 
20 #include "test_iterators.h"
21 #include "test_range.h"
22 #include "types.h"
23 
test()24 constexpr bool test() {
25   int buf[] = {1, 2, 3};
26 
27   // views::common(r) is equivalent to views::all(r) if r is a common_range
28   {
29     {
30       CommonView view(buf, buf + 3);
31       std::same_as<CommonView> auto result = std::views::common(view);
32       assert(result.begin_ == buf);
33       assert(result.end_ == buf + 3);
34     }
35     {
36       using NotAView = std::array<int, 3>;
37       NotAView arr = {1, 2, 3};
38       std::same_as<std::ranges::ref_view<NotAView>> auto result = std::views::common(arr);
39       assert(result.begin() == arr.begin());
40       assert(result.end() == arr.end());
41     }
42   }
43 
44   // Otherwise, views::common(r) is equivalent to ranges::common_view{r}
45   {
46     NonCommonView view(buf, buf + 3);
47     std::same_as<std::ranges::common_view<NonCommonView>> auto result = std::views::common(view);
48     assert(result.base().begin_ == buf);
49     assert(result.base().end_ == buf + 3);
50   }
51 
52   // Test that std::views::common is a range adaptor
53   {
54     using SomeView = NonCommonView;
55 
56     // Test `v | views::common`
57     {
58       SomeView view(buf, buf + 3);
59       std::same_as<std::ranges::common_view<SomeView>> auto result = view | std::views::common;
60       assert(result.base().begin_ == buf);
61       assert(result.base().end_ == buf + 3);
62     }
63 
64     // Test `adaptor | views::common`
65     {
66       SomeView view(buf, buf + 3);
67       auto f = [](int i) { return i; };
68       auto const partial = std::views::transform(f) | std::views::common;
69       using Result = std::ranges::common_view<std::ranges::transform_view<SomeView, decltype(f)>>;
70       std::same_as<Result> auto result = partial(view);
71       assert(result.base().base().begin_ == buf);
72       assert(result.base().base().end_ == buf + 3);
73     }
74 
75     // Test `views::common | adaptor`
76     {
77       SomeView view(buf, buf + 3);
78       auto f = [](int i) { return i; };
79       auto const partial = std::views::common | std::views::transform(f);
80       using Result = std::ranges::transform_view<std::ranges::common_view<SomeView>, decltype(f)>;
81       std::same_as<Result> auto result = partial(view);
82       assert(result.base().base().begin_ == buf);
83       assert(result.base().base().end_ == buf + 3);
84     }
85 
86     // Check SFINAE friendliness
87     {
88       struct NotAView { };
89       static_assert(!std::is_invocable_v<decltype(std::views::common)>);
90       static_assert(!std::is_invocable_v<decltype(std::views::common), NotAView>);
91       static_assert( CanBePiped<SomeView&,   decltype(std::views::common)>);
92       static_assert( CanBePiped<int(&)[10],  decltype(std::views::common)>);
93       static_assert(!CanBePiped<int(&&)[10], decltype(std::views::common)>);
94       static_assert(!CanBePiped<NotAView,    decltype(std::views::common)>);
95     }
96   }
97 
98   {
99     static_assert(std::same_as<decltype(std::views::common), decltype(std::ranges::views::common)>);
100   }
101 
102   return true;
103 }
104 
main(int,char **)105 int main(int, char**) {
106   test();
107   static_assert(test());
108 
109   return 0;
110 }
111