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