Files
allhaileris afb81b8278
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
init
2026-02-16 15:50:16 +03:00

98 lines
2.5 KiB
C++

/// \file
// Range v3 library
//
// Copyright Eric Niebler 2017-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_UTILITY_SCOPE_EXIT_HPP
#define RANGES_V3_UTILITY_SCOPE_EXIT_HPP
#include <functional>
#include <type_traits>
#include <utility>
#include <meta/meta.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
template<typename Fun>
struct scope_exit
{
private:
using nothrow_move_t = std::is_nothrow_move_constructible<Fun>;
using nothrow_copy_t = std::is_nothrow_copy_constructible<Fun>;
Fun fun_;
bool dismissed_{false};
using ref_t = decltype(std::ref(std::declval<Fun const &>()));
using guard = scope_exit<ref_t>;
scope_exit(Fun const & fun, guard && g)
: fun_(fun)
{
g.dismiss();
}
scope_exit(Fun const & fun, std::false_type)
: scope_exit(fun, guard{std::ref(fun)})
{}
scope_exit(Fun const & fun, std::true_type) noexcept
: fun_(fun)
{}
scope_exit(Fun && fun, std::true_type) noexcept
: fun_(std::move(fun))
{}
public:
explicit scope_exit(Fun const & fun) noexcept(
noexcept(scope_exit(fun, nothrow_copy_t{})))
: scope_exit(fun, nothrow_copy_t{})
{}
explicit scope_exit(Fun && fun) noexcept(noexcept(scope_exit(std::move(fun),
nothrow_move_t{})))
: scope_exit(std::move(fun), nothrow_move_t{})
{}
scope_exit(scope_exit const &) = delete;
scope_exit(scope_exit && that) noexcept(
std::is_nothrow_move_constructible<Fun>::value)
: scope_exit(std::move((that.dismiss(), that)).fun_)
{}
~scope_exit()
{
if(!dismissed_)
fun_();
}
void dismiss() noexcept
{
dismissed_ = true;
}
};
template<typename Fun, typename ScopeExit = scope_exit<meta::_t<std::decay<Fun>>>>
ScopeExit make_scope_exit(Fun && fun) noexcept(
noexcept(ScopeExit(ScopeExit((Fun &&) fun))))
{
return ScopeExit((Fun &&) fun);
}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif