123 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// std::views::drop_while12 13#include <algorithm>14#include <cassert>15#include <ranges>16#include <type_traits>17#include <utility>18 19#include "test_range.h"20 21struct Pred {22 constexpr bool operator()(int i) const { return i < 3; }23};24 25struct Foo {};26 27template <class T>28struct BufferView : std::ranges::view_base {29 T* buffer_;30 std::size_t size_;31 32 template <std::size_t N>33 constexpr BufferView(T (&b)[N]) : buffer_(b), size_(N) {}34};35 36using IntBufferView = BufferView<int>;37 38struct MoveOnlyView : IntBufferView {39 using IntBufferView::IntBufferView;40 MoveOnlyView(const MoveOnlyView&) = delete;41 MoveOnlyView& operator=(const MoveOnlyView&) = delete;42 MoveOnlyView(MoveOnlyView&&) = default;43 MoveOnlyView& operator=(MoveOnlyView&&) = default;44 constexpr const int* begin() const { return buffer_; }45 constexpr const int* end() const { return buffer_ + size_; }46};47 48static_assert(!std::is_invocable_v<decltype((std::views::drop_while))>);49static_assert(std::is_invocable_v<decltype((std::views::drop_while)), int>);50static_assert(std::is_invocable_v<decltype((std::views::drop_while)), Pred>);51static_assert(!std::is_invocable_v<decltype((std::views::drop_while)), int, Pred>);52static_assert(std::is_invocable_v<decltype((std::views::drop_while)), int (&)[2], Pred>);53static_assert(!std::is_invocable_v<decltype((std::views::drop_while)), Foo (&)[2], Pred>);54static_assert(std::is_invocable_v<decltype((std::views::drop_while)), MoveOnlyView, Pred>);55 56static_assert(!CanBePiped<MoveOnlyView, decltype(std::views::drop_while)>);57static_assert(CanBePiped<MoveOnlyView, decltype(std::views::drop_while(Pred{}))>);58static_assert(!CanBePiped<int, decltype(std::views::drop_while(Pred{}))>);59static_assert(CanBePiped<int (&)[2], decltype(std::views::drop_while(Pred{}))>);60static_assert(!CanBePiped<Foo (&)[2], decltype(std::views::drop_while(Pred{}))>);61 62constexpr bool test() {63 int buff[] = {1, 2, 3, 4, 3, 2, 1};64 65 // Test `views::drop_while(p)(v)`66 {67 using Result = std::ranges::drop_while_view<MoveOnlyView, Pred>;68 std::same_as<Result> auto result = std::views::drop_while(Pred{})(MoveOnlyView{buff});69 auto expected = {3, 4, 3, 2, 1};70 assert(std::ranges::equal(result, expected));71 }72 {73 auto const partial = std::views::drop_while(Pred{});74 using Result = std::ranges::drop_while_view<MoveOnlyView, Pred>;75 std::same_as<Result> auto result = partial(MoveOnlyView{buff});76 auto expected = {3, 4, 3, 2, 1};77 assert(std::ranges::equal(result, expected));78 }79 80 // Test `v | views::drop_while(p)`81 {82 using Result = std::ranges::drop_while_view<MoveOnlyView, Pred>;83 std::same_as<Result> auto result = MoveOnlyView{buff} | std::views::drop_while(Pred{});84 auto expected = {3, 4, 3, 2, 1};85 assert(std::ranges::equal(result, expected));86 }87 {88 auto const partial = std::views::drop_while(Pred{});89 using Result = std::ranges::drop_while_view<MoveOnlyView, Pred>;90 std::same_as<Result> auto result = MoveOnlyView{buff} | partial;91 auto expected = {3, 4, 3, 2, 1};92 assert(std::ranges::equal(result, expected));93 }94 95 // Test `views::drop_while(v, p)`96 {97 using Result = std::ranges::drop_while_view<MoveOnlyView, Pred>;98 std::same_as<Result> auto result = std::views::drop_while(MoveOnlyView{buff}, Pred{});99 auto expected = {3, 4, 3, 2, 1};100 assert(std::ranges::equal(result, expected));101 }102 103 // Test adaptor | adaptor104 {105 struct Pred2 {106 constexpr bool operator()(int i) const { return i < 4; }107 };108 auto const partial = std::views::drop_while(Pred{}) | std::views::drop_while(Pred2{});109 using Result = std::ranges::drop_while_view<std::ranges::drop_while_view<MoveOnlyView, Pred>, Pred2>;110 std::same_as<Result> auto result = MoveOnlyView{buff} | partial;111 auto expected = {4, 3, 2, 1};112 assert(std::ranges::equal(result, expected));113 }114 return true;115}116 117int main(int, char**) {118 test();119 static_assert(test());120 121 return 0;122}123