{"id":13731026,"url":"https://github.com/foonathan/debug_assert","last_synced_at":"2025-04-07T19:17:04.908Z","repository":{"id":55141793,"uuid":"68325046","full_name":"foonathan/debug_assert","owner":"foonathan","description":"Simple, flexible and modular assertion macro.","archived":false,"fork":false,"pushed_at":"2024-04-22T20:12:23.000Z","size":54,"stargazers_count":226,"open_issues_count":0,"forks_count":21,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-31T16:17:32.277Z","etag":null,"topics":["assert","c-plus-plus"],"latest_commit_sha":null,"homepage":"http://foonathan.net/blog/2016/09/16/assertions.html","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"zlib","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/foonathan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-09-15T19:33:01.000Z","updated_at":"2025-03-24T00:17:50.000Z","dependencies_parsed_at":"2023-12-28T10:49:05.375Z","dependency_job_id":"880ee818-2c97-4cc7-adb8-b0b4b3a44451","html_url":"https://github.com/foonathan/debug_assert","commit_stats":{"total_commits":33,"total_committers":8,"mean_commits":4.125,"dds":0.5151515151515151,"last_synced_commit":"7ea47091830eec9a9c6a338c8a29da70494692a5"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foonathan%2Fdebug_assert","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foonathan%2Fdebug_assert/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foonathan%2Fdebug_assert/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foonathan%2Fdebug_assert/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/foonathan","download_url":"https://codeload.github.com/foonathan/debug_assert/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247713258,"owners_count":20983683,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assert","c-plus-plus"],"created_at":"2024-08-03T02:01:22.936Z","updated_at":"2025-04-07T19:17:04.883Z","avatar_url":"https://github.com/foonathan.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# debug_assert \n\n![Project Status](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jonathanmueller.dev%2Fproject%2Fdebug_assert%2Findex.json)\n[![Download](https://api.bintray.com/packages/manu343726/conan-packages/debug_assert%3AManu343726/images/download.svg) ](https://bintray.com/manu343726/conan-packages/debug_assert%3AManu343726/_latestVersion)\n\ndebug_assert is a simple, C++11, header-only library that provides a very flexible `DEBUG_ASSERT()` macro.\nHow 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?\nThis library solves the problem by providing a flexible, modular assertion macro.\n\n## Features\n\n* No dependencies. It only requires `std::abort()` and - unless `DEBUG_ASSERT_NO_STDIO` is defined - `std::fprintf()`.\n* Single, small header file that just needs to be copied into your own project.\n* Customizable assertion handling - assertion failure will call a user-defined function, with user-defined arguments.\n* Modular - enable or disable assertions for different parts of the same program.\n* Support for levels - give levels to your assertion macro and only enable certain levels of assertions.\n* 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.\n* Fast - even though a disabled assertion will still expand to something,\nthere 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!\n\n## Overview\n\nThe basic usage of the library is like so:\n\n```cpp\nDEBUG_ASSERT(1 + 1 == 2, my_module{}); // basic\nDEBUG_ASSERT(1 + 1 == 2, my_module{}, debug_assert::level\u003c2\u003e{}); // with level\n```\n\nWhere `my_module` is a user-defined tag type that will both control the assertion level and the handler code.\nIt looks like this:\n\n```cpp\nstruct my_module\n: debug_assert::default_handler, // use the default handler\n  debug_assert::set_level\u003c-1\u003e // level -1, i.e. all assertions, 0 would mean none, 1 would be level 1, 2 level 2 or lower,...\n{};\n```\n\nA 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`).\n\nSee `example.cpp` for more information and [read the blogpost](https://foonathan.github.io/blog/2016/09/16/assertions.html).\n\n### CMake\n\nFor convenience you can also use CMake to setup the include directory and have options that map to the customizable macros.\nSimple call `add_subdirectory(path/to/debug_assert)` and then `target_link_libraries(my_target PUBLIC debug_assert)`.\nIt will not actually build something, only setup the flags.\nNote that it will not enable C++11 support.\nThe options are named like the macros.\n\n## Documentation\n\n\u003e Generated by [standardese](https://github.com/foonathan/standardese).\n\n# Header file `debug_assert.hpp`\u003ca id=\"debug_assert.hpp\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003e#define \u003ca href='doc_debug_assert.md#debug_assert.hpp'\u003eDEBUG_ASSERT_MARK_UNREACHABLE\u003c/a\u003e\n\n#define \u003ca href='doc_debug_assert.md#debug_assert.hpp'\u003eDEBUG_ASSERT_FORCE_INLINE\u003c/a\u003e\n\n#define \u003ca href='doc_debug_assert.md#DEBUG_ASSERT_CUR_SOURCE_LOCATION'\u003eDEBUG_ASSERT_CUR_SOURCE_LOCATION\u003c/a\u003e\n\n#define \u003ca href='doc_debug_assert.md#DEBUG_ASSERT'\u003eDEBUG_ASSERT\u003c/a\u003e(Expr, ...)\n\n#define \u003ca href='doc_debug_assert.md#DEBUG_UNREACHABLE'\u003eDEBUG_UNREACHABLE\u003c/a\u003e(...)\n\nnamespace \u003ca href='doc_debug_assert.md#debug_assert.hpp'\u003edebug_assert\u003c/a\u003e\n{\n    struct \u003ca href='doc_debug_assert.md#debug_assert::source_location'\u003esource_location\u003c/a\u003e;\n\n    template \u0026lt;unsigned Level\u0026gt;\n    struct \u003ca href='doc_debug_assert.md#debug_assert::level-Level-'\u003elevel\u003c/a\u003e;\n\n    template \u0026lt;unsigned Level\u0026gt;\n    struct \u003ca href='doc_debug_assert.md#debug_assert::set_level-Level-'\u003eset_level\u003c/a\u003e;\n\n    struct \u003ca href='doc_debug_assert.md#debug_assert::allow_exception'\u003eallow_exception\u003c/a\u003e;\n\n    struct \u003ca href='doc_debug_assert.md#debug_assert::no_handler'\u003eno_handler\u003c/a\u003e;\n\n    struct \u003ca href='doc_debug_assert.md#debug_assert::default_handler'\u003edefault_handler\u003c/a\u003e;\n}\u003c/code\u003e\u003c/pre\u003e\n\n## Macro `DEBUG_ASSERT_CUR_SOURCE_LOCATION`\u003ca id=\"DEBUG_ASSERT_CUR_SOURCE_LOCATION\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003e#define DEBUG_ASSERT_CUR_SOURCE_LOCATION\u003c/code\u003e\u003c/pre\u003e\n\nExpands to the current [debug\\_assert::source\\_location](doc_debug_assert.md#debug_assert::source_location).\n\n## Macro `DEBUG_ASSERT`\u003ca id=\"DEBUG_ASSERT\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003e#define DEBUG_ASSERT(Expr, ...)\u003c/code\u003e\u003c/pre\u003e\n\nUsage: \\`DEBUG\\_ASSERT(\\\u003cexpr\\\u003e, \\\u003chandler\\\u003e, \\[\\\u003clevel\\\u003e\\], \\[\\\u003chandler-specific-args\\\u003e\\]. Where:\n\n  - `\u003cexpr\u003e` - the expression to check for, the expression `!\u003cexpr\u003e` must be well-formed and contextually convertible to `bool`.\n  - `\u003chandler\u003e` - an object of the module specific handler\n  - `\u003clevel\u003e` (optional, defaults to `1`) - the level of the assertion, must be an object of type [debug\\_assert::level\\\u003cLevel\\\u003e](doc_debug_assert.md#debug_assert::level-Level-).\n  - `\u003chandler-specific-args\u003e` (optional) - any additional arguments that are just forwarded to the handler function.\n\nIt will only check the assertion if `\u003clevel\u003e` 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](doc_debug_assert.md#debug_assert::source_location) at the macro expansion, `expression` is the stringified expression and `args` are the `\u003chandler-specific-args\u003e` as-is. If the handler function returns, it will call \\[std::abort()\\].\n\n*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.\n\n## Macro `DEBUG_UNREACHABLE`\u003ca id=\"DEBUG_UNREACHABLE\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003e#define DEBUG_UNREACHABLE(...)\u003c/code\u003e\u003c/pre\u003e\n\nMarks a branch as unreachable.\n\nUsage: `DEBUG_UNREACHABLE(\u003chandler\u003e, [\u003clevel\u003e], [\u003chandler-specific-args\u003e])` Where:\n\n  - `\u003chandler\u003e` - an object of the module specific handler\n  - `\u003clevel\u003e` (optional, defaults to `1`) - the level of the assertion, must be an object of type [debug\\_assert::level\\\u003cLevel\\\u003e](doc_debug_assert.md#debug_assert::level-Level-).\n  - `\u003chandler-specific-args\u003e` (optional) - any additional arguments that are just forwarded to the handler function.\n\nIt will only check the assertion if `\u003clevel\u003e` is less than or equal to `Handler::level`. A failed assertion will call: `Handler::handle(location, \"\", args)`. and `args` are the `\u003chandler-specific-args\u003e` as-is. If the handler function returns, it will call \\[std::abort()\\].\n\n*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.\n\n## Struct `debug_assert::source_location`\u003ca id=\"debug_assert::source_location\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003estruct source_location\n{\n    const char* \u003ca href='doc_debug_assert.md#debug_assert::source_location'\u003efile_name\u003c/a\u003e;\n\n    unsigned \u003ca href='doc_debug_assert.md#debug_assert::source_location::line_number'\u003eline_number\u003c/a\u003e;\n};\u003c/code\u003e\u003c/pre\u003e\n\nDefines a location in the source code.\n\n**Members:**\n\n  - \u003ca id=\"debug_assert::source_location::line_number\"\u003e\u003c/a\u003e`line_number` - \\\u003c The file name. \\\u003c The line number.\n\n## Class template `debug_assert::level`\u003ca id=\"debug_assert::level-Level-\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003etemplate \u0026lt;unsigned Level\u0026gt;\nstruct level\n{\n};\u003c/code\u003e\u003c/pre\u003e\n\nTag type to indicate the level of an assertion.\n\n## Class template `debug_assert::set_level`\u003ca id=\"debug_assert::set_level-Level-\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003etemplate \u0026lt;unsigned Level\u0026gt;\nstruct set_level\n{\n    static const unsigned \u003ca href='doc_debug_assert.md#debug_assert::set_level-Level-'\u003elevel\u003c/a\u003e = Level;\n};\u003c/code\u003e\u003c/pre\u003e\n\nHelper class that sets a certain level. Inherit from it in your module handler.\n\n## Struct `debug_assert::allow_exception`\u003ca id=\"debug_assert::allow_exception\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003estruct allow_exception\n{\n    static const bool \u003ca href='doc_debug_assert.md#debug_assert::allow_exception'\u003ethrowing_exception_is_allowed\u003c/a\u003e = true;\n};\u003c/code\u003e\u003c/pre\u003e\n\nHelper 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.\n\n## Struct `debug_assert::no_handler`\u003ca id=\"debug_assert::no_handler\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003estruct no_handler\n{\n    template \u0026lt;typename ... Args\u0026gt;\n    static void \u003ca href='doc_debug_assert.md#debug_assert::no_handler::handle(constdebug_assert::source_location\u0026,constchar*,Args\u0026\u0026...)'\u003ehandle\u003c/a\u003e(const \u003ca href='doc_debug_assert.md#debug_assert::source_location'\u003esource_location\u003c/a\u003e\u0026amp;, const char*, Args\u0026amp;\u0026amp;...) noexcept;\n};\u003c/code\u003e\u003c/pre\u003e\n\nDoes not do anything to handle a failed assertion (except calling [std::abort()](http://en.cppreference.com/mwiki/index.php?title=Special%3ASearch\u0026search=std::abort())). Inherit from it in your module handler.\n\n### Function template `debug_assert::no_handler::handle`\u003ca id=\"debug_assert::no_handler::handle(constdebug_assert::source_location\u0026,constchar*,Args\u0026\u0026...)\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003etemplate \u0026lt;typename ... Args\u0026gt;\nstatic void handle(const \u003ca href='doc_debug_assert.md#debug_assert::source_location'\u003esource_location\u003c/a\u003e\u0026amp;, const char*, Args\u0026amp;\u0026amp;...) noexcept;\u003c/code\u003e\u003c/pre\u003e\n\n*Effects*: Does nothing.\n\n*Notes*: Can take any additional arguments.\n\n-----\n\n## Struct `debug_assert::default_handler`\u003ca id=\"debug_assert::default_handler\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003estruct default_handler\n{\n    static void \u003ca href='doc_debug_assert.md#debug_assert::default_handler::handle(constdebug_assert::source_location\u0026,constchar*,constchar*)'\u003ehandle\u003c/a\u003e(const \u003ca href='doc_debug_assert.md#debug_assert::source_location'\u003esource_location\u003c/a\u003e\u0026amp; loc, const char* expression, const char* message = nullptr) noexcept;\n};\u003c/code\u003e\u003c/pre\u003e\n\nThe default handler that writes a message to `stderr`. Inherit from it in your module handler.\n\n### Function `debug_assert::default_handler::handle`\u003ca id=\"debug_assert::default_handler::handle(constdebug_assert::source_location\u0026,constchar*,constchar*)\"\u003e\u003c/a\u003e\n\n\u003cpre\u003e\u003ccode class=\"language-cpp\"\u003estatic void handle(const \u003ca href='doc_debug_assert.md#debug_assert::source_location'\u003esource_location\u003c/a\u003e\u0026amp; loc, const char* expression, const char* message = nullptr) noexcept;\u003c/code\u003e\u003c/pre\u003e\n\n*Effects*: Prints a message to `stderr`.\n\n*Notes*: It can optionally accept an additional message string.\n\n*Notes*: If `DEBUG_ASSERT_NO_STDIO` is defined, it will do nothing.\n\n-----\n\n-----\n\n\n## Acknowledgements\n\nThanks a lot to [@Manu343726](https://github.com/Manu343726), [@verri](https://github.com/verri) and [@pfultz2](https://github.com/pfultz2).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoonathan%2Fdebug_assert","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffoonathan%2Fdebug_assert","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoonathan%2Fdebug_assert/lists"}