diff options
Diffstat (limited to 'unittest/Catch/include/internal/catch_evaluate.hpp')
-rw-r--r-- | unittest/Catch/include/internal/catch_evaluate.hpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/unittest/Catch/include/internal/catch_evaluate.hpp b/unittest/Catch/include/internal/catch_evaluate.hpp new file mode 100644 index 0000000..b2f47cd --- /dev/null +++ b/unittest/Catch/include/internal/catch_evaluate.hpp @@ -0,0 +1,218 @@ +/* + * 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 bool( opCast( lhs ) == opCast( rhs ) ); + } + }; + template<typename T1, typename T2> + struct Evaluator<T1, T2, IsNotEqualTo> { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) != opCast( rhs ) ); + } + }; + template<typename T1, typename T2> + struct Evaluator<T1, T2, IsLessThan> { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) < opCast( rhs ) ); + } + }; + template<typename T1, typename T2> + struct Evaluator<T1, T2, IsGreaterThan> { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) > opCast( rhs ) ); + } + }; + template<typename T1, typename T2> + struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) >= opCast( rhs ) ); + } + }; + template<typename T1, typename T2> + struct Evaluator<T1, T2, IsLessThanOrEqualTo> { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( 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 |