54 lines
1.2 KiB
C++
54 lines
1.2 KiB
C++
|
#pragma once
|
||
|
#include <type_traits>
|
||
|
|
||
|
namespace utils
|
||
|
{
|
||
|
/*
|
||
|
* Copied from here: https://github.com/microsoft/GSL/blob/e0880931ae5885eb988d1a8a57acf8bc2b8dacda/include/gsl/util#L57
|
||
|
*/
|
||
|
|
||
|
template <class F>
|
||
|
class final_action
|
||
|
{
|
||
|
public:
|
||
|
static_assert(!std::is_reference<F>::value && !std::is_const<F>::value &&
|
||
|
!std::is_volatile<F>::value,
|
||
|
"Final_action should store its callable by value");
|
||
|
|
||
|
explicit final_action(F f) noexcept : f_(std::move(f))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
final_action(final_action&& other) noexcept
|
||
|
: f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
final_action(const final_action&) = delete;
|
||
|
final_action& operator=(const final_action&) = delete;
|
||
|
final_action& operator=(final_action&&) = delete;
|
||
|
|
||
|
~final_action() noexcept
|
||
|
{
|
||
|
if (invoke_) f_();
|
||
|
}
|
||
|
|
||
|
// Added by momo5502
|
||
|
void cancel()
|
||
|
{
|
||
|
invoke_ = false;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
F f_;
|
||
|
bool invoke_{true};
|
||
|
};
|
||
|
|
||
|
template <class F>
|
||
|
final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>
|
||
|
finally(F&& f) noexcept
|
||
|
{
|
||
|
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
|
||
|
std::forward<F>(f));
|
||
|
}
|
||
|
}
|