xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.take.while/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::take_while
12 
13 #include <algorithm>
14 #include <cassert>
15 #include <ranges>
16 #include <type_traits>
17 #include <utility>
18 
19 #include "test_range.h"
20 #include "types.h"
21 
22 struct Pred {
operator ()Pred23   constexpr bool operator()(int i) const { return i < 3; }
24 };
25 
26 struct Foo {};
27 
28 struct MoveOnlyView : IntBufferViewBase {
29   using IntBufferViewBase::IntBufferViewBase;
30   MoveOnlyView(const MoveOnlyView&)            = delete;
31   MoveOnlyView& operator=(const MoveOnlyView&) = delete;
32   MoveOnlyView(MoveOnlyView&&)                 = default;
33   MoveOnlyView& operator=(MoveOnlyView&&)      = default;
beginMoveOnlyView34   constexpr const int* begin() const { return buffer_; }
endMoveOnlyView35   constexpr const int* end() const { return buffer_ + size_; }
36 };
37 
38 static_assert(!std::is_invocable_v<decltype((std::views::take_while))>);
39 static_assert(std::is_invocable_v<decltype((std::views::take_while)), int>);
40 static_assert(std::is_invocable_v<decltype((std::views::take_while)), Pred>);
41 static_assert(!std::is_invocable_v<decltype((std::views::take_while)), int, Pred>);
42 static_assert(std::is_invocable_v<decltype((std::views::take_while)), int (&)[2], Pred>);
43 static_assert(!std::is_invocable_v<decltype((std::views::take_while)), Foo (&)[2], Pred>);
44 static_assert(std::is_invocable_v<decltype((std::views::take_while)), MoveOnlyView, Pred>);
45 
46 static_assert(!CanBePiped<MoveOnlyView, decltype(std::views::take_while)>);
47 static_assert(CanBePiped<MoveOnlyView, decltype(std::views::take_while(Pred{}))>);
48 static_assert(!CanBePiped<int, decltype(std::views::take_while(Pred{}))>);
49 static_assert(CanBePiped<int (&)[2], decltype(std::views::take_while(Pred{}))>);
50 static_assert(!CanBePiped<Foo (&)[2], decltype(std::views::take_while(Pred{}))>);
51 
test()52 constexpr bool test() {
53   int buff[] = {1, 2, 3, 4, 3, 2, 1};
54 
55   // Test `views::take_while(p)(v)`
56   {
57     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
58     std::same_as<Result> decltype(auto) result = std::views::take_while(Pred{})(MoveOnlyView{buff});
59     auto expected                              = {1, 2};
60     assert(std::ranges::equal(result, expected));
61   }
62   {
63     auto const partial                         = std::views::take_while(Pred{});
64     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
65     std::same_as<Result> decltype(auto) result = partial(MoveOnlyView{buff});
66     auto expected                              = {1, 2};
67     assert(std::ranges::equal(result, expected));
68   }
69 
70   // Test `v | views::take_while(p)`
71   {
72     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
73     std::same_as<Result> decltype(auto) result = MoveOnlyView{buff} | std::views::take_while(Pred{});
74     auto expected                              = {1, 2};
75     assert(std::ranges::equal(result, expected));
76   }
77   {
78     auto const partial                         = std::views::take_while(Pred{});
79     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
80     std::same_as<Result> decltype(auto) result = MoveOnlyView{buff} | partial;
81     auto expected                              = {1, 2};
82     assert(std::ranges::equal(result, expected));
83   }
84 
85   // Test `views::take_while(v, p)`
86   {
87     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
88     std::same_as<Result> decltype(auto) result = std::views::take_while(MoveOnlyView{buff}, Pred{});
89     auto expected                              = {1, 2};
90     assert(std::ranges::equal(result, expected));
91   }
92 
93   // Test adaptor | adaptor
94   {
95     struct Pred2 {
96       constexpr bool operator()(int i) const { return i < 2; }
97     };
98     auto const partial = std::views::take_while(Pred{}) | std::views::take_while(Pred2{});
99     using Result       = std::ranges::take_while_view<std::ranges::take_while_view<MoveOnlyView, Pred>, Pred2>;
100     std::same_as<Result> decltype(auto) result = MoveOnlyView{buff} | partial;
101     auto expected                              = {1};
102     assert(std::ranges::equal(result, expected));
103   }
104   return true;
105 }
106 
main(int,char **)107 int main(int, char**) {
108   test();
109   static_assert(test());
110 
111   return 0;
112 }
113