Listing 1: The assert_cast function templates

// cast.h  definitions for assert_cast

#ifndef CAST_H_A2434B93
#define CAST_H_A2434B93

#include <assert.h>

// assert_cast is similar to dynamic_cast; it differs in that 
// (1) RTTI, with its (small) associated cost in executable size 
// and speed, is used only in Debug mode (i.e., when NDEBUG is 
// not #defined), and (2) a bad cast is signalled by raising an 
// assertion, rather than by returning 0 or throwing 
// std::bad_cast.

// for pointers
template<typename Result_ptr, typename Source>
inline Result_ptr assert_cast(Source* pSource)
{
    assert ( static_cast<Result_ptr>(pSource) ==
                 dynamic_cast<Result_ptr>(pSource) );
    return static_cast<Result_ptr>(pSource);
}

// for references
template<typename Result_ref, typename Source>
inline Result_ref assert_cast(Source& rSource)
{
#ifndef NDEBUG
    try
    {
        assert ( &static_cast<Result_ref>(rSource) ==
                    &dynamic_cast<Result_ref>(rSource) );
    }
    catch(...)
    {
        // convert exceptions to assertions to prevent them 
        // from being "handled"
        assert(false);
    }
#endif
    return static_cast<Result_ref>(rSource);
}

#endif  // CAST_H_A2434B93