toast assertion library


Detailed Description

Introduction (why assert?)

Motivation (why TOAST_ASSERT?)

Using the library (Assert Liberally)

Introduction (why assert?)

Asserting is one of the simplest ways to find problems early. It's a way of documenting your assumptions and expectations right in the code and test them automatically without any extra effort. As if the benefits of having a nice clean stack trace and core dump when something is wrong weren't enough, you also eliminate the possibility for this documentation to be out of date (or if it is you'll likely find out quickly)!

Motivation (why TOAST_ASSERT?)

The toast assertion library exists as a result of discussion over when and how to assert. If asserting is so great, why do we ever turn it off with NDEBUG in production code?! Well... Is aborting really appropriate when I'm in the middle of manipulating an external data source? Is checking my asserts that important when the critical path is chewing up my CPU?

We decided that in the general case asserts should be left in production code, and asserts should just die. However we also provided ways to address the special cases.

Additionally we provided specially named assertions to take advantage of their documentation value, and their ability to output different information when they trip. This includes limited support for Design by Contract.

Using the library (Assert Liberally)

For the general case there is TOAST_ASSERT, which is always on regardless of whether or not NDEBUG is set, and aborts by default.

If after profiling, the asserts show themselves as a bottle-neck, you don't want them in production code anymore! Of course, you don't just want to lose their documentation value, and you can still check them during development. So for this case there is TOAST_ASSERT_D.

If you're in the middle of manipulating an external data source, or you're managing a resource that won't be released by the program exiting, you don't want them aborting anymore! Again, you still want to check (perhaps even in production), so you can modify asserts to throw a toast::assert_exception by wrapping some code in TOAST_THROW_ASSERTS.

Since we're big on pretty messages we also added a few convenience macros. TOAST_ASSERT_NOT_NULL, TOAST_ASSERT_NULL, and TOAST_ASSERT_MESSAGE. Each of these behave like TOAST_ASSERT and have a counterpart with an _D suffix which behaves like TOAST_ASSERT_D.

Built on top of the basic assertion mechanisms are macros for aiding Programming with Contracts (see example ). These macros are basically convenience wrappers. They make your intentions clearer than just using the assertions and output more informative messages when they trip. They also do a little extra work so that you can check before and after values in a function as well as check invariants before and after a function call without writing two checks. They are TOAST_IN, TOAST_OUT, TOAST_EXCEPT, TOAST_INVARIANTS and TOAST_NEW. Also with very little effort you can set up doxygen to automatically document these requirements. And of course, each has an _D variant and like all assertions are affected by TOAST_THROW_ASSERTS.


Files

file  assert.hpp
 assert.hpp contains several macros for easy asserting
file  contracts.hpp
 conatracts.hpp contains several macros to ease Programming with Contracts

Classes

class  toast::assert_exception
 Exception thrown by toast assertions in the case that TOAST_THROW_ASSERTS is used. More...

Defines

#define TOAST_THROW_ASSERTS(statement)   TOAST_THROW_ASSERTS_IMPL(statement)
 transform toast assertions to exceptions.
#define TOAST_ASSERT(condition)   TOAST_ASSERT_IMPL(condition)
 assert that condition is true.
#define TOAST_ASSERT_NOT_NULL(pointer)   TOAST_ASSERT_NOT_NULL_IMPL(pointer)
 assert that pointer is not 0.
#define TOAST_ASSERT_NULL(pointer)   TOAST_ASSERT_NULL_IMPL(pointer)
 assert that pointer is 0.
#define TOAST_ASSERT_MESSAGE(condition, message)   TOAST_ASSERT_MESSAGE_IMPL(condition, message)
 assert that condition is true.
#define TOAST_ASSERT_D(condition)   TOAST_ASSERT(condition)
 assert that condition is true.
#define TOAST_ASSERT_NOT_NULL_D(pointer)   TOAST_ASSERT_NOT_NULL(pointer)
 assert that pointer is not 0.
#define TOAST_ASSERT_NULL_D(pointer)   TOAST_ASSERT_NULL(pointer)
 assert that pointer is 0.
#define TOAST_ASSERT_MESSAGE_D(condition, message)   TOAST_ASSERT_MESSAGE(condition, message)
 assert that condition is true.
#define TOAST_INVARIANTS()   TOAST_INVARIANTS_IMPL()
 check class invariants.
#define TOAST_IN(condition)   TOAST_IN_IMPL(condition, #condition)
 declare condition to be a precondition.
#define TOAST_OUT(condition)   TOAST_OUT_IMPL(condition, #condition)
 declare condition to be a postcondition.
#define TOAST_EXCEPT(condition)   TOAST_EXCEPT_IMPL(condition, #condition)
 declare condition to be an exceptional condition.
#define TOAST_NEW(variable)   TOAST_NEW_IMPL(variable)
 delays evaluation of the variable.
#define TOAST_INVARIANTS_BEGIN()   TOAST_INVARIANTS_BEGIN_IMPL()
 begin definition of class invariants.
#define TOAST_DEFINE_INVARIANT(condition)   TOAST_DEFINE_INVARIANT_IMPL(condition)
 declare condition to be a class invariant.
#define TOAST_INVARIANTS_END()   TOAST_INVARIANTS_END_IMPL()
 end definition of class invariants.
#define TOAST_INVARIANTS_D()   TOAST_INVARIANTS()
 check class invariants.
#define TOAST_IN_D(condition)   TOAST_IN(condition)
 declare condition to be a precondition.
#define TOAST_OUT_D(condition)   TOAST_OUT(condition)
 declare condition to be a postcondition.
#define TOAST_EXCEPT_D(condition)   TOAST_EXCEPT(condition)
 declare condition to be an exceptional condition.


Define Documentation

#define TOAST_ASSERT ( condition   )     TOAST_ASSERT_IMPL(condition)

assert that condition is true.

When condition is false program will abort (with a pretty message to stdout). There is no provision for switching this macro on or off at compile time.

See also:
TOAST_ASSERT_D

Referenced by toast::async::default_worker_pool(), and toast::async::init_default_worker_pool().

#define TOAST_ASSERT_D ( condition   )     TOAST_ASSERT(condition)

assert that condition is true.

When condition is false program will abort (with a pretty message to stdout). This macro is disabled when NDEBUG is set.

See also:
TOAST_ASSERT

#define TOAST_ASSERT_MESSAGE ( condition,
message   )     TOAST_ASSERT_MESSAGE_IMPL(condition, message)

