Pointer comparisons and compare to NULL

This commit is contained in:
Phil Nash 2011-03-18 14:39:58 +00:00
parent 1e15669f2a
commit ef611c65d9
3 changed files with 137 additions and 3 deletions

View File

@ -214,6 +214,19 @@ TEST_CASE( "./failing/conditions/unsigned-negative", "Comparisons between negati
CHECK( negative == ui ); CHECK( negative == ui );
} }
TEST_CASE( "./succeeding/conditions/ptr", "Pointers can be compared to null" )
{
TestData* p = NULL;
TestData* pNULL = NULL;
REQUIRE( p == NULL );
REQUIRE( p == pNULL );
TestData data;
p = &data;
REQUIRE( p != NULL );
}
// Not (!) tests // Not (!) tests
// The problem with the ! operator is that it has right-to-left associativity. // The problem with the ! operator is that it has right-to-left associativity.
// This means we can't isolate it when we decompose. The simple REQUIRE( !false ) form, therefore, // This means we can't isolate it when we decompose. The simple REQUIRE( !false ) form, therefore,

View File

@ -155,6 +155,39 @@ inline std::string toString
return value ? "true" : "false"; return value ? "true" : "false";
} }
///////////////////////////////////////////////////////////////////////////////
inline std::string toString
(
void* p
)
{
if( !p )
return INTERNAL_CATCH_STRINGIFY( NULL );
std::ostringstream oss;
oss << p;
return oss.str();
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline std::string toString
(
T* p
)
{
return toString( static_cast<void*>( p ) );
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline std::string toString
(
const T* p
)
{
return toString( static_cast<void*>( const_cast<T*>( p ) ) );
}
struct TestFailureException struct TestFailureException
{ {
}; };
@ -226,8 +259,9 @@ public:
private: private:
friend class ResultBuilder; friend class ResultBuilder;
template<typename T> template<typename T> friend class Expression;
friend class Expression;
template<typename T> friend class PtrExpression;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
MutableResultInfo& captureBoolExpression MutableResultInfo& captureBoolExpression
@ -361,6 +395,66 @@ private:
const T& m_lhs; const T& m_lhs;
}; };
template<typename LhsT>
class PtrExpression
{
public:
///////////////////////////////////////////////////////////////////////////
PtrExpression
(
MutableResultInfo& result,
const LhsT* lhs
)
: m_result( result ),
m_lhs( lhs )
{}
///////////////////////////////////////////////////////////////////////////
template<typename RhsT>
MutableResultInfo& operator ==
(
const RhsT* rhs
)
{
return m_result.captureExpression<Internal::IsEqualTo>( m_lhs, rhs );
}
///////////////////////////////////////////////////////////////////////////
// This catches NULL
MutableResultInfo& operator ==
(
LhsT* rhs
)
{
return m_result.captureExpression<Internal::IsEqualTo>( m_lhs, rhs );
}
///////////////////////////////////////////////////////////////////////////
template<typename RhsT>
MutableResultInfo& operator !=
(
const RhsT* rhs
)
{
return m_result.captureExpression<Internal::IsNotEqualTo>( m_lhs, rhs );
}
///////////////////////////////////////////////////////////////////////////
// This catches NULL
MutableResultInfo& operator !=
(
LhsT* rhs
)
{
return m_result.captureExpression<Internal::IsNotEqualTo>( m_lhs, rhs );
}
private:
MutableResultInfo& m_result;
const LhsT* m_lhs;
};
class ResultBuilder class ResultBuilder
{ {
public: public:
@ -389,6 +483,30 @@ public:
return expr; return expr;
} }
///////////////////////////////////////////////////////////////////////////
template<typename T>
PtrExpression<T> operator->*
(
const T* operand
)
{
PtrExpression<T> expr( m_result, operand );
return expr;
}
///////////////////////////////////////////////////////////////////////////
template<typename T>
PtrExpression<T> operator->*
(
T* operand
)
{
PtrExpression<T> expr( m_result, operand );
return expr;
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template<typename T> template<typename T>
ResultBuilder& operator << ResultBuilder& operator <<
@ -478,7 +596,7 @@ class Approx
public: public:
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// !TBD more generic // !TBD more generic
Approx explicit Approx
( (
double d double d
) )

View File

@ -17,6 +17,9 @@
#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
#ifdef __GNUC__ #ifdef __GNUC__
#define ATTRIBUTE_NORETURN __attribute__ ((noreturn)) #define ATTRIBUTE_NORETURN __attribute__ ((noreturn))
#else #else