diff --git a/include/internal/catch_evaluate.hpp b/include/internal/catch_evaluate.hpp index 7e9d57d0..ca301079 100644 --- a/include/internal/catch_evaluate.hpp +++ b/include/internal/catch_evaluate.hpp @@ -33,40 +33,52 @@ namespace Internal { template class Evaluator{}; + template + inline T& catch_const_cast(const T& t) { return const_cast(t); } + +#ifdef CATCH_CONFIG_CPP11_NULLPTR + inline std::nullptr_t catch_const_cast(const 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 + class Evaluator{}; + template struct Evaluator { static bool evaluate( const T1& lhs, const T2& rhs) { - return const_cast( lhs ) == const_cast( rhs ); + return catch_const_cast( lhs ) == catch_const_cast( rhs ); } }; template struct Evaluator { static bool evaluate( const T1& lhs, const T2& rhs ) { - return const_cast( lhs ) != const_cast( rhs ); + return catch_const_cast( lhs ) != catch_const_cast( rhs ); } }; template struct Evaluator { static bool evaluate( const T1& lhs, const T2& rhs ) { - return const_cast( lhs ) < const_cast( rhs ); + return catch_const_cast( lhs ) < catch_const_cast( rhs ); } }; template struct Evaluator { static bool evaluate( const T1& lhs, const T2& rhs ) { - return const_cast( lhs ) > const_cast( rhs ); + return catch_const_cast( lhs ) > catch_const_cast( rhs ); } }; template struct Evaluator { static bool evaluate( const T1& lhs, const T2& rhs ) { - return const_cast( lhs ) >= const_cast( rhs ); + return catch_const_cast( lhs ) >= catch_const_cast( rhs ); } }; template struct Evaluator { static bool evaluate( const T1& lhs, const T2& rhs ) { - return const_cast( lhs ) <= const_cast( rhs ); + return catch_const_cast( lhs ) <= catch_const_cast( rhs ); } }; @@ -144,6 +156,16 @@ namespace Internal { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } +#ifdef CATCH_CONFIG_CPP11_NULLPTR + // nullptr_t to T-pointer (when comparing against nullptr) + template bool compare( std::nullptr_t lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, std::nullptr_t rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } +#endif // CATCH_CONFIG_CPP11_NULLPTR + } // end of namespace Internal } // end of namespace Catch