basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | af6f09456de19449cd0697120574a50ab4d4e0b8 |
parent | a7d70b2f7e880b17b28820d33cb819f8c1de2135 |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Mon, 28 Apr 2025 13:07:04 +0200 |
scopeguard
M | include/based/template.hpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | include/based/utility.hpp | | | ++++++++++++++++++++++++ |
2 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/ include/based/template.hpp b/ include/based/template.hpp
@@ -356,4 +356,76 @@
public:
template<typename T>
Function(T) -> Function<typename signature<decltype(&T::operator())>::sig_type>;
template<Procedure Func, bool on_success = false, bool on_failure = false>
class scopeguard
{
uncaught_exception_detector m_detector;
Func m_func;
public:
explicit scopeguard(Func&& func)
: m_func(std::move(func))
{
}
explicit scopeguard(const Func& func)
: m_func(func)
{
}
scopeguard(const scopeguard&) = delete;
scopeguard& operator=(const scopeguard&) = delete;
scopeguard(scopeguard&&) = default;
scopeguard& operator=(scopeguard&&) = default;
~scopeguard()
{
if ((on_success && !m_detector) || (on_failure && m_detector)) {
m_func();
}
}
};
template<Procedure Func>
class scopeguard<Func, false, false>
{
bool m_commit = false;
Func m_func;
public:
explicit scopeguard(Func&& func)
: m_func(std::move(func))
{
}
explicit scopeguard(const Func& func)
: m_func(func)
{
}
scopeguard(const scopeguard&) = delete;
scopeguard& operator=(const scopeguard&) = delete;
scopeguard(scopeguard&&) = default;
scopeguard& operator=(scopeguard&&) = default;
~scopeguard()
{
if (m_commit) {
m_func();
}
}
void commit() { m_commit = true; }
};
template<Procedure Func>
using scopeguard_exit = scopeguard<Func, true, true>;
template<Procedure Func>
using scopeguard_success = scopeguard<Func, true, false>;
template<Procedure Func>
using scopeguard_failure = scopeguard<Func, false, true>;
} // namespace based
diff --git a/ include/based/utility.hpp b/ include/based/utility.hpp
@@ -0,0 +1,24 @@
#pragma once
#include <exception>
namespace based
{
class uncaught_exception_detector
{
int m_count;
public:
uncaught_exception_detector()
: m_count(std::uncaught_exceptions())
{
}
operator bool() const noexcept // NOLINT explicit
{
return std::uncaught_exceptions() > m_count;
}
};
} // namespace based