Remove type erasure in predicate matcher

Now the type of the predicate is part of the type of the
PredicateMatcher.
This commit is contained in:
Martin Hořeňovský 2019-10-28 15:28:19 +01:00
parent c781301cd4
commit 316a5c0572
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
4 changed files with 14 additions and 20 deletions

View File

@ -33,16 +33,6 @@ The API for Catch2's console colour will be changed to take an extra
argument, the stream to which the colour code should be applied. argument, the stream to which the colour code should be applied.
### Type erasure in the `PredicateMatcher`
Currently, the `PredicateMatcher` uses `std::function` for type erasure,
so that type of the matcher is always `PredicateMatcher<T>`, regardless
of the type of the predicate. Because of the high compilation overhead
of `std::function`, and the fact that the type erasure is used only rarely,
`PredicateMatcher` will no longer be type erased in the future. Instead,
the predicate type will be made part of the PredicateMatcher's type.
--- ---
[Home](Readme.md#top) [Home](Readme.md#top)

View File

@ -44,7 +44,8 @@
* If the second argument has text outside tags, the text will be ignored. * If the second argument has text outside tags, the text will be ignored.
* Hidden test cases are no longer included just because they don't match an exclusion tag * Hidden test cases are no longer included just because they don't match an exclusion tag
* Previously, a `TEST_CASE("A", "[.foo]")` would be included by asking for `~[bar]`. * Previously, a `TEST_CASE("A", "[.foo]")` would be included by asking for `~[bar]`.
* `PredicateMatcher` is no longer type erased.
* This means that the type of the provided predicate is part of the `PredicateMatcher`'s type
### Fixes ### Fixes

View File

@ -14,7 +14,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <cassert> #include <cassert>
#include <tuple>
#include <utility> #include <utility>
#include <exception> #include <exception>

View File

@ -9,9 +9,10 @@
#include "catch_common.h" #include "catch_common.h"
#include "catch_matchers.h" #include "catch_matchers.h"
#include "catch_meta.hpp"
#include <functional>
#include <string> #include <string>
#include <utility>
namespace Catch { namespace Catch {
namespace Matchers { namespace Matchers {
@ -21,14 +22,14 @@ namespace Detail {
std::string finalizeDescription(const std::string& desc); std::string finalizeDescription(const std::string& desc);
} }
template <typename T> template <typename T, typename Predicate>
class PredicateMatcher : public MatcherBase<T> { class PredicateMatcher : public MatcherBase<T> {
std::function<bool(T const&)> m_predicate; Predicate m_predicate;
std::string m_description; std::string m_description;
public: public:
PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr) PredicateMatcher(Predicate&& elem, std::string const& descr)
:m_predicate(std::move(elem)), :m_predicate(std::forward<Predicate>(elem)),
m_description(Detail::finalizeDescription(descr)) m_description(Detail::finalizeDescription(descr))
{} {}
@ -47,9 +48,11 @@ public:
// The user has to explicitly specify type to the function, because // The user has to explicitly specify type to the function, because
// inferring std::function<bool(T const&)> is hard (but possible) and // inferring std::function<bool(T const&)> is hard (but possible) and
// requires a lot of TMP. // requires a lot of TMP.
template<typename T> template<typename T, typename Pred>
Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") { Generic::PredicateMatcher<T, Pred> Predicate(Pred&& predicate, std::string const& description = "") {
return Generic::PredicateMatcher<T>(predicate, description); static_assert(is_callable<Pred(T)>::value, "Predicate not callable with argument T");
static_assert(std::is_same<bool, FunctionReturnType<Pred, T>>::value, "Predicate does not return bool");
return Generic::PredicateMatcher<T, Pred>(std::forward<Pred>(predicate), description);
} }
} // namespace Matchers } // namespace Matchers