xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.take.while/adaptor.pass.cpp (revision ba2236d3000645d3127f972aa7ac1844c47e299c)
1a2c6a119SHui Xie //===----------------------------------------------------------------------===//
2a2c6a119SHui Xie //
3a2c6a119SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a2c6a119SHui Xie // See https://llvm.org/LICENSE.txt for license information.
5a2c6a119SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a2c6a119SHui Xie //
7a2c6a119SHui Xie //===----------------------------------------------------------------------===//
8a2c6a119SHui Xie 
9a2c6a119SHui Xie // UNSUPPORTED: c++03, c++11, c++14, c++17
10a2c6a119SHui Xie 
11a2c6a119SHui Xie // std::views::take_while
12a2c6a119SHui Xie 
13a2c6a119SHui Xie #include <algorithm>
14a2c6a119SHui Xie #include <cassert>
15a2c6a119SHui Xie #include <ranges>
16a2c6a119SHui Xie #include <type_traits>
17a2c6a119SHui Xie #include <utility>
18a2c6a119SHui Xie 
19*ba2236d3SWill Hawkins #include "test_range.h"
20a2c6a119SHui Xie #include "types.h"
21a2c6a119SHui Xie 
22a2c6a119SHui Xie struct Pred {
operator ()Pred23a2c6a119SHui Xie   constexpr bool operator()(int i) const { return i < 3; }
24a2c6a119SHui Xie };
25a2c6a119SHui Xie 
26a2c6a119SHui Xie struct Foo {};
27a2c6a119SHui Xie 
28a2c6a119SHui Xie struct MoveOnlyView : IntBufferViewBase {
29a2c6a119SHui Xie   using IntBufferViewBase::IntBufferViewBase;
30a2c6a119SHui Xie   MoveOnlyView(const MoveOnlyView&)            = delete;
31a2c6a119SHui Xie   MoveOnlyView& operator=(const MoveOnlyView&) = delete;
32a2c6a119SHui Xie   MoveOnlyView(MoveOnlyView&&)                 = default;
33a2c6a119SHui Xie   MoveOnlyView& operator=(MoveOnlyView&&)      = default;
beginMoveOnlyView34a2c6a119SHui Xie   constexpr const int* begin() const { return buffer_; }
endMoveOnlyView35a2c6a119SHui Xie   constexpr const int* end() const { return buffer_ + size_; }
36a2c6a119SHui Xie };
37a2c6a119SHui Xie 
38a2c6a119SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::take_while))>);
39a2c6a119SHui Xie static_assert(std::is_invocable_v<decltype((std::views::take_while)), int>);
40a2c6a119SHui Xie static_assert(std::is_invocable_v<decltype((std::views::take_while)), Pred>);
41a2c6a119SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::take_while)), int, Pred>);
42a2c6a119SHui Xie static_assert(std::is_invocable_v<decltype((std::views::take_while)), int (&)[2], Pred>);
43a2c6a119SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::take_while)), Foo (&)[2], Pred>);
44a2c6a119SHui Xie static_assert(std::is_invocable_v<decltype((std::views::take_while)), MoveOnlyView, Pred>);
45a2c6a119SHui Xie 
46a2c6a119SHui Xie static_assert(!CanBePiped<MoveOnlyView, decltype(std::views::take_while)>);
47a2c6a119SHui Xie static_assert(CanBePiped<MoveOnlyView, decltype(std::views::take_while(Pred{}))>);
48a2c6a119SHui Xie static_assert(!CanBePiped<int, decltype(std::views::take_while(Pred{}))>);
49a2c6a119SHui Xie static_assert(CanBePiped<int (&)[2], decltype(std::views::take_while(Pred{}))>);
50a2c6a119SHui Xie static_assert(!CanBePiped<Foo (&)[2], decltype(std::views::take_while(Pred{}))>);
51a2c6a119SHui Xie 
test()52a2c6a119SHui Xie constexpr bool test() {
53a2c6a119SHui Xie   int buff[] = {1, 2, 3, 4, 3, 2, 1};
54a2c6a119SHui Xie 
55a2c6a119SHui Xie   // Test `views::take_while(p)(v)`
56a2c6a119SHui Xie   {
57a2c6a119SHui Xie     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
58a2c6a119SHui Xie     std::same_as<Result> decltype(auto) result = std::views::take_while(Pred{})(MoveOnlyView{buff});
59a2c6a119SHui Xie     auto expected                              = {1, 2};
60a2c6a119SHui Xie     assert(std::ranges::equal(result, expected));
61a2c6a119SHui Xie   }
62a2c6a119SHui Xie   {
63a2c6a119SHui Xie     auto const partial                         = std::views::take_while(Pred{});
64a2c6a119SHui Xie     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
65a2c6a119SHui Xie     std::same_as<Result> decltype(auto) result = partial(MoveOnlyView{buff});
66a2c6a119SHui Xie     auto expected                              = {1, 2};
67a2c6a119SHui Xie     assert(std::ranges::equal(result, expected));
68a2c6a119SHui Xie   }
69a2c6a119SHui Xie 
70a2c6a119SHui Xie   // Test `v | views::take_while(p)`
71a2c6a119SHui Xie   {
72a2c6a119SHui Xie     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
73a2c6a119SHui Xie     std::same_as<Result> decltype(auto) result = MoveOnlyView{buff} | std::views::take_while(Pred{});
74a2c6a119SHui Xie     auto expected                              = {1, 2};
75a2c6a119SHui Xie     assert(std::ranges::equal(result, expected));
76a2c6a119SHui Xie   }
77a2c6a119SHui Xie   {
78a2c6a119SHui Xie     auto const partial                         = std::views::take_while(Pred{});
79a2c6a119SHui Xie     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
80a2c6a119SHui Xie     std::same_as<Result> decltype(auto) result = MoveOnlyView{buff} | partial;
81a2c6a119SHui Xie     auto expected                              = {1, 2};
82a2c6a119SHui Xie     assert(std::ranges::equal(result, expected));
83a2c6a119SHui Xie   }
84a2c6a119SHui Xie 
85a2c6a119SHui Xie   // Test `views::take_while(v, p)`
86a2c6a119SHui Xie   {
87a2c6a119SHui Xie     using Result                               = std::ranges::take_while_view<MoveOnlyView, Pred>;
88a2c6a119SHui Xie     std::same_as<Result> decltype(auto) result = std::views::take_while(MoveOnlyView{buff}, Pred{});
89a2c6a119SHui Xie     auto expected                              = {1, 2};
90a2c6a119SHui Xie     assert(std::ranges::equal(result, expected));
91a2c6a119SHui Xie   }
92a2c6a119SHui Xie 
93a2c6a119SHui Xie   // Test adaptor | adaptor
94a2c6a119SHui Xie   {
95a2c6a119SHui Xie     struct Pred2 {
96a2c6a119SHui Xie       constexpr bool operator()(int i) const { return i < 2; }
97a2c6a119SHui Xie     };
98a2c6a119SHui Xie     auto const partial = std::views::take_while(Pred{}) | std::views::take_while(Pred2{});
99a2c6a119SHui Xie     using Result       = std::ranges::take_while_view<std::ranges::take_while_view<MoveOnlyView, Pred>, Pred2>;
100a2c6a119SHui Xie     std::same_as<Result> decltype(auto) result = MoveOnlyView{buff} | partial;
101a2c6a119SHui Xie     auto expected                              = {1};
102a2c6a119SHui Xie     assert(std::ranges::equal(result, expected));
103a2c6a119SHui Xie   }
104a2c6a119SHui Xie   return true;
105a2c6a119SHui Xie }
106a2c6a119SHui Xie 
main(int,char **)107a2c6a119SHui Xie int main(int, char**) {
108a2c6a119SHui Xie   test();
109a2c6a119SHui Xie   static_assert(test());
110a2c6a119SHui Xie 
111a2c6a119SHui Xie   return 0;
112a2c6a119SHui Xie }
113