From 2b74613c545203794d15df51ad710c36b1f0a0fe Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Mon, 6 Feb 2017 22:37:23 +0000 Subject: [PATCH] Revert "First cut of Evaluate refactoring to remove int specialisations, among other things" This reverts commit 39753558eb635886555a07e0fa01ee72816c06f6. --- include/internal/catch_assertionresult.h | 22 +-- include/internal/catch_evaluate.hpp | 168 ++++++++++++++++------ include/internal/catch_expression_lhs.hpp | 31 ++-- include/internal/catch_result_builder.h | 2 +- include/internal/catch_result_builder.hpp | 4 +- 5 files changed, 150 insertions(+), 77 deletions(-) diff --git a/include/internal/catch_assertionresult.h b/include/internal/catch_assertionresult.h index d84cbec3f0..e2b979f8ce 100644 --- a/include/internal/catch_assertionresult.h +++ b/include/internal/catch_assertionresult.h @@ -21,25 +21,7 @@ namespace Catch { virtual bool isBinaryExpression() const { return false; } - virtual std::string reconstructExpression() const = 0; - - std::string reconstructExpressionImpl( std::string const& lhs, std::string const& rhs, std::string const& op ) const { - std::string dest; - char delim = lhs.size() + rhs.size() < 40 && - lhs.find('\n') == std::string::npos && - rhs.find('\n') == std::string::npos ? ' ' : '\n'; - dest.reserve( 7 + lhs.size() + rhs.size() ); - // 2 for spaces around operator - // 2 for operator - // 2 for parentheses (conditionally added later) - // 1 for negation (conditionally added later) - dest = lhs; - dest += delim; - dest += op; - dest += delim; - dest += rhs; - return dest; - } + virtual void reconstructExpression( std::string& dest ) const = 0; // Only simple binary comparisons can be decomposed. // If more complex check is required then wrap sub-expressions in parentheses. @@ -84,7 +66,7 @@ namespace Catch { std::string const& reconstructExpression() const { if( decomposedExpression != CATCH_NULL ) { - reconstructedExpression = decomposedExpression->reconstructExpression(); + decomposedExpression->reconstructExpression( reconstructedExpression ); if( parenthesized ) { reconstructedExpression.insert( 0, 1, '(' ); reconstructedExpression.append( 1, ')' ); diff --git a/include/internal/catch_evaluate.hpp b/include/internal/catch_evaluate.hpp index 15878c6da4..b2f47cddb2 100644 --- a/include/internal/catch_evaluate.hpp +++ b/include/internal/catch_evaluate.hpp @@ -46,86 +46,166 @@ namespace Internal { // 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 + template class Evaluator{}; - template<> - struct Evaluator { - template - static bool evaluate( T1& lhs, T2& rhs) { - return static_cast( lhs == rhs ); + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs) { + return bool( opCast( lhs ) == opCast( rhs ) ); } }; - template<> - struct Evaluator { - template - static bool evaluate( T1& lhs, T2& rhs ) { - return bool( lhs != rhs ); + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) != opCast( rhs ) ); } }; - template<> - struct Evaluator { - template - static bool evaluate( T1& lhs, T2& rhs ) { - return bool( lhs < rhs ); + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) < opCast( rhs ) ); } }; - template<> - struct Evaluator { - template - static bool evaluate( T1& lhs, T2& rhs ) { - return bool( lhs > rhs ); + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) > opCast( rhs ) ); } }; - template<> - struct Evaluator { - template - static bool evaluate( T1& lhs, T2& rhs ) { - return bool( lhs >= rhs ); + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) >= opCast( rhs ) ); } }; - template<> - struct Evaluator { - template - static bool evaluate( T1& lhs, T2& rhs ) { - return bool( lhs <= rhs ); + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) <= opCast( rhs ) ); } }; + template + bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, 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( opCast( lhs ), opCast( 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( opCast( reinterpret_cast( lhs ) ), opCast( rhs ) ); + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, long rhs ) { - return Evaluator::evaluate( opCast( lhs ), opCast( reinterpret_cast( 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( opCast( reinterpret_cast( lhs ) ), opCast( rhs ) ); + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, int rhs ) { - return Evaluator::evaluate( opCast( lhs ), opCast( reinterpret_cast( rhs ) ) ); + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } -// Needed? +#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 ); -// } + // 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 diff --git a/include/internal/catch_expression_lhs.hpp b/include/internal/catch_expression_lhs.hpp index 528796cfdd..33a0cb11dd 100644 --- a/include/internal/catch_expression_lhs.hpp +++ b/include/internal/catch_expression_lhs.hpp @@ -78,8 +78,8 @@ class ExpressionLhs : public DecomposedExpression { .endExpression( *this ); } - virtual std::string reconstructExpression() const CATCH_OVERRIDE { - return Catch::toString( m_truthy ); + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + dest = Catch::toString( m_truthy ); } private: @@ -115,11 +115,22 @@ class BinaryExpression : public DecomposedExpression { return true; } - virtual std::string reconstructExpression() const CATCH_OVERRIDE { - return reconstructExpressionImpl - (Catch::toString( m_lhs ), - Catch::toString( m_rhs ), - Internal::OperatorTraits::getName() ); + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + std::string lhs = Catch::toString( m_lhs ); + std::string rhs = Catch::toString( m_rhs ); + char delim = lhs.size() + rhs.size() < 40 && + lhs.find('\n') == std::string::npos && + rhs.find('\n') == std::string::npos ? ' ' : '\n'; + dest.reserve( 7 + lhs.size() + rhs.size() ); + // 2 for spaces around operator + // 2 for operator + // 2 for parentheses (conditionally added later) + // 1 for negation (conditionally added later) + dest = lhs; + dest += delim; + dest += Internal::OperatorTraits::getName(); + dest += delim; + dest += rhs; } private: @@ -138,14 +149,14 @@ class MatchExpression : public DecomposedExpression { return true; } - virtual std::string reconstructExpression() const CATCH_OVERRIDE { + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { std::string matcherAsString = m_matcher.toString(); - std::string dest = Catch::toString( m_arg ) + " "; + dest = Catch::toString( m_arg ); + dest += ' '; if( matcherAsString == Detail::unprintableString ) dest += m_matcherString; else dest += matcherAsString; - return dest; } private: diff --git a/include/internal/catch_result_builder.h b/include/internal/catch_result_builder.h index 3d262159fa..dfdffd5f51 100644 --- a/include/internal/catch_result_builder.h +++ b/include/internal/catch_result_builder.h @@ -55,7 +55,7 @@ namespace Catch { void endExpression( DecomposedExpression const& expr ); - virtual std::string reconstructExpression() const CATCH_OVERRIDE; + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE; AssertionResult build() const; AssertionResult build( DecomposedExpression const& expr ) const; diff --git a/include/internal/catch_result_builder.hpp b/include/internal/catch_result_builder.hpp index f6da5e852d..7bb2cdc283 100644 --- a/include/internal/catch_result_builder.hpp +++ b/include/internal/catch_result_builder.hpp @@ -132,8 +132,8 @@ namespace Catch { return AssertionResult( m_assertionInfo, data ); } - std::string ResultBuilder::reconstructExpression() const { - return m_assertionInfo.capturedExpression; + void ResultBuilder::reconstructExpression( std::string& dest ) const { + dest = m_assertionInfo.capturedExpression; } } // end namespace Catch