mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 20:27:11 +01:00 
			
		
		
		
	Cherry-picked "evaluate" refactoring from dev-modernize branch
- fixed up NULL comparisons to allow for NULL being a long - should address #981
This commit is contained in:
		 Phil Nash
					Phil Nash
				
			
				
					committed by
					
						 Martin Hořeňovský
						Martin Hořeňovský
					
				
			
			
				
	
			
			
			 Martin Hořeňovský
						Martin Hořeňovský
					
				
			
						parent
						
							b07a2bdf87
						
					
				
				
					commit
					b7bd52cc98
				
			| @@ -37,12 +37,7 @@ namespace Internal { | ||||
|     template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } }; | ||||
|  | ||||
|     template<typename T> | ||||
|     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 | ||||
|     T& removeConst(T const &t) { return const_cast<T&>(t); } | ||||
|  | ||||
|  | ||||
|     // So the compare overloads can be operator agnostic we convey the operator as a template | ||||
| @@ -53,161 +48,90 @@ namespace Internal { | ||||
|     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 ) ); | ||||
|             return bool(removeConst(lhs) == removeConst(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 ) ); | ||||
|             return bool(removeConst(lhs) != removeConst(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 ) ); | ||||
|             return bool(removeConst(lhs) < removeConst(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 ) ); | ||||
|             return bool(removeConst(lhs) > removeConst(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 ) ); | ||||
|             return bool(removeConst(lhs) >= removeConst(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 ) ); | ||||
|             return bool(removeConst(lhs) <= removeConst(rhs) ); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     template<Operator Op, typename T1, typename T2> | ||||
|     bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { | ||||
|         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs ); | ||||
|     } | ||||
|     // Special case for comparing a pointer to an int (deduced for p==0) | ||||
|     template<typename T> | ||||
|     struct Evaluator<int const&, T* const&, IsEqualTo> { | ||||
|         static bool evaluate( int lhs, T* rhs) { | ||||
|             return reinterpret_cast<void const*>( lhs ) ==  rhs; | ||||
|         } | ||||
|     }; | ||||
|     template<typename T> | ||||
|     struct Evaluator<T* const&, int const&, IsEqualTo> { | ||||
|         static bool evaluate( T* lhs, int rhs) { | ||||
|             return lhs == reinterpret_cast<void const*>( rhs ); | ||||
|         } | ||||
|     }; | ||||
|     template<typename T> | ||||
|     struct Evaluator<int const&, T* const&, IsNotEqualTo> { | ||||
|         static bool evaluate( int lhs, T* rhs) { | ||||
|             return reinterpret_cast<void const*>( lhs ) !=  rhs; | ||||
|         } | ||||
|     }; | ||||
|     template<typename T> | ||||
|     struct Evaluator<T* const&, int const&, IsNotEqualTo> { | ||||
|         static bool evaluate( T* lhs, int rhs) { | ||||
|             return lhs != reinterpret_cast<void const*>( 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 | ||||
|     template<typename T> | ||||
|     struct Evaluator<long const&, T* const&, IsEqualTo> { | ||||
|         static bool evaluate( long lhs, T* rhs) { | ||||
|             return reinterpret_cast<void const*>( lhs ) ==  rhs; | ||||
|         } | ||||
|     }; | ||||
|     template<typename T> | ||||
|     struct Evaluator<T* const&, long const&, IsEqualTo> { | ||||
|         static bool evaluate( T* lhs, long rhs) { | ||||
|             return lhs == reinterpret_cast<void const*>( rhs ); | ||||
|         } | ||||
|     }; | ||||
|     template<typename T> | ||||
|     struct Evaluator<long const&, T* const&, IsNotEqualTo> { | ||||
|         static bool evaluate( long lhs, T* rhs) { | ||||
|             return reinterpret_cast<void const*>( lhs ) !=  rhs; | ||||
|         } | ||||
|     }; | ||||
|     template<typename T> | ||||
|     struct Evaluator<T* const&, long const&, IsNotEqualTo> { | ||||
|         static bool evaluate( T* lhs, long rhs) { | ||||
|             return lhs != reinterpret_cast<void const*>( rhs ); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| } // end of namespace Internal | ||||
| } // end of namespace Catch | ||||
|   | ||||
| @@ -111,7 +111,7 @@ public: | ||||
|  | ||||
|     void endExpression() const { | ||||
|         m_rb | ||||
|             .setResultType( Internal::compare<Op>( m_lhs, m_rhs ) ) | ||||
|             .setResultType(  Internal::Evaluator<LhsT, RhsT, Op>::evaluate( m_lhs, m_rhs ) ) | ||||
|             .endExpression( *this ); | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user