PageRenderTime 82ms CodeModel.GetById 40ms app.highlight 3ms RepoModel.GetById 37ms app.codeStats 1ms

/mordor/assert.h

http://github.com/mozy/mordor
C Header | 104 lines | 76 code | 18 blank | 10 comment | 7 complexity | 541ba273d2d9c00bcef5b0ed24f6800d MD5 | raw file
  1#ifndef __MORDOR_ASSERT_H__
  2#define __MORDOR_ASSERT_H__
  3// Copyright (c) 2009 - Mozy, Inc.
  4
  5#include "exception.h"
  6#include "log.h"
  7#include "version.h"
  8
  9namespace Mordor {
 10
 11bool isDebuggerAttached();
 12void debugBreak();
 13
 14struct Assertion : virtual Exception
 15{
 16    Assertion(const std::string &expr) : m_expr(expr) {}
 17    ~Assertion() throw() {}
 18
 19    const char *what() const throw() { return m_expr.c_str(); }
 20
 21    static bool throwOnAssertion;
 22private:
 23    std::string m_expr;
 24};
 25
 26}
 27
 28#endif
 29// No include guard - you can include multiple times
 30#ifdef MORDOR_ASSERT
 31#undef MORDOR_ASSERT
 32#endif
 33#ifdef MORDOR_VERIFY
 34#undef MORDOR_VERIFY
 35#endif
 36#ifdef MORDOR_NOTREACHED
 37#undef MORDOR_NOTREACHED
 38#endif
 39
 40#ifdef NDEBUG
 41
 42#ifndef NDEBUG_PERF
 43#define NDEBUG_PERF
 44#endif
 45
 46#define MORDOR_ASSERT(x) ((void)0)
 47#define MORDOR_NOTHROW_ASSERT(x) ((void)0)
 48#define MORDOR_VERIFY(x) ((void)(x))
 49#define MORDOR_NOTHROW_VERIFY(x) ((void)(x))
 50#define MORDOR_NOTREACHED() ::std::terminate();
 51
 52#else
 53
 54#define MORDOR_ASSERT(x)                                                        \
 55    while (!(x)) {                                                              \
 56        MORDOR_LOG_FATAL(::Mordor::Log::root())                                 \
 57            << "ASSERTION: " # x                                                \
 58            << "\nbacktrace:\n" << ::Mordor::to_string(::Mordor::backtrace());  \
 59        if (::Mordor::Assertion::throwOnAssertion)                              \
 60            MORDOR_THROW_EXCEPTION(::Mordor::Assertion(# x));                   \
 61        if (::Mordor::isDebuggerAttached())                                     \
 62            ::Mordor::debugBreak();                                             \
 63        ::std::terminate();                                                     \
 64    }
 65
 66#define MORDOR_NOTHROW_ASSERT(x)                                                \
 67    while (!(x)) {                                                              \
 68        MORDOR_LOG_FATAL(::Mordor::Log::root())                                 \
 69            << "ASSERTION: " # x                                                \
 70            << "\nbacktrace:\n" << ::Mordor::to_string(::Mordor::backtrace());  \
 71        if (::Mordor::isDebuggerAttached())                                     \
 72            ::Mordor::debugBreak();                                             \
 73        ::std::terminate();                                                     \
 74    }
 75
 76#define MORDOR_VERIFY(x) MORDOR_ASSERT(x)
 77#define MORDOR_NOTHROW_VERIFY(x) MORDOR_NOTHROW_ASSERT(x)
 78
 79#define MORDOR_NOTREACHED()                                                     \
 80{                                                                               \
 81    MORDOR_LOG_FATAL(::Mordor::Log::root()) << "NOT REACHED"                    \
 82        << "\nbacktrace:\n" << ::Mordor::to_string(::Mordor::backtrace());      \
 83    if (::Mordor::Assertion::throwOnAssertion)                                  \
 84        MORDOR_THROW_EXCEPTION(::Mordor::Assertion("Not Reached"));             \
 85    if (::Mordor::isDebuggerAttached())                                         \
 86        ::Mordor::debugBreak();                                                 \
 87    ::std::terminate();                                                         \
 88}
 89
 90#endif
 91
 92/// MORDOR_ASSERT_PERF Macro is mostly the same as MORDOR_ASSERT except that
 93/// - MORDOR_ASSERT can be only turned off by defining NDEBUG
 94/// - MORDOR_ASSERT_PERF can be turned off by either NDEBUG or NDEBUG_PERF
 95/// * MORDOR_ASSERT_PERF applies to those assertion that has significant
 96///   performance impact.
 97/// * NDEBUG_PERF can be defined When application don't want to disable all
 98///   assertions but only to those which have big performance impact.
 99/// * NOTE: if NDEBUG is defined, NDEBUG_PERF will be automatically defined.
100#ifndef NDEBUG_PERF
101#define MORDOR_ASSERT_PERF(x) MORDOR_ASSERT(x)
102#else
103#define MORDOR_ASSERT_PERF(x) ((void)0)
104#endif