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 #ifndef TEST_SUPPORT_COUNTING_PREDICATES_H
10 #define TEST_SUPPORT_COUNTING_PREDICATES_H
11 
12 #include <cstddef>
13 #include <utility>
14 #include "test_macros.h"
15 
16 template <typename Predicate, typename Arg>
17 struct unary_counting_predicate {
18 public:
19     typedef Arg argument_type;
20     typedef bool result_type;
21 
unary_counting_predicateunary_counting_predicate22     unary_counting_predicate(Predicate p) : p_(p), count_(0) {}
~unary_counting_predicateunary_counting_predicate23     ~unary_counting_predicate() {}
24 
operatorunary_counting_predicate25     bool operator () (const Arg &a) const { ++count_; return p_(a); }
countunary_counting_predicate26     size_t count() const { return count_; }
resetunary_counting_predicate27     void reset() { count_ = 0; }
28 
29 private:
30     Predicate p_;
31     mutable size_t count_;
32 };
33 
34 
35 template <typename Predicate, typename Arg1, typename Arg2=Arg1>
36 struct binary_counting_predicate {
37 public:
38     typedef Arg1 first_argument_type;
39     typedef Arg2 second_argument_type;
40     typedef bool result_type;
41 
binary_counting_predicatebinary_counting_predicate42     binary_counting_predicate ( Predicate p ) : p_(p), count_(0) {}
~binary_counting_predicatebinary_counting_predicate43     ~binary_counting_predicate() {}
44 
operatorbinary_counting_predicate45     bool operator () (const Arg1 &a1, const Arg2 &a2) const { ++count_; return p_(a1, a2); }
countbinary_counting_predicate46     size_t count() const { return count_; }
resetbinary_counting_predicate47     void reset() { count_ = 0; }
48 
49 private:
50     Predicate p_;
51     mutable size_t count_;
52 };
53 
54 #if TEST_STD_VER > 14
55 
56 template <class Predicate>
57 class counting_predicate {
58   Predicate pred_;
59   int* count_ = nullptr;
60 
61 public:
62   constexpr counting_predicate() = default;
counting_predicate(Predicate pred,int & count)63   constexpr counting_predicate(Predicate pred, int& count) : pred_(std::move(pred)), count_(&count) {}
64 
65   template <class... Args>
decltype(auto)66   constexpr decltype(auto) operator()(Args&& ...args) {
67     ++(*count_);
68     return pred_(std::forward<Args>(args)...);
69   }
70 
71   template <class... Args>
decltype(auto)72   constexpr decltype(auto) operator()(Args&& ...args) const {
73     ++(*count_);
74     return pred_(std::forward<Args>(args)...);
75   }
76 };
77 
78 template <class Predicate>
79 counting_predicate(Predicate pred, int& count) -> counting_predicate<Predicate>;
80 
81 #endif // TEST_STD_VER > 14
82 
83 #endif // TEST_SUPPORT_COUNTING_PREDICATES_H
84