| //===----------------------------------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| // UNSUPPORTED: c++03, c++11, c++14, c++17 |
| |
| // Check constraints on the type itself. |
| // |
| // template<input_range View, indirect_unary_predicate<iterator_t<View>> Pred> |
| // requires view<View> && is_object_v<Pred> |
| // class filter_view; |
| |
| #include <ranges> |
| |
| #include <concepts> |
| #include <cstddef> |
| #include <iterator> |
| #include <type_traits> |
| |
| template <class View, class Pred> |
| concept can_form_filter_view = requires { |
| typename std::ranges::filter_view<View, Pred>; |
| }; |
| |
| // filter_view is not valid when the view is not an input_range |
| namespace test1 { |
| struct View : std::ranges::view_base { |
| struct NotInputIterator { |
| NotInputIterator& operator++(); |
| void operator++(int); |
| int& operator*() const; |
| using difference_type = std::ptrdiff_t; |
| friend bool operator==(NotInputIterator const&, NotInputIterator const&); |
| }; |
| NotInputIterator begin() const; |
| NotInputIterator end() const; |
| }; |
| struct Pred { bool operator()(int) const; }; |
| |
| static_assert(!std::ranges::input_range<View>); |
| static_assert( std::indirect_unary_predicate<Pred, int*>); |
| static_assert( std::ranges::view<View>); |
| static_assert( std::is_object_v<Pred>); |
| static_assert(!can_form_filter_view<View, Pred>); |
| } |
| |
| // filter_view is not valid when the predicate is not indirect_unary_predicate |
| namespace test2 { |
| struct View : std::ranges::view_base { |
| int* begin() const; |
| int* end() const; |
| }; |
| struct Pred { }; |
| |
| static_assert( std::ranges::input_range<View>); |
| static_assert(!std::indirect_unary_predicate<Pred, int*>); |
| static_assert( std::ranges::view<View>); |
| static_assert( std::is_object_v<Pred>); |
| static_assert(!can_form_filter_view<View, Pred>); |
| } |
| |
| // filter_view is not valid when the view is not a view |
| namespace test3 { |
| struct View { |
| int* begin() const; |
| int* end() const; |
| }; |
| struct Pred { bool operator()(int) const; }; |
| |
| static_assert( std::ranges::input_range<View>); |
| static_assert( std::indirect_unary_predicate<Pred, int*>); |
| static_assert(!std::ranges::view<View>); |
| static_assert( std::is_object_v<Pred>); |
| static_assert(!can_form_filter_view<View, Pred>); |
| } |
| |
| // filter_view is not valid when the predicate is not an object type |
| namespace test4 { |
| struct View : std::ranges::view_base { |
| int* begin() const; |
| int* end() const; |
| }; |
| using Pred = bool(&)(int); |
| |
| static_assert( std::ranges::input_range<View>); |
| static_assert( std::indirect_unary_predicate<Pred, int*>); |
| static_assert( std::ranges::view<View>); |
| static_assert(!std::is_object_v<Pred>); |
| static_assert(!can_form_filter_view<View, Pred>); |
| } |
| |
| // filter_view is valid when all the constraints are satisfied (test the test) |
| namespace test5 { |
| struct View : std::ranges::view_base { |
| int* begin() const; |
| int* end() const; |
| }; |
| struct Pred { bool operator()(int) const; }; |
| |
| static_assert( std::ranges::input_range<View>); |
| static_assert( std::indirect_unary_predicate<Pred, int*>); |
| static_assert( std::ranges::view<View>); |
| static_assert( std::is_object_v<Pred>); |
| static_assert( can_form_filter_view<View, Pred>); |
| } |