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
22struct Pred {
23 constexpr bool operator()(int i) const { return i < 3; }
24};
25
26struct Foo {};
27
28struct 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;
34 constexpr const int* begin() const { return buffer_; }
35 constexpr const int* end() const { return buffer_ + size_; }
36};
37
38static_assert(!std::is_invocable_v<decltype((std::views::take_while))>);
39static_assert(std::is_invocable_v<decltype((std::views::take_while)), int>);
40static_assert(std::is_invocable_v<decltype((std::views::take_while)), Pred>);
41static_assert(!std::is_invocable_v<decltype((std::views::take_while)), int, Pred>);
42static_assert(std::is_invocable_v<decltype((std::views::take_while)), int (&)[2], Pred>);
43static_assert(!std::is_invocable_v<decltype((std::views::take_while)), Foo (&)[2], Pred>);
44static_assert(std::is_invocable_v<decltype((std::views::take_while)), MoveOnlyView, Pred>);
45
46static_assert(!CanBePiped<MoveOnlyView, decltype(std::views::take_while)>);
47static_assert(CanBePiped<MoveOnlyView, decltype(std::views::take_while(Pred{}))>);
48static_assert(!CanBePiped<int, decltype(std::views::take_while(Pred{}))>);
49static_assert(CanBePiped<int (&)[2], decltype(std::views::take_while(Pred{}))>);
50static_assert(!CanBePiped<Foo (&)[2], decltype(std::views::take_while(Pred{}))>);
51
52constexpr 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
107int main(int, char**) {
108 test();
109 static_assert(test());
110
111 return 0;
112}
113

source code of libcxx/test/std/ranges/range.adaptors/range.take.while/adaptor.pass.cpp