mirror of
https://github.com/catchorg/Catch2.git
synced 2025-08-02 13:25:41 +02:00
Start fixing up Matchers: namespaces, composition ops
This commit also forbids composing lvalues of composed matchers, as per previous deprecation notice. I do not expect this to be contentious in practice, because there was a bug in that usage for years, and nobody complained.
This commit is contained in:
@@ -26,7 +26,6 @@
|
||||
#include <catch2/catch_compiler_capabilities.h>
|
||||
#include <catch2/catch_string_manip.h>
|
||||
|
||||
#include <catch2/catch_capture_matchers.h>
|
||||
#include <catch2/catch_generators.hpp>
|
||||
#include <catch2/catch_generators_generic.hpp>
|
||||
#include <catch2/catch_generators_specific.hpp>
|
||||
|
@@ -10,8 +10,6 @@
|
||||
|
||||
namespace Catch {
|
||||
|
||||
using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
|
||||
|
||||
// This is the general overload that takes a any string matcher
|
||||
// There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
|
||||
// the Equals matcher (so the header does not mention matchers)
|
||||
|
@@ -17,7 +17,7 @@ namespace Catch {
|
||||
template<typename ArgT, typename MatcherT>
|
||||
class MatchExpr : public ITransientExpression {
|
||||
ArgT && m_arg;
|
||||
MatcherT m_matcher;
|
||||
MatcherT const& m_matcher;
|
||||
StringRef m_matcherString;
|
||||
public:
|
||||
MatchExpr( ArgT && arg, MatcherT const& matcher, StringRef const& matcherString )
|
||||
@@ -37,7 +37,7 @@ namespace Catch {
|
||||
}
|
||||
};
|
||||
|
||||
using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
|
||||
using StringMatcher = Matchers::MatcherBase<std::string>;
|
||||
|
||||
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
|
||||
|
||||
|
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
|
||||
std::string MatcherUntypedBase::toString() const {
|
||||
if( m_cachedToString.empty() )
|
||||
@@ -19,10 +18,5 @@ namespace Matchers {
|
||||
|
||||
MatcherUntypedBase::~MatcherUntypedBase() = default;
|
||||
|
||||
} // namespace Impl
|
||||
} // namespace Matchers
|
||||
|
||||
using namespace Matchers;
|
||||
using Matchers::Impl::MatcherBase;
|
||||
|
||||
} // namespace Catch
|
||||
|
@@ -15,11 +15,11 @@
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
|
||||
template<typename ArgT> struct MatchAllOf;
|
||||
template<typename ArgT> struct MatchAnyOf;
|
||||
template<typename ArgT> struct MatchNotOf;
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#endif
|
||||
|
||||
class MatcherUntypedBase {
|
||||
public:
|
||||
@@ -29,16 +29,11 @@ namespace Matchers {
|
||||
std::string toString() const;
|
||||
|
||||
protected:
|
||||
virtual ~MatcherUntypedBase();
|
||||
virtual ~MatcherUntypedBase(); // = default;
|
||||
virtual std::string describe() const = 0;
|
||||
mutable std::string m_cachedToString;
|
||||
};
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#endif
|
||||
|
||||
template<typename ObjectT>
|
||||
struct MatcherMethod {
|
||||
virtual bool match( ObjectT const& arg ) const = 0;
|
||||
@@ -58,16 +53,19 @@ namespace Matchers {
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
|
||||
struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {};
|
||||
|
||||
|
||||
MatchAllOf<T> operator && ( MatcherBase const& other ) const;
|
||||
MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
|
||||
MatchNotOf<T> operator ! () const;
|
||||
};
|
||||
namespace Detail {
|
||||
|
||||
template<typename ArgT>
|
||||
struct MatchAllOf : MatcherBase<ArgT> {
|
||||
MatchAllOf() = default;
|
||||
MatchAllOf(MatchAllOf const&) = delete;
|
||||
MatchAllOf& operator=(MatchAllOf const&) = delete;
|
||||
MatchAllOf(MatchAllOf&&) = default;
|
||||
MatchAllOf& operator=(MatchAllOf&&) = default;
|
||||
|
||||
|
||||
bool match( ArgT const& arg ) const override {
|
||||
for( auto matcher : m_matchers ) {
|
||||
if (!matcher->match(arg))
|
||||
@@ -91,16 +89,35 @@ namespace Matchers {
|
||||
return description;
|
||||
}
|
||||
|
||||
MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
|
||||
auto copy(*this);
|
||||
copy.m_matchers.push_back( &other );
|
||||
return copy;
|
||||
friend MatchAllOf operator&& (MatchAllOf&& lhs, MatcherBase<ArgT> const& rhs) {
|
||||
lhs.m_matchers.push_back(&rhs);
|
||||
return std::move(lhs);
|
||||
}
|
||||
friend MatchAllOf operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf&& rhs) {
|
||||
rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
|
||||
return std::move(rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<MatcherBase<ArgT> const*> m_matchers;
|
||||
};
|
||||
|
||||
//! lvalue overload is intentionally deleted, users should
|
||||
//! not be trying to compose stored composition matchers
|
||||
template<typename ArgT>
|
||||
MatchAllOf<ArgT> operator&& (MatchAllOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
|
||||
//! lvalue overload is intentionally deleted, users should
|
||||
//! not be trying to compose stored composition matchers
|
||||
template<typename ArgT>
|
||||
MatchAllOf<ArgT> operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf<ArgT> const& rhs) = delete;
|
||||
|
||||
template<typename ArgT>
|
||||
struct MatchAnyOf : MatcherBase<ArgT> {
|
||||
MatchAnyOf() = default;
|
||||
MatchAnyOf(MatchAnyOf const&) = delete;
|
||||
MatchAnyOf& operator=(MatchAnyOf const&) = delete;
|
||||
MatchAnyOf(MatchAnyOf&&) = default;
|
||||
MatchAnyOf& operator=(MatchAnyOf&&) = default;
|
||||
|
||||
bool match( ArgT const& arg ) const override {
|
||||
for( auto matcher : m_matchers ) {
|
||||
@@ -125,19 +142,34 @@ namespace Matchers {
|
||||
return description;
|
||||
}
|
||||
|
||||
MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
|
||||
auto copy(*this);
|
||||
copy.m_matchers.push_back( &other );
|
||||
return copy;
|
||||
friend MatchAnyOf operator|| (MatchAnyOf&& lhs, MatcherBase<ArgT> const& rhs) {
|
||||
lhs.m_matchers.push_back(&rhs);
|
||||
return std::move(lhs);
|
||||
}
|
||||
friend MatchAnyOf operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf&& rhs) {
|
||||
rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
|
||||
return std::move(rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<MatcherBase<ArgT> const*> m_matchers;
|
||||
};
|
||||
|
||||
//! lvalue overload is intentionally deleted, users should
|
||||
//! not be trying to compose stored composition matchers
|
||||
template<typename ArgT>
|
||||
MatchAnyOf<ArgT> operator|| (MatchAnyOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
|
||||
//! lvalue overload is intentionally deleted, users should
|
||||
//! not be trying to compose stored composition matchers
|
||||
template<typename ArgT>
|
||||
MatchAnyOf<ArgT> operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf<ArgT> const& rhs) = delete;
|
||||
|
||||
template<typename ArgT>
|
||||
struct MatchNotOf : MatcherBase<ArgT> {
|
||||
|
||||
MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
|
||||
explicit MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ):
|
||||
m_underlyingMatcher( underlyingMatcher )
|
||||
{}
|
||||
|
||||
bool match( ArgT const& arg ) const override {
|
||||
return !m_underlyingMatcher.match( arg );
|
||||
@@ -146,29 +178,29 @@ namespace Matchers {
|
||||
std::string describe() const override {
|
||||
return "not " + m_underlyingMatcher.toString();
|
||||
}
|
||||
|
||||
private:
|
||||
MatcherBase<ArgT> const& m_underlyingMatcher;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
|
||||
return MatchAllOf<T>() && *this && other;
|
||||
}
|
||||
template<typename T>
|
||||
MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
|
||||
return MatchAnyOf<T>() || *this || other;
|
||||
}
|
||||
template<typename T>
|
||||
MatchNotOf<T> MatcherBase<T>::operator ! () const {
|
||||
return MatchNotOf<T>( *this );
|
||||
}
|
||||
} // namespace Detail
|
||||
|
||||
template <typename T>
|
||||
Detail::MatchAllOf<T> operator&& (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
|
||||
return Detail::MatchAllOf<T>{} && lhs && rhs;
|
||||
}
|
||||
template <typename T>
|
||||
Detail::MatchAnyOf<T> operator|| (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
|
||||
return Detail::MatchAnyOf<T>{} || lhs || rhs;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Detail::MatchNotOf<T> operator! (MatcherBase<T> const& matcher) {
|
||||
return Detail::MatchNotOf<T>{ matcher };
|
||||
}
|
||||
|
||||
} // namespace Impl
|
||||
|
||||
} // namespace Matchers
|
||||
|
||||
using namespace Matchers;
|
||||
using Matchers::Impl::MatcherBase;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
|
||||
|
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
MatcherGenericBase::~MatcherGenericBase() {}
|
||||
MatcherGenericBase::~MatcherGenericBase() = default;
|
||||
|
||||
namespace Detail {
|
||||
|
||||
std::string describe_multi_matcher(StringRef combine, std::string const* descriptions_begin, std::string const* descriptions_end) {
|
||||
std::string description;
|
||||
@@ -27,6 +28,7 @@ namespace Matchers {
|
||||
description += " )";
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Detail
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
@@ -14,16 +14,12 @@
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
struct MatcherGenericBase : MatcherUntypedBase {
|
||||
virtual ~MatcherGenericBase(); // = default;
|
||||
};
|
||||
|
||||
template<typename... MatcherTs> struct MatchAllOfGeneric;
|
||||
template<typename... MatcherTs> struct MatchAnyOfGeneric;
|
||||
template<typename MatcherT> struct MatchNotOfGeneric;
|
||||
|
||||
struct MatcherGenericBase : MatcherUntypedBase {
|
||||
virtual ~MatcherGenericBase();
|
||||
};
|
||||
|
||||
namespace Detail {
|
||||
template<std::size_t N, std::size_t M>
|
||||
std::array<void const*, N + M> array_cat(std::array<void const*, N> && lhs, std::array<void const*, M> && rhs) {
|
||||
std::array<void const*, N + M> arr{};
|
||||
@@ -63,7 +59,7 @@ namespace Matchers {
|
||||
|
||||
template<typename T>
|
||||
using is_generic_matcher = std::is_base_of<
|
||||
Catch::Matchers::Impl::MatcherGenericBase,
|
||||
Catch::Matchers::MatcherGenericBase,
|
||||
typename std::remove_cv<typename std::remove_reference<T>::type>::type
|
||||
>;
|
||||
|
||||
@@ -72,7 +68,7 @@ namespace Matchers {
|
||||
|
||||
template<typename T>
|
||||
using is_matcher = std::is_base_of<
|
||||
Catch::Matchers::Impl::MatcherUntypedBase,
|
||||
Catch::Matchers::MatcherUntypedBase,
|
||||
typename std::remove_cv<typename std::remove_reference<T>::type>::type
|
||||
>;
|
||||
|
||||
@@ -161,102 +157,101 @@ namespace Matchers {
|
||||
|
||||
MatcherT const& m_matcher;
|
||||
};
|
||||
} // namespace Detail
|
||||
|
||||
// compose only generic matchers
|
||||
template<typename MatcherLHS, typename MatcherRHS>
|
||||
typename std::enable_if<are_generic_matchers<MatcherLHS, MatcherRHS>::value, MatchAllOfGeneric<MatcherLHS, MatcherRHS>>::type
|
||||
|
||||
// FIXME: enable_if_t
|
||||
|
||||
// compose only generic matchers
|
||||
template<typename MatcherLHS, typename MatcherRHS>
|
||||
typename std::enable_if<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherRHS>>::type
|
||||
operator && (MatcherLHS const& lhs, MatcherRHS const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
return { lhs, rhs };
|
||||
}
|
||||
|
||||
template<typename MatcherLHS, typename MatcherRHS>
|
||||
typename std::enable_if<are_generic_matchers<MatcherLHS, MatcherRHS>::value, MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>::type
|
||||
template<typename MatcherLHS, typename MatcherRHS>
|
||||
typename std::enable_if<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>::type
|
||||
operator || (MatcherLHS const& lhs, MatcherRHS const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
return { lhs, rhs };
|
||||
}
|
||||
|
||||
template<typename MatcherT>
|
||||
typename std::enable_if<is_generic_matcher<MatcherT>::value, MatchNotOfGeneric<MatcherT>>::type
|
||||
template<typename MatcherT>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherT>::value, Detail::MatchNotOfGeneric<MatcherT>>::type
|
||||
operator ! (MatcherT const& matcher) {
|
||||
return MatchNotOfGeneric<MatcherT>{matcher};
|
||||
}
|
||||
return Detail::MatchNotOfGeneric<MatcherT>{matcher};
|
||||
}
|
||||
|
||||
|
||||
// compose mixed generic and non-generic matchers
|
||||
template<typename MatcherLHS, typename ArgRHS>
|
||||
typename std::enable_if<is_generic_matcher<MatcherLHS>::value, MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type
|
||||
// compose mixed generic and non-generic matchers
|
||||
template<typename MatcherLHS, typename ArgRHS>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type
|
||||
operator && (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
return { lhs, rhs };
|
||||
}
|
||||
|
||||
template<typename ArgLHS, typename MatcherRHS>
|
||||
typename std::enable_if<is_generic_matcher<MatcherRHS>::value, MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
|
||||
template<typename ArgLHS, typename MatcherRHS>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
|
||||
operator && (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
return { lhs, rhs };
|
||||
}
|
||||
|
||||
template<typename MatcherLHS, typename ArgRHS>
|
||||
typename std::enable_if<is_generic_matcher<MatcherLHS>::value, MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type
|
||||
template<typename MatcherLHS, typename ArgRHS>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type
|
||||
operator || (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
return { lhs, rhs };
|
||||
}
|
||||
|
||||
template<typename ArgLHS, typename MatcherRHS>
|
||||
typename std::enable_if<is_generic_matcher<MatcherRHS>::value, MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
|
||||
template<typename ArgLHS, typename MatcherRHS>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
|
||||
operator || (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
return { lhs, rhs };
|
||||
}
|
||||
|
||||
|
||||
// avoid deep nesting of matcher templates
|
||||
template<typename... MatchersLHS, typename... MatchersRHS>
|
||||
MatchAllOfGeneric<MatchersLHS..., MatchersRHS...>
|
||||
operator && (MatchAllOfGeneric<MatchersLHS...> && lhs, MatchAllOfGeneric<MatchersRHS...> && rhs) {
|
||||
return MatchAllOfGeneric<MatchersLHS..., MatchersRHS...>{array_cat(std::move(lhs.m_matchers), std::move(rhs.m_matchers))};
|
||||
}
|
||||
// avoid deep nesting of matcher templates
|
||||
template<typename... MatchersLHS, typename... MatchersRHS>
|
||||
Detail::MatchAllOfGeneric<MatchersLHS..., MatchersRHS...>
|
||||
operator && (Detail::MatchAllOfGeneric<MatchersLHS...>&& lhs, Detail::MatchAllOfGeneric<MatchersRHS...>&& rhs) {
|
||||
return Detail::MatchAllOfGeneric<MatchersLHS..., MatchersRHS...>{Detail::array_cat(std::move(lhs.m_matchers), std::move(rhs.m_matchers))};
|
||||
}
|
||||
|
||||
template<typename... MatchersLHS, typename MatcherRHS>
|
||||
typename std::enable_if<is_matcher<MatcherRHS>::value, MatchAllOfGeneric<MatchersLHS..., MatcherRHS>>::type
|
||||
operator && (MatchAllOfGeneric<MatchersLHS...> && lhs, MatcherRHS const& rhs) {
|
||||
return MatchAllOfGeneric<MatchersLHS..., MatcherRHS>{array_cat(std::move(lhs.m_matchers), static_cast<void const*>(&rhs))};
|
||||
}
|
||||
template<typename... MatchersLHS, typename MatcherRHS>
|
||||
typename std::enable_if<Detail::is_matcher<MatcherRHS>::value, Detail::MatchAllOfGeneric<MatchersLHS..., MatcherRHS>>::type
|
||||
operator && (Detail::MatchAllOfGeneric<MatchersLHS...>&& lhs, MatcherRHS const& rhs) {
|
||||
return Detail::MatchAllOfGeneric<MatchersLHS..., MatcherRHS>{Detail::array_cat(std::move(lhs.m_matchers), static_cast<void const*>(&rhs))};
|
||||
}
|
||||
|
||||
template<typename MatcherLHS, typename... MatchersRHS>
|
||||
typename std::enable_if<is_matcher<MatcherLHS>::value, MatchAllOfGeneric<MatcherLHS, MatchersRHS...>>::type
|
||||
operator && (MatcherLHS const& lhs, MatchAllOfGeneric<MatchersRHS...> && rhs) {
|
||||
return MatchAllOfGeneric<MatcherLHS, MatchersRHS...>{array_cat(static_cast<void const*>(std::addressof(lhs)), std::move(rhs.m_matchers))};
|
||||
}
|
||||
template<typename MatcherLHS, typename... MatchersRHS>
|
||||
typename std::enable_if<Detail::is_matcher<MatcherLHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatchersRHS...>>::type
|
||||
operator && (MatcherLHS const& lhs, Detail::MatchAllOfGeneric<MatchersRHS...>&& rhs) {
|
||||
return Detail::MatchAllOfGeneric<MatcherLHS, MatchersRHS...>{Detail::array_cat(static_cast<void const*>(std::addressof(lhs)), std::move(rhs.m_matchers))};
|
||||
}
|
||||
|
||||
template<typename... MatchersLHS, typename... MatchersRHS>
|
||||
MatchAnyOfGeneric<MatchersLHS..., MatchersRHS...>
|
||||
operator || (MatchAnyOfGeneric<MatchersLHS...> && lhs, MatchAnyOfGeneric<MatchersRHS...> && rhs) {
|
||||
return MatchAnyOfGeneric<MatchersLHS..., MatchersRHS...>{array_cat(std::move(lhs.m_matchers), std::move(rhs.m_matchers))};
|
||||
}
|
||||
template<typename... MatchersLHS, typename... MatchersRHS>
|
||||
Detail::MatchAnyOfGeneric<MatchersLHS..., MatchersRHS...>
|
||||
operator || (Detail::MatchAnyOfGeneric<MatchersLHS...>&& lhs, Detail::MatchAnyOfGeneric<MatchersRHS...>&& rhs) {
|
||||
return Detail::MatchAnyOfGeneric<MatchersLHS..., MatchersRHS...>{Detail::array_cat(std::move(lhs.m_matchers), std::move(rhs.m_matchers))};
|
||||
}
|
||||
|
||||
template<typename... MatchersLHS, typename MatcherRHS>
|
||||
typename std::enable_if<is_matcher<MatcherRHS>::value, MatchAnyOfGeneric<MatchersLHS..., MatcherRHS>>::type
|
||||
operator || (MatchAnyOfGeneric<MatchersLHS...> && lhs, MatcherRHS const& rhs) {
|
||||
return MatchAnyOfGeneric<MatchersLHS..., MatcherRHS>{array_cat(std::move(lhs.m_matchers), static_cast<void const*>(std::addressof(rhs)))};
|
||||
}
|
||||
template<typename... MatchersLHS, typename MatcherRHS>
|
||||
typename std::enable_if<Detail::is_matcher<MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatchersLHS..., MatcherRHS>>::type
|
||||
operator || (Detail::MatchAnyOfGeneric<MatchersLHS...>&& lhs, MatcherRHS const& rhs) {
|
||||
return Detail::MatchAnyOfGeneric<MatchersLHS..., MatcherRHS>{Detail::array_cat(std::move(lhs.m_matchers), static_cast<void const*>(std::addressof(rhs)))};
|
||||
}
|
||||
|
||||
template<typename MatcherLHS, typename... MatchersRHS>
|
||||
typename std::enable_if<is_matcher<MatcherLHS>::value, MatchAnyOfGeneric<MatcherLHS, MatchersRHS...>>::type
|
||||
operator || (MatcherLHS const& lhs, MatchAnyOfGeneric<MatchersRHS...> && rhs) {
|
||||
return MatchAnyOfGeneric<MatcherLHS, MatchersRHS...>{array_cat(static_cast<void const*>(std::addressof(lhs)), std::move(rhs.m_matchers))};
|
||||
}
|
||||
template<typename MatcherLHS, typename... MatchersRHS>
|
||||
typename std::enable_if<Detail::is_matcher<MatcherLHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatchersRHS...>>::type
|
||||
operator || (MatcherLHS const& lhs, Detail::MatchAnyOfGeneric<MatchersRHS...>&& rhs) {
|
||||
return Detail::MatchAnyOfGeneric<MatcherLHS, MatchersRHS...>{Detail::array_cat(static_cast<void const*>(std::addressof(lhs)), std::move(rhs.m_matchers))};
|
||||
}
|
||||
|
||||
template<typename MatcherT>
|
||||
MatcherT const& operator ! (MatchNotOfGeneric<MatcherT> const& matcher) {
|
||||
return matcher.m_matcher;
|
||||
}
|
||||
template<typename MatcherT>
|
||||
MatcherT const& operator ! (Detail::MatchNotOfGeneric<MatcherT> const& matcher) {
|
||||
return matcher.m_matcher;
|
||||
}
|
||||
|
||||
} // namespace Impl
|
||||
|
||||
} // namespace Matchers
|
||||
|
||||
using namespace Matchers;
|
||||
using Matchers::Impl::MatcherGenericBase;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#endif //TWOBLUECUBES_CATCH_MATCHERS_TEMPLATES_HPP_INCLUDED
|
||||
|
Reference in New Issue
Block a user