All Projects → foonathan → Debug_assert

foonathan / Debug_assert

Licence: zlib
Simple, flexible and modular assertion macro.

Labels

Projects that are alternatives of or similar to Debug assert

openapi-assert
Asserting data against OpenAPI docs.
Stars: ✭ 17 (-90.61%)
Mutual labels:  assert
Validator.js
⁉️轻量级的 JavaScript 表单验证,字符串验证。没有依赖,支持 UMD ,~3kb。
Stars: ✭ 486 (+168.51%)
Mutual labels:  assert
Expect More
Curried Type Testing library, and Test Matchers for Jest
Stars: ✭ 124 (-31.49%)
Mutual labels:  assert
Naza
🍀 Go basic library. || Go语言基础库
Stars: ✭ 253 (+39.78%)
Mutual labels:  assert
Static Assertions Rs
Ensure correct assumptions about constants, types, and more in Rust
Stars: ✭ 363 (+100.55%)
Mutual labels:  assert
Baloo
Expressive end-to-end HTTP API testing made easy in Go
Stars: ✭ 702 (+287.85%)
Mutual labels:  assert
assert-true
A lot of ways to you set your assert as true
Stars: ✭ 19 (-89.5%)
Mutual labels:  assert
Resumable Assert
Assert replacement to continue execution in debugger
Stars: ✭ 157 (-13.26%)
Mutual labels:  assert
Ava
Node.js test runner that lets you develop with confidence 🚀
Stars: ✭ 19,458 (+10650.28%)
Mutual labels:  assert
Assert
A collection of convenient assertions for Swift testing
Stars: ✭ 69 (-61.88%)
Mutual labels:  assert
Commonjs Assert
Node.js's require('assert') for all engines
Stars: ✭ 255 (+40.88%)
Mutual labels:  assert
Atrium
A multiplatform assertion library for Kotlin
Stars: ✭ 359 (+98.34%)
Mutual labels:  assert
Regex Assert Symfony
Common Regex to use with Assert in Symfony's entity
Stars: ✭ 5 (-97.24%)
Mutual labels:  assert
underscore.haz
🔍 _.haz() is like _.has() but this underscore and/or lodash mixin lets you do deep object key existence checking with a dot denoted string, for example 'a.b.c'
Stars: ✭ 13 (-92.82%)
Mutual labels:  assert
Gopwt
PowerAssert library for golang
Stars: ✭ 137 (-24.31%)
Mutual labels:  assert
php-assert
Fast flexible php assert
Stars: ✭ 18 (-90.06%)
Mutual labels:  assert
Node Deep Equal
node's assert.deepEqual algorithm
Stars: ✭ 577 (+218.78%)
Mutual labels:  assert
Ppk assert
PPK_ASSERT is a cross platform drop-in & self-contained C++ assertion library
Stars: ✭ 164 (-9.39%)
Mutual labels:  assert
Earl
☕ Ergonomic, modern and type-safe assertion library for TypeScript
Stars: ✭ 153 (-15.47%)
Mutual labels:  assert
Testify
A unit testing framework written in bash for bash scripts
Stars: ✭ 45 (-75.14%)
Mutual labels:  assert

debug_assert

Project Status Download

debug_assert is a simple, C++11, header-only library that provides a very flexible DEBUG_ASSERT() macro. How many times did you write an assertion macro yourself, because assert() is controlled globally and cannot be enabled for certain parts of the program only? This library solves the problem by providing a flexible, modular assertion macro.

Features

  • No dependencies. It only requires std::abort() and - unless DEBUG_ASSERT_NO_STDIO is defined - std::fprintf().
  • Single, small header file that just needs to be copied into your own project.
  • Customizable assertion handling - assertion failure will call a user-defined function, with user-defined arguments.
  • Modular - enable or disable assertions for different parts of the same program.
  • Support for levels - give levels to your assertion macro and only enable certain levels of assertions.
  • Little preprocessor use - just a single assertion macro which is needed to get the stringified expression and source location. Enabling/Disabling is controlled by compile time programming instead of preprocessor conditionals.
  • Fast - even though a disabled assertion will still expand to something, there is no overhead with even basic optimizations enabled and very little without optimization (just the code to read __FILE__ and __LINE__). To be precise: It will only evaluate the assertion expression if the assertion is enabled!

Overview

The basic usage of the library is like so:

DEBUG_ASSERT(1 + 1 == 2, my_module{}); // basic
DEBUG_ASSERT(1 + 1 == 2, my_module{}, debug_assert::level<2>{}); // with level

Where my_module is a user-defined tag type that will both control the assertion level and the handler code. It looks like this:

struct my_module
: debug_assert::default_handler, // use the default handler
  debug_assert::set_level<-1> // level -1, i.e. all assertions, 0 would mean none, 1 would be level 1, 2 level 2 or lower,...
{};

A module handler must have static function handle() that takes a debug_assert::source_location, the stringified expression and any additional arguments you pass to DEBUG_ASSERT() (besides the debug_assert::level).

