| /* |
| * Created by Phil on 04/03/2011. |
| * Copyright 2011 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_EVALUATE_HPP_INCLUDED |
| #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED |
| |
| #ifdef _MSC_VER |
| #pragma warning(push) |
| #pragma warning(disable:4389) // '==' : signed/unsigned mismatch |
| #endif |
| |
| #include <cstddef> |
| |
| namespace Catch { |
| namespace Internal { |
| |
| enum Operator { |
| IsEqualTo, |
| IsNotEqualTo, |
| IsLessThan, |
| IsGreaterThan, |
| IsLessThanOrEqualTo, |
| IsGreaterThanOrEqualTo |
| }; |
| |
| template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } }; |
| template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } }; |
| template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } }; |
| template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } }; |
| template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } }; |
| template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } }; |
| template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } }; |
| |
| template<typename T> |
| inline T& opCast(T const& t) { return const_cast<T&>(t); } |
| |
| // nullptr_t support based on pull request #154 from Konstantin Baumann |
| #ifdef CATCH_CONFIG_CPP11_NULLPTR |
| inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } |
| #endif // CATCH_CONFIG_CPP11_NULLPTR |
| |
| |
| // So the compare overloads can be operator agnostic we convey the operator as a template |
| // enum, which is used to specialise an Evaluator for doing the comparison. |
| template<typename T1, typename T2, Operator Op> |
| class Evaluator{}; |
| |
| template<typename T1, typename T2> |
| struct Evaluator<T1, T2, IsEqualTo> { |
| static bool evaluate( T1 const& lhs, T2 const& rhs) { |
| return opCast( lhs ) == opCast( rhs ); |
| } |
| }; |
| template<typename T1, typename T2> |
| struct Evaluator<T1, T2, IsNotEqualTo> { |
| static bool evaluate( T1 const& lhs, T2 const& rhs ) { |
| return opCast( lhs ) != opCast( rhs ); |
| } |
| }; |
| template<typename T1, typename T2> |
| struct Evaluator<T1, T2, IsLessThan> { |
| static bool evaluate( T1 const& lhs, T2 const& rhs ) { |
| return opCast( lhs ) < opCast( rhs ); |
| } |
| }; |
| template<typename T1, typename T2> |
| struct Evaluator<T1, T2, IsGreaterThan> { |
| static bool evaluate( T1 const& lhs, T2 const& rhs ) { |
| return opCast( lhs ) > opCast( rhs ); |
| } |
| }; |
| template<typename T1, typename T2> |
| struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> { |
| static bool evaluate( T1 const& lhs, T2 const& rhs ) { |
| return opCast( lhs ) >= opCast( rhs ); |
| } |
| }; |
| template<typename T1, typename T2> |
| struct Evaluator<T1, T2, IsLessThanOrEqualTo> { |
| static bool evaluate( T1 const& lhs, T2 const& rhs ) { |
| return opCast( lhs ) <= opCast( rhs ); |
| } |
| }; |
| |
| template<Operator Op, typename T1, typename T2> |
| bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { |
| return Evaluator<T1, T2, Op>::evaluate( lhs, rhs ); |
| } |
| |
| // This level of indirection allows us to specialise for integer types |
| // to avoid signed/ unsigned warnings |
| |
| // "base" overload |
| template<Operator Op, typename T1, typename T2> |
| bool compare( T1 const& lhs, T2 const& rhs ) { |
| return Evaluator<T1, T2, Op>::evaluate( lhs, rhs ); |
| } |
| |
| // unsigned X to int |
| template<Operator Op> bool compare( unsigned int lhs, int rhs ) { |
| return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); |
| } |
| template<Operator Op> bool compare( unsigned long lhs, int rhs ) { |
| return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); |
| } |
| template<Operator Op> bool compare( unsigned char lhs, int rhs ) { |
| return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); |
| } |
| |
| // unsigned X to long |
| template<Operator Op> bool compare( unsigned int lhs, long rhs ) { |
| return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) ); |
| } |
| template<Operator Op> bool compare( unsigned long lhs, long rhs ) { |
| return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) ); |
| } |
| template<Operator Op> bool compare( unsigned char lhs, long rhs ) { |
| return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) ); |
| } |
| |
| // int to unsigned X |
| template<Operator Op> bool compare( int lhs, unsigned int rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( int lhs, unsigned long rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( int lhs, unsigned char rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs ); |
| } |
| |
| // long to unsigned X |
| template<Operator Op> bool compare( long lhs, unsigned int rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( long lhs, unsigned long rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( long lhs, unsigned char rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); |
| } |
| |
| // pointer to long (when comparing against NULL) |
| template<Operator Op, typename T> bool compare( long lhs, T* rhs ) { |
| return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs ); |
| } |
| template<Operator Op, typename T> bool compare( T* lhs, long rhs ) { |
| return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); |
| } |
| |
| // pointer to int (when comparing against NULL) |
| template<Operator Op, typename T> bool compare( int lhs, T* rhs ) { |
| return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs ); |
| } |
| template<Operator Op, typename T> bool compare( T* lhs, int rhs ) { |
| return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); |
| } |
| |
| #ifdef CATCH_CONFIG_CPP11_LONG_LONG |
| // long long to unsigned X |
| template<Operator Op> bool compare( long long lhs, unsigned int rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( long long lhs, unsigned long rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( long long lhs, unsigned char rhs ) { |
| return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); |
| } |
| |
| // unsigned long long to X |
| template<Operator Op> bool compare( unsigned long long lhs, int rhs ) { |
| return applyEvaluator<Op>( static_cast<long>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( unsigned long long lhs, long rhs ) { |
| return applyEvaluator<Op>( static_cast<long>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) { |
| return applyEvaluator<Op>( static_cast<long>( lhs ), rhs ); |
| } |
| template<Operator Op> bool compare( unsigned long long lhs, char rhs ) { |
| return applyEvaluator<Op>( static_cast<long>( lhs ), rhs ); |
| } |
| |
| // pointer to long long (when comparing against NULL) |
| template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) { |
| return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs ); |
| } |
| template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) { |
| return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); |
| } |
| #endif // CATCH_CONFIG_CPP11_LONG_LONG |
| |
| #ifdef CATCH_CONFIG_CPP11_NULLPTR |
| // pointer to nullptr_t (when comparing against nullptr) |
| template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) { |
| return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs ); |
| } |
| template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) { |
| return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr ); |
| } |
| #endif // CATCH_CONFIG_CPP11_NULLPTR |
| |
| } // end of namespace Internal |
| } // end of namespace Catch |
| |
| #ifdef _MSC_VER |
| #pragma warning(pop) |
| #endif |
| |
| #endif // TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED |