| 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 Matchersusing namespace Matchers;using Matchers::Impl::MatcherBase;} // namespace Catch#endif // TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
 |