From d8a3ffedbae45f2797847fa686283da967818e72 Mon Sep 17 00:00:00 2001 From: Konstantin Baumann Date: Thu, 31 Jan 2013 10:50:04 +0100 Subject: [PATCH] enhanced support for nullptr these fixes enhance the support for C++11 nullptr/std::nullptr_t; now you can write something like this: std::exception_ptr ex; CATCH_REQUIRE(ex == nullptr); and std::unique_ptr ptr; CATCH_REQUIRE(ptr.get() == nullptr); The issue with the const_cast is that you cannot cast a std::nullptr_t to a non-const-ref. --- include/internal/catch_evaluate.hpp | 34 ++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) 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