123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- /*
- * Created by Phil Nash on 04/03/2012.
- * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
- *
- * Distributed under the Boost Software License, Version 1.0. (See accompanying
- * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- */
- #ifndef TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
- #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
- #include "catch_common.h"
- #include <string>
- #include <vector>
- namespace Catch {
- namespace Matchers {
- namespace Impl {
- template<typename ArgT> struct MatchAllOf;
- template<typename ArgT> struct MatchAnyOf;
- template<typename ArgT> struct MatchNotOf;
- class MatcherUntypedBase {
- public:
- MatcherUntypedBase() = default;
- MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
- MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
- std::string toString() const;
- protected:
- virtual ~MatcherUntypedBase();
- 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;
- };
- #if defined(__OBJC__)
- // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
- // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
- template<>
- struct MatcherMethod<NSString*> {
- virtual bool match( NSString* arg ) const = 0;
- };
- #endif
- #ifdef __clang__
- # pragma clang diagnostic pop
- #endif
- template<typename T>
- struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
- MatchAllOf<T> operator && ( MatcherBase const& other ) const;
- MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
- MatchNotOf<T> operator ! () const;
- };
- template<typename ArgT>
- struct MatchAllOf : MatcherBase<ArgT> {
- bool match( ArgT const& arg ) const override {
- for( auto matcher : m_matchers ) {
- if (!matcher->match(arg))
- return false;
- }
- return true;
- }
- std::string describe() const override {
- std::string description;
- description.reserve( 4 + m_matchers.size()*32 );
- description += "( ";
- bool first = true;
- for( auto matcher : m_matchers ) {
- if( first )
- first = false;
- else
- description += " and ";
- description += matcher->toString();
- }
- description += " )";
- return description;
- }
- MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
- auto copy(*this);
- copy.m_matchers.push_back( &other );
- return copy;
- }
- std::vector<MatcherBase<ArgT> const*> m_matchers;
- };
- template<typename ArgT>
- struct MatchAnyOf : MatcherBase<ArgT> {
- bool match( ArgT const& arg ) const override {
- for( auto matcher : m_matchers ) {
- if (matcher->match(arg))
- return true;
- }
- return false;
- }
- std::string describe() const override {
- std::string description;
- description.reserve( 4 + m_matchers.size()*32 );
- description += "( ";
- bool first = true;
- for( auto matcher : m_matchers ) {
- if( first )
- first = false;
- else
- description += " or ";
- description += matcher->toString();
- }
- description += " )";
- return description;
- }
- MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
- auto copy(*this);
- copy.m_matchers.push_back( &other );
- return copy;
- }
- std::vector<MatcherBase<ArgT> const*> m_matchers;
- };
- template<typename ArgT>
- struct MatchNotOf : MatcherBase<ArgT> {
- MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
- bool match( ArgT const& arg ) const override {
- return !m_underlyingMatcher.match( arg );
- }
- std::string describe() const override {
- return "not " + m_underlyingMatcher.toString();
- }
- 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 Impl
- } // namespace Matchers
- using namespace Matchers;
- using Matchers::Impl::MatcherBase;
- } // namespace Catch
- #endif // TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
|