xref: /llvm-project/libcxx/test/support/counting_predicates.h (revision 70248920fcd804a5825ecf69f24b96a7e340afe6)
1cc89063bSNico Weber //===----------------------------------------------------------------------===//
2cc89063bSNico Weber //
3cc89063bSNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cc89063bSNico Weber // See https://llvm.org/LICENSE.txt for license information.
5cc89063bSNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cc89063bSNico Weber //
7cc89063bSNico Weber //===----------------------------------------------------------------------===//
8cc89063bSNico Weber 
9cc89063bSNico Weber #ifndef TEST_SUPPORT_COUNTING_PREDICATES_H
10cc89063bSNico Weber #define TEST_SUPPORT_COUNTING_PREDICATES_H
11cc89063bSNico Weber 
12cc89063bSNico Weber #include <cstddef>
13065202f3SKonstantin Varlamov #include <utility>
14065202f3SKonstantin Varlamov #include "test_macros.h"
15cc89063bSNico Weber 
16cc89063bSNico Weber template <typename Predicate, typename Arg>
17cc89063bSNico Weber struct unary_counting_predicate {
18cc89063bSNico Weber public:
19cc89063bSNico Weber     typedef Arg argument_type;
20cc89063bSNico Weber     typedef bool result_type;
21cc89063bSNico Weber 
unary_counting_predicateunary_counting_predicate22cc89063bSNico Weber     unary_counting_predicate(Predicate p) : p_(p), count_(0) {}
23*70248920SIgor Zhukov     unary_counting_predicate(const unary_counting_predicate&) = default;
24*70248920SIgor Zhukov     unary_counting_predicate& operator=(const unary_counting_predicate&) = default;
~unary_counting_predicateunary_counting_predicate25cc89063bSNico Weber     ~unary_counting_predicate() {}
26cc89063bSNico Weber 
operatorunary_counting_predicate27cc89063bSNico Weber     bool operator () (const Arg &a) const { ++count_; return p_(a); }
countunary_counting_predicate28fb855eb9SMark de Wever     std::size_t count() const { return count_; }
resetunary_counting_predicate29cc89063bSNico Weber     void reset() { count_ = 0; }
30cc89063bSNico Weber 
31cc89063bSNico Weber private:
32cc89063bSNico Weber     Predicate p_;
33fb855eb9SMark de Wever     mutable std::size_t count_;
34cc89063bSNico Weber };
35cc89063bSNico Weber 
36cc89063bSNico Weber 
37cc89063bSNico Weber template <typename Predicate, typename Arg1, typename Arg2=Arg1>
38cc89063bSNico Weber struct binary_counting_predicate {
39cc89063bSNico Weber public:
40cc89063bSNico Weber     typedef Arg1 first_argument_type;
41cc89063bSNico Weber     typedef Arg2 second_argument_type;
42cc89063bSNico Weber     typedef bool result_type;
43cc89063bSNico Weber 
binary_counting_predicatebinary_counting_predicate44cc89063bSNico Weber     binary_counting_predicate ( Predicate p ) : p_(p), count_(0) {}
~binary_counting_predicatebinary_counting_predicate45cc89063bSNico Weber     ~binary_counting_predicate() {}
46cc89063bSNico Weber 
operatorbinary_counting_predicate47cc89063bSNico Weber     bool operator () (const Arg1 &a1, const Arg2 &a2) const { ++count_; return p_(a1, a2); }
countbinary_counting_predicate48fb855eb9SMark de Wever     std::size_t count() const { return count_; }
resetbinary_counting_predicate49cc89063bSNico Weber     void reset() { count_ = 0; }
50cc89063bSNico Weber 
51cc89063bSNico Weber private:
52cc89063bSNico Weber     Predicate p_;
53fb855eb9SMark de Wever     mutable std::size_t count_;
54cc89063bSNico Weber };
55cc89063bSNico Weber 
56065202f3SKonstantin Varlamov #if TEST_STD_VER > 14
57065202f3SKonstantin Varlamov 
58065202f3SKonstantin Varlamov template <class Predicate>
59065202f3SKonstantin Varlamov class counting_predicate {
60065202f3SKonstantin Varlamov   Predicate pred_;
61065202f3SKonstantin Varlamov   int* count_ = nullptr;
62065202f3SKonstantin Varlamov 
63065202f3SKonstantin Varlamov public:
64065202f3SKonstantin Varlamov   constexpr counting_predicate() = default;
counting_predicate(Predicate pred,int & count)65065202f3SKonstantin Varlamov   constexpr counting_predicate(Predicate pred, int& count) : pred_(std::move(pred)), count_(&count) {}
66065202f3SKonstantin Varlamov 
67065202f3SKonstantin Varlamov   template <class... Args>
decltype(auto)6893172c1cSNikolas Klauser   constexpr decltype(auto) operator()(Args&& ...args) {
6993172c1cSNikolas Klauser     ++(*count_);
7093172c1cSNikolas Klauser     return pred_(std::forward<Args>(args)...);
7193172c1cSNikolas Klauser   }
7293172c1cSNikolas Klauser 
7393172c1cSNikolas Klauser   template <class... Args>
decltype(auto)74065202f3SKonstantin Varlamov   constexpr decltype(auto) operator()(Args&& ...args) const {
75065202f3SKonstantin Varlamov     ++(*count_);
76065202f3SKonstantin Varlamov     return pred_(std::forward<Args>(args)...);
77065202f3SKonstantin Varlamov   }
78065202f3SKonstantin Varlamov };
79065202f3SKonstantin Varlamov 
80065202f3SKonstantin Varlamov template <class Predicate>
81065202f3SKonstantin Varlamov counting_predicate(Predicate pred, int& count) -> counting_predicate<Predicate>;
82065202f3SKonstantin Varlamov 
83065202f3SKonstantin Varlamov #endif // TEST_STD_VER > 14
84065202f3SKonstantin Varlamov 
85cc89063bSNico Weber #endif // TEST_SUPPORT_COUNTING_PREDICATES_H
86