See example.cpp for more information and read the blogpost.

CMake

For convenience you can also use CMake to setup the include directory and have options that map to the customizable macros. Simple call add_subdirectory(path/to/debug_assert) and then target_link_libraries(my_target PUBLIC debug_assert). It will not actually build something, only setup the flags. Note that it will not enable C++11 support. The options are named like the macros.

Documentation

Generated by standardese.

Header file debug_assert.hpp

#define DEBUG_ASSERT_MARK_UNREACHABLE

#define DEBUG_ASSERT_FORCE_INLINE

#define DEBUG_ASSERT_CUR_SOURCE_LOCATION

#define DEBUG_ASSERT(Expr, ...)

#define DEBUG_UNREACHABLE(...)

namespace debug_assert
{
    struct source_location;

    template <unsigned Level>
    struct level;

    template <unsigned Level>
    struct set_level;

    struct allow_exception;

    struct no_handler;

    struct default_handler;
}

Macro DEBUG_ASSERT_CUR_SOURCE_LOCATION

#define DEBUG_ASSERT_CUR_SOURCE_LOCATION

Expands to the current debug_assert::source_location.

Macro DEBUG_ASSERT

#define DEBUG_ASSERT(Expr, ...)

Usage: `DEBUG_ASSERT(<expr>, <handler>, [<level>], [<handler-specific-args>]. Where:

  • <expr> - the expression to check for, the expression !<expr> must be well-formed and contextually convertible to bool.
  • <handler> - an object of the module specific handler
  • <level> (optional, defaults to 1) - the level of the assertion, must be an object of type debug_assert::level<Level>.
  • <handler-specific-args> (optional) - any additional arguments that are just forwarded to the handler function.

It will only check the assertion if <level> is less than or equal to Handler::level. A failed assertion will call: Handler::handle(location, expression, args). location is the debug_assert::source_location at the macro expansion, expression is the stringified expression and args are the <handler-specific-args> as-is. If the handler function returns, it will call [std::abort()].

Notes: Define DEBUG_ASSERT_DISABLE to completely disable this macro, it will expand to nothing. This should not be necessary, the regular version is optimized away completely.

Macro DEBUG_UNREACHABLE

#define DEBUG_UNREACHABLE(...)

Marks a branch as unreachable.

Usage: DEBUG_UNREACHABLE(<handler>, [<level>], [<handler-specific-args>]) Where:

  • <handler> - an object of the module specific handler
  • <level> (optional, defaults to 1) - the level of the assertion, must be an object of type debug_assert::level<Level>.
  • <handler-specific-args> (optional) - any additional arguments that are just forwarded to the handler function.

It will only check the assertion if <level> is less than or equal to Handler::level. A failed assertion will call: Handler::handle(location, "", args). and args are the <handler-specific-args> as-is. If the handler function returns, it will call [std::abort()].

Notes: Define DEBUG_ASSERT_DISABLE to completely disable this macro, it will expand to DEBUG_ASSERT_MARK_UNREACHABLE. This should not be necessary, the regular version is optimized away completely.

Struct debug_assert::source_location

struct source_location
{
    const char* file_name;

    unsigned line_number;
};

Defines a location in the source code.

Members:

  • line_number - < The file name. < The line number.

Class template debug_assert::level

template <unsigned Level>
struct level
{
};

Tag type to indicate the level of an assertion.

Class template debug_assert::set_level

template <unsigned Level>
struct set_level
{
    static const unsigned level = Level;
};

Helper class that sets a certain level. Inherit from it in your module handler.

Struct debug_assert::allow_exception

struct allow_exception
{
    static const bool throwing_exception_is_allowed = true;
};

Helper class that controls whether the handler can throw or not. Inherit from it in your module handler. If the module does not inherit from this class, it is assumed that the handle does not throw.

Struct debug_assert::no_handler

struct no_handler
{
    template <typename ... Args>
    static void handle(const source_location&, const char*, Args&&...) noexcept;
};

Does not do anything to handle a failed assertion (except calling std::abort()). Inherit from it in your module handler.

Function template debug_assert::no_handler::handle

template <typename ... Args>
static void handle(const source_location&, const char*, Args&&...) noexcept;

Effects: Does nothing.

Notes: Can take any additional arguments.


Struct debug_assert::default_handler

struct default_handler
{
    static void handle(const source_location& loc, const char* expression, const char* message = nullptr) noexcept;
};

The default handler that writes a message to stderr. Inherit from it in your module handler.

Function debug_assert::default_handler::handle

static void handle(const source_location& loc, const char* expression, const char* message = nullptr) noexcept;

Effects: Prints a message to stderr.

Notes: It can optionally accept an additional message string.

Notes: If DEBUG_ASSERT_NO_STDIO is defined, it will do nothing.



Acknowledgements

Thanks a lot to @Manu343726, @verri and @pfultz2.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].