based

Opinionated 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

Diffstat:
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