enhanced support for C++11 style nullptr

with these changes you can now write the following tests:

std::exception_ptr ex;
CATCH_REQUIRE(ex == nullptr);

and

std::unique_ptr<int> ptr;
CATCH_REQUIRE(ptr.get() == nullptr);

The issue was that you cannot cast a std::nullptr_t to a non-const
reference.
This commit is contained in:
Konstantin Baumann 2013-01-31 12:25:57 +01:00
parent d658dea1dd
commit 060ed99f0c
4 changed files with 56 additions and 22 deletions

10
README
View File

@ -1,4 +1,4 @@
CATCH v0.9 build 16 (integration branch) CATCH v0.9 build 18 (integration branch)
--------------------------------------------- ---------------------------------------------
CATCH is an automated test framework for C, C++ and Objective-C. CATCH is an automated test framework for C, C++ and Objective-C.
@ -6,9 +6,9 @@ CATCH is an automated test framework for C, C++ and Objective-C.
This branch may contain code that is experimental or not yet fully tested. This branch may contain code that is experimental or not yet fully tested.
The latest stable version can be found on the Master branch. The latest stable version can be found on the Master branch.
For documentation see the wiki at: For documentation see the wiki at:
https://github.com/philsquared/Catch/wiki https://github.com/philsquared/Catch/wiki
Issues and bugs can be raised at: Issues and bugs can be raised at:
https://github.com/philsquared/Catch/issues https://github.com/philsquared/Catch/issues
For discussion or questions please use: For discussion or questions please use:
https://groups.google.com/forum/?fromgroups#!forum/catch-forum https://groups.google.com/forum/?fromgroups#!forum/catch-forum

View File

@ -28,6 +28,13 @@ namespace Internal {
template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } }; template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } }; template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
template<typename T>
inline T& catch_const_cast(const T& t) { return const_cast<T&>(t); }
#ifdef CATCH_CONFIG_CPP11_NULLPTR
inline std::nullptr_t catch_const_cast(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 // 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. // enum, which is used to specialise an Evaluator for doing the comparison.
template<typename T1, typename T2, Operator Op> template<typename T1, typename T2, Operator Op>
@ -36,37 +43,37 @@ namespace Internal {
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsEqualTo> { struct Evaluator<T1, T2, IsEqualTo> {
static bool evaluate( const T1& lhs, const T2& rhs) { static bool evaluate( const T1& lhs, const T2& rhs) {
return const_cast<T1&>( lhs ) == const_cast<T2&>( rhs ); return catch_const_cast( lhs ) == catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsNotEqualTo> { struct Evaluator<T1, T2, IsNotEqualTo> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) != const_cast<T2&>( rhs ); return catch_const_cast( lhs ) != catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsLessThan> { struct Evaluator<T1, T2, IsLessThan> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) < const_cast<T2&>( rhs ); return catch_const_cast( lhs ) < catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsGreaterThan> { struct Evaluator<T1, T2, IsGreaterThan> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) > const_cast<T2&>( rhs ); return catch_const_cast( lhs ) > catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> { struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) >= const_cast<T2&>( rhs ); return catch_const_cast( lhs ) >= catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsLessThanOrEqualTo> { struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) <= const_cast<T2&>( rhs ); return catch_const_cast( lhs ) <= catch_const_cast( rhs );
} }
}; };
@ -143,7 +150,17 @@ namespace Internal {
template<Operator Op, typename T> bool compare( T* lhs, int rhs ) { template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
} }
#ifdef CATCH_CONFIG_CPP11_NULLPTR
// pointer to nullptr_t (when comparing against nullptr)
template<Operator Op, typename T> bool compare( std::nullptr_t lhs, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
#endif // CATCH_CONFIG_CPP11_NULLPTR
} // end of namespace Internal } // end of namespace Internal
} // end of namespace Catch } // end of namespace Catch

View File

@ -13,7 +13,7 @@
namespace Catch { namespace Catch {
// These numbers are maintained by a script // These numbers are maintained by a script
Version libraryVersion( 0, 9, 16, "integration" ); Version libraryVersion( 0, 9, 18, "integration" );
} }
#endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED #endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
/* /*
* CATCH v0.9 build 16 (integration branch) * CATCH v0.9 build 17 (integration branch)
* Generated: 2013-01-26 20:18:07.076275 * Generated: 2013-01-31 12:14:41.781000
* ---------------------------------------------------------- * ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly * This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@ -758,6 +758,13 @@ namespace Internal {
template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } }; template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } }; template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
template<typename T>
inline T& catch_const_cast(const T& t) { return const_cast<T&>(t); }
#ifdef CATCH_CONFIG_CPP11_NULLPTR
inline std::nullptr_t catch_const_cast(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 // 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. // enum, which is used to specialise an Evaluator for doing the comparison.
template<typename T1, typename T2, Operator Op> template<typename T1, typename T2, Operator Op>
@ -766,37 +773,37 @@ namespace Internal {
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsEqualTo> { struct Evaluator<T1, T2, IsEqualTo> {
static bool evaluate( const T1& lhs, const T2& rhs) { static bool evaluate( const T1& lhs, const T2& rhs) {
return const_cast<T1&>( lhs ) == const_cast<T2&>( rhs ); return catch_const_cast( lhs ) == catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsNotEqualTo> { struct Evaluator<T1, T2, IsNotEqualTo> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) != const_cast<T2&>( rhs ); return catch_const_cast( lhs ) != catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsLessThan> { struct Evaluator<T1, T2, IsLessThan> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) < const_cast<T2&>( rhs ); return catch_const_cast( lhs ) < catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsGreaterThan> { struct Evaluator<T1, T2, IsGreaterThan> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) > const_cast<T2&>( rhs ); return catch_const_cast( lhs ) > catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> { struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) >= const_cast<T2&>( rhs ); return catch_const_cast( lhs ) >= catch_const_cast( rhs );
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct Evaluator<T1, T2, IsLessThanOrEqualTo> { struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
static bool evaluate( const T1& lhs, const T2& rhs ) { static bool evaluate( const T1& lhs, const T2& rhs ) {
return const_cast<T1&>( lhs ) <= const_cast<T2&>( rhs ); return catch_const_cast( lhs ) <= catch_const_cast( rhs );
} }
}; };
@ -874,6 +881,16 @@ namespace Internal {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
} }
#ifdef CATCH_CONFIG_CPP11_NULLPTR
// pointer to nullptr_t (when comparing against nullptr)
template<Operator Op, typename T> bool compare( std::nullptr_t lhs, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
#endif // CATCH_CONFIG_CPP11_NULLPTR
} // end of namespace Internal } // end of namespace Internal
} // end of namespace Catch } // end of namespace Catch
@ -5777,7 +5794,7 @@ namespace Catch {
namespace Catch { namespace Catch {
// These numbers are maintained by a script // These numbers are maintained by a script
Version libraryVersion( 0, 9, 16, "integration" ); Version libraryVersion( 0, 9, 17, "integration" );
} }
// #included from: catch_line_wrap.hpp // #included from: catch_line_wrap.hpp