| 1234567891011121314151617181920212223242526272829303132333435363738394041424344 |
- #pragma once
- #include <concepts>
- #include <functional>
- #include <utility>
- namespace jvalidate::detail {
- /**
- * @brief An object representing a cleanup function, to be called as if it was
- * a destructor for the current function scope. Similar to e.g. D-lang's
- * scope(exit) or @see https://en.cppreference.com/w/cpp/experimental/scope_exit
- *
- * Is movable - allowing us to return this scope object from its constructing
- * context into the actual owning context that wants to control that scope.
- */
- class OnBlockExit {
- private:
- std::function<void()> callback_;
- public:
- OnBlockExit() = default;
- template <typename F>
- requires std::constructible_from<std::function<void()>, F>
- explicit(false) OnBlockExit(F && callback) : callback_(std::forward<F>(callback)) {}
- OnBlockExit(OnBlockExit const &) = delete;
- OnBlockExit & operator=(OnBlockExit const &) = delete;
- // Must be explicity implemented because function's move ctor is non-destructive
- OnBlockExit(OnBlockExit && other) noexcept { std::swap(other.callback_, callback_); }
- // Must be explicity implemented because function's move-assign is non-destructive
- OnBlockExit & operator=(OnBlockExit && other) noexcept {
- std::swap(other.callback_, callback_);
- return *this;
- }
- ~OnBlockExit() {
- if (callback_) {
- callback_();
- }
- }
- };
- }
|