From 07b9bda1d212de50a8f5a1fb73cdf1f8dca05fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Thu, 7 Dec 2017 19:46:26 +0100 Subject: [PATCH] Revert backport of new evaluate layer to fix C++98 compilation The backport fixed some bugs (ie #981), but caused strict C++98 (and MSVC 9) compilers to fail. This means that we will reintroduce some issues but get back compatibility with obsolete compilers. People using newer ones can keep using Catch2. This reverts commit b6e7c9bd7a160c07c5de894292022687895c17a3. This reverts commit b7bd52cc98f8a9b646a13241ce8355ba97b8bab3. Should fix #1103 --- include/internal/catch_evaluate.hpp | 189 +++++++++++++++------- include/internal/catch_expression_lhs.hpp | 2 +- 2 files changed, 132 insertions(+), 59 deletions(-) diff --git a/include/internal/catch_evaluate.hpp b/include/internal/catch_evaluate.hpp index 8a7ed288..19323132 100644 --- a/include/internal/catch_evaluate.hpp +++ b/include/internal/catch_evaluate.hpp @@ -38,10 +38,12 @@ namespace Internal { template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; template - T& removeConst(T const &t) { return const_cast(t); } + T& opCast(T const& t) { return const_cast(t); } + +// nullptr_t support based on pull request #154 from Konstantin Baumann #ifdef CATCH_CONFIG_CPP11_NULLPTR - inline std::nullptr_t removeConst(std::nullptr_t) { return nullptr; } -#endif + 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 @@ -52,90 +54,161 @@ namespace Internal { template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs) { - return bool(removeConst(lhs) == removeConst(rhs) ); + return bool( opCast( lhs ) == opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) != removeConst(rhs) ); + return bool( opCast( lhs ) != opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) < removeConst(rhs) ); + return bool( opCast( lhs ) < opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) > removeConst(rhs) ); + return bool( opCast( lhs ) > opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) >= removeConst(rhs) ); + return bool( opCast( lhs ) >= opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) <= removeConst(rhs) ); + return bool( opCast( lhs ) <= opCast( rhs ) ); } }; - // Special case for comparing a pointer to an int (deduced for p==0) - template - struct Evaluator { - static bool evaluate( int lhs, T* rhs) { - return reinterpret_cast( lhs ) == rhs; - } - }; - template - struct Evaluator { - static bool evaluate( T* lhs, int rhs) { - return lhs == reinterpret_cast( rhs ); - } - }; - template - struct Evaluator { - static bool evaluate( int lhs, T* rhs) { - return reinterpret_cast( lhs ) != rhs; - } - }; - template - struct Evaluator { - static bool evaluate( T* lhs, int rhs) { - return lhs != reinterpret_cast( rhs ); - } - }; + template + bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } - template - struct Evaluator { - static bool evaluate( long lhs, T* rhs) { - return reinterpret_cast( lhs ) == rhs; - } - }; - template - struct Evaluator { - static bool evaluate( T* lhs, long rhs) { - return lhs == reinterpret_cast( rhs ); - } - }; - template - struct Evaluator { - static bool evaluate( long lhs, T* rhs) { - return reinterpret_cast( lhs ) != rhs; - } - }; - template - struct Evaluator { - static bool evaluate( T* lhs, long rhs) { - return lhs != reinterpret_cast( rhs ); - } - }; + // This level of indirection allows us to specialise for integer types + // to avoid signed/ unsigned warnings + + // "base" overload + template + bool compare( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } + + // unsigned X to int + template bool compare( unsigned int lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // unsigned X to long + template bool compare( unsigned int lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // int to unsigned X + template bool compare( int lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // long to unsigned X + template bool compare( long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long (when comparing against NULL) + template bool compare( long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + + // pointer to int (when comparing against NULL) + template bool compare( int lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, int rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG + // long long to unsigned X + template bool compare( long long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // unsigned long long to X + template bool compare( unsigned long long lhs, int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long long (when comparing against NULL) + template bool compare( long long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } +#endif // CATCH_CONFIG_CPP11_LONG_LONG + +#ifdef CATCH_CONFIG_CPP11_NULLPTR + // pointer to nullptr_t (when comparing against nullptr) + template bool compare( std::nullptr_t, T* rhs ) { + return Evaluator::evaluate( nullptr, rhs ); + } + template bool compare( T* lhs, std::nullptr_t ) { + return Evaluator::evaluate( lhs, nullptr ); + } +#endif // CATCH_CONFIG_CPP11_NULLPTR } // end of namespace Internal } // end of namespace Catch diff --git a/include/internal/catch_expression_lhs.hpp b/include/internal/catch_expression_lhs.hpp index d809f96f..7133e09b 100644 --- a/include/internal/catch_expression_lhs.hpp +++ b/include/internal/catch_expression_lhs.hpp @@ -111,7 +111,7 @@ public: void endExpression() const { m_rb - .setResultType( Internal::Evaluator::evaluate( m_lhs, m_rhs ) ) + .setResultType( Internal::compare( m_lhs, m_rhs ) ) .endExpression( *this ); }