scope_guard
A public, general, simple, and fast C++11 scope guard that
defends against implicitly ignored returns and optionally enforces noexcept
at compile time (in C++17), all in a SFINAE-friendly maner.
TLDR
Get it here. Usage is simple:
#include "scope_guard.hpp"
...
{
...
auto guard = sg::make_scope_guard(my_callback);
...
} // my_callback is invoked at this point
Introduction
A scope guard is an object that employs RAII to execute a provided callback when leaving scope, be it through a fall-through, a return, or an exception. That callback can be a function, a function pointer, a functor, a lambda, a bind result, a std::function, a reference to any of these, or any other callable, as long as it respects a few preconditions – most of which are enforced during compilation, the rest being hopefully intuitive.
All necessary code is provided in a single header (the remaining files are only for testing and documentation).
Acknowledgments
The concept of “scope guard” was proposed by Andrei Alexandrescu and Petru Marginean and it is well known in the C++ community. It has been proposed for standardization (see N4189) but is still not part of the standard library, as of March 2018.
Why
While there are several implementations available, I did not find any with all the characteristics I aimed for here - safe, tested, documented, public domain, thin wrapping, general, standalone, simple interface… (see feature list below).
Features
Main features
- ≥ C++11
- Reduced interface
- Thin callback wrapping: no added
std::function
or virtual table penalties - General: accepts any callable that respects a few preconditions
- No implicitly ignored return (details here)
- Option to enforce
noexcept
in C++17 (details here) - Modern exception specifications (
noexcept
with conditions when necessary) - SFINAE friendliness (see here)
Other characteristics
- No dependencies to use (besides ≥C++11 compiler and standard library)
- No macros to make guard – just write explicit lambda or bind or what have you
- Extensively tested, with both compile time tests and runtime-tests
- Carefully documented (adhering to RFC2119)
- Standalone header that can be directly dumped into any project
- Unlicense’d
snake_case
style
Notes
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
Issues
Bug reports and suggestions are welcome. If you find that something is incorrect or could be improved, feel free to open an issue.
Setup
Setup consists merely of making the header file available to the compiler. That can be achieved by any of the following options:
- placing it directly in the client project’s include path
- placing it in a central include path that is known to the compiler
- placing it in an arbitrary path and configuring the compiler to include that path
The preprocessor definition SG_REQUIRE_NOEXCEPT_IN_CPP17
MAY be provided
to the compiler. The effect of this option is explained
here.
Further documentation
Client interface
The client interface is documented in detail here.
Preconditions in detail
Callback preconditions are explained here.
Design choices and concepts
Design choices and concepts are discussed here.
Tests
Instructions on how to run the tests are here.