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 | |
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 | |
105 | int main(int, char**) { |
106 | test(); |
107 | static_assert(test()); |
108 | |
109 | return 0; |
110 | } |
111 | |