assert that condition is true.

When condition is false program will abort (with a pretty message partially provided by you to stdout). There is no provision for switching this macro on or off at compile time.

See also:
TOAST_ASSERT_MESSAGE_D

#define TOAST_ASSERT_MESSAGE_D ( condition,
message   )     TOAST_ASSERT_MESSAGE(condition, message)

assert that condition is true.

When condition is false program will abort (with a pretty message partially provided by you to stdout). This macro is disabled when NDEBUG is set.

See also:
TOAST_ASSERT_MESSAGE

#define TOAST_ASSERT_NOT_NULL ( pointer   )     TOAST_ASSERT_NOT_NULL_IMPL(pointer)

assert that pointer is not 0.

When pointer is 0 program will abort (with a pretty message to stdout). There is no provision for switching this macro on or off at compile time.

See also:
TOAST_ASSERT_NOT_NULL_D

#define TOAST_ASSERT_NOT_NULL_D ( pointer   )     TOAST_ASSERT_NOT_NULL(pointer)

assert that pointer is not 0.

When pointer is 0 program will abort (with a pretty message to stdout). There is no provision for switching this macro on or off at compile time.

See also:
TOAST_ASSERT_NOT_NULL_D

#define TOAST_ASSERT_NULL ( pointer   )     TOAST_ASSERT_NULL_IMPL(pointer)

assert that pointer is 0.

When pointer is not 0 program will abort (with a pretty message to stdout). There is no provision for switching this macro on or off at compile time.

See also:
TOAST_ASSERT_NULL_D

#define TOAST_ASSERT_NULL_D ( pointer   )     TOAST_ASSERT_NULL(pointer)

assert that pointer is 0.

When pointer is not 0 program will abort (with a pretty message to stdout). This macro is disabled when NDEBUG is set.

See also:
TOAST_ASSERT_NULL

