You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.1 KiB
C

/**
* Copyright 2013-2022 Software Radio Systems Limited
*
* This file is part of srsRAN.
*
* srsRAN is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsRAN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSRAN_SCOPE_EXIT_H
#define SRSRAN_SCOPE_EXIT_H
#include <type_traits>
#include <utility>
namespace srsran {
namespace detail {
template <typename Callable>
struct scope_exit {
template <typename C>
explicit scope_exit(C&& f_) : exit_function(std::forward<C>(f_))
{}
scope_exit(scope_exit&& rhs) noexcept : exit_function(std::move(rhs.exit_function)), active(rhs.active)
{
rhs.release();
}
scope_exit(const scope_exit&) = delete;
scope_exit& operator=(const scope_exit&) = delete;
scope_exit& operator=(scope_exit&&) noexcept = delete;
~scope_exit()
{
if (active) {
exit_function();
}
}
void release() { active = false; }
private:
Callable exit_function;
bool active = true;
};
} // namespace detail
/**
* @brief Defers callable call to scope exit
* @tparam Callable Any type with a call operator
* @param callable function that is called at scope exit
* @return object that has to be stored in a local variable
*/
template <typename Callable>
detail::scope_exit<typename std::decay<Callable>::type> make_scope_exit(Callable&& callable)
{
return detail::scope_exit<typename std::decay<Callable>::type>{std::forward<Callable>(callable)};
}
#define DEFER(FUNC) auto on_exit_call##__LINE__ = srsran::make_scope_exit([&]() { FUNC })
} // namespace srsran
#endif // SRSRAN_SCOPE_EXIT_H