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