#define TOAST_DEFINE_INVARIANT ( condition   )     TOAST_DEFINE_INVARIANT_IMPL(condition)

declare condition to be a class invariant.

condition is checked upon a call to TOAST_INVARIANTS and again when the program leave the scope of that call. May only be used between TOAST_INVARIANTS_BEGIN and TOAST_INVARIANTS_END.

Examples:
contracts/whatami.cpp.

#define TOAST_EXCEPT ( condition   )     TOAST_EXCEPT_IMPL(condition, #condition)

declare condition to be an exceptional condition.

condition is checked when the program leaves the enclosing scope due to an exception. If condition is false program will abort (with a pretty message to stdout). There is no provision for switching this macro on or off at compile time.

See also:
TOAST_EXCEPT_D

#define TOAST_EXCEPT_D ( condition   )     TOAST_EXCEPT(condition)

declare condition to be an exceptional condition.

condition is checked when the program leaves the enclosing scope due to an exception. If condition is false program will abort (with a pretty message to stdout). This macro is disabled when NDEBUG is set.

See also:
TOAST_EXCEPT

#define TOAST_IN ( condition   )     TOAST_IN_IMPL(condition, #condition)

declare condition to be a precondition.

condition is checked immediately. If condition is false program will abort (with a pretty message to stdout). There is no provision for switching this macro on or off at compile time.

See also:
TOAST_IN_D
Examples:
contracts/whatami.cpp.

Referenced by toast::async::worker_pool::worker_pool().

#define TOAST_IN_D ( condition   )     TOAST_IN(condition)

declare condition to be a precondition.

condition is checked immediately. If condition is false program will abort (with a pretty message to stdout). This macro is disabled when NDEBUG is set.

See also:
TOAST_IN

 
#define TOAST_INVARIANTS (  )     TOAST_INVARIANTS_IMPL()

check class invariants.

invariants are checked immediately and when the program leaves the enclosing scope. There is no provision for switching this macro on or off at compile time.

See also:
TOAST_DEFINE_INVARIANT TOAST_INVARIANTS_D

 
#define TOAST_INVARIANTS_BEGIN (  )     TOAST_INVARIANTS_BEGIN_IMPL()

begin definition of class invariants.

This can only be used within a class definition.

Examples:
contracts/whatami.cpp.

 
#define TOAST_INVARIANTS_D (  )     TOAST_INVARIANTS()

check class invariants.

invariants are checked immediately and when the program leaves the enclosing scope. This macro is disabled when NDEBUG is set.

See also:
TOAST_DEFINE_INVARIANT TOAST_INVARIANTS

 
#define TOAST_INVARIANTS_END (  )     TOAST_INVARIANTS_END_IMPL()

end definition of class invariants.

This can only be used within a class definition.

Examples:
contracts/whatami.cpp.

#define TOAST_NEW ( variable   )     TOAST_NEW_IMPL(variable)

delays evaluation of the variable.

For use with TOAST_OUT and TOAST_EXCEPT, this allows for the old value of a variable to be checked against its new value. Note: This only works with variables! A call to a member function will not work with TOAST_NEW. In this case you must move the TOAST_OUT to the end of the function. This not being a good idea with TOAST_EXCEPT you may not be able to do exactly what you want.

#define TOAST_OUT ( condition   )     TOAST_OUT_IMPL(condition, #condition)

declare condition to be a postcondition.

condition is checked when the program leaves the enclosing scope normally. If condition is false program will abort (with a pretty message to stdout). There is no provision for switching this macro on or off at compile time.

See also:
TOAST_OUT_D
Examples:
contracts/whatami.cpp.

#define TOAST_OUT_D ( condition   )     TOAST_OUT(condition)

declare condition to be a postcondition.

condition is checked when the program leaves the enclosing scope normally. If condition is false program will abort (with a pretty message to stdout). This macro is disabled when NDEBUG is set.

See also:
TOAST_OUT

#define TOAST_THROW_ASSERTS ( statement   )     TOAST_THROW_ASSERTS_IMPL(statement)

transform toast assertions to exceptions.

The statement will be executed in such a way that any assertion that fails will throw toast::assert_exception (including TOAST_IN and friends). The what() message will match what would have been printed out prior to aborting.


SourceForge.net Logo