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// template<class F, class I>
12// concept indirect_unary_predicate;
13
14#include <iterator>
15#include <type_traits>
16
17#include "indirectly_readable.h"
18#include "test_macros.h"
19
20using It = IndirectlyReadable<struct Token>;
21
22template <class I>
23struct GoodPredicate {
24 bool operator()(std::iter_reference_t<I>) const;
25 bool operator()(std::iter_value_t<I>&) const;
26 bool operator()(std::iter_common_reference_t<I>) const;
27};
28
29// Should work when all constraints are satisfied
30static_assert(std::indirect_unary_predicate<GoodPredicate<It>, It>);
31static_assert(std::indirect_unary_predicate<bool(*)(int), int*>);
32[[maybe_unused]] auto lambda = [](int i) { return i % 2 == 0; };
33static_assert(std::indirect_unary_predicate<decltype(lambda), int*>);
34
35// Should fail when the iterator is not indirectly_readable
36struct NotIndirectlyReadable { };
37static_assert(!std::indirect_unary_predicate<GoodPredicate<NotIndirectlyReadable>, NotIndirectlyReadable>);
38
39// Should fail when the predicate is not copy constructible
40struct BadPredicate1 {
41 BadPredicate1(BadPredicate1 const&) = delete;
42 template <class T> bool operator()(T const&) const;
43};
44static_assert(!std::indirect_unary_predicate<BadPredicate1, It>);
45
46// Should fail when the predicate can't be called with std::iter_value_t<It>&
47struct BadPredicate2 {
48 template <class T> bool operator()(T const&) const;
49 bool operator()(std::iter_value_t<It>&) const = delete;
50};
51static_assert(!std::indirect_unary_predicate<BadPredicate2, It>);
52
53// Should fail when the predicate can't be called with std::iter_reference_t<It>
54struct BadPredicate3 {
55 template <class T> bool operator()(T const&) const;
56 bool operator()(std::iter_reference_t<It>) const = delete;
57};
58static_assert(!std::indirect_unary_predicate<BadPredicate3, It>);
59
60// Should fail when the predicate can't be called with std::iter_common_reference_t<It>
61struct BadPredicate4 {
62 template <class T> bool operator()(T const&) const;
63 bool operator()(std::iter_common_reference_t<It>) const = delete;
64};
65static_assert(!std::indirect_unary_predicate<BadPredicate4, It>);
66
67// Test ADL-proofing (P2538R1)
68#if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
69struct Incomplete;
70template<class T> struct Holder { T t; };
71struct HolderIncompletePred { bool operator()(Holder<Incomplete>*) const; };
72static_assert(std::indirect_unary_predicate<HolderIncompletePred, Holder<Incomplete>**>);
73static_assert(!std::indirect_unary_predicate<Holder<Incomplete>*, Holder<Incomplete>**>);
74#endif
75

source code of libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp