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

View File

@@ -28,6 +28,13 @@ namespace Internal {
template<> struct OperatorTraits<IsLessThanOrEqualTo> { 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
// enum, which is used to specialise an Evaluator for doing the comparison.
template<typename T1, typename T2, Operator Op>
@@ -36,37 +43,37 @@ namespace Internal {
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsEqualTo> {
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>
struct Evaluator<T1, T2, IsNotEqualTo> {
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>
struct Evaluator<T1, T2, IsLessThan> {
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>
struct Evaluator<T1, T2, IsGreaterThan> {
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>
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
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>
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
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 ) {
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 Catch

View File

@@ -13,7 +13,7 @@
namespace Catch {
// 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