AronaCore/core/misc/scope_exit.h
2024-02-19 01:33:18 +08:00

69 lines
1.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
namespace scope_exit_support {
/**
* Not meant for direct consumption : use ON_SCOPE_EXIT instead.
*
* RAII class that calls a lambda when it is destroyed.
*/
template<typename FuncType>
class scope_guard {
scope_guard(scope_guard&&) = delete;
scope_guard(const scope_guard&) = delete;
scope_guard& operator=(scope_guard&&) = delete;
scope_guard& operator=(const scope_guard&) = delete;
public:
// Given a lambda, constructs an RAII scope guard.
explicit scope_guard(FuncType&& InFunc)
: func_((FuncType&&) InFunc) {
}
// Causes the lambda to be executed.
~scope_guard() {
func_();
}
private:
// The lambda to be executed when this guard goes out of scope.
FuncType func_;
};
struct scope_guard_syntax_support {
template<typename FuncType>
scope_guard<FuncType> operator+(FuncType&& in_func) {
return scope_guard<FuncType>((FuncType&&) in_func);
}
};
}
#define UE_PRIVATE_SCOPE_EXIT_JOIN_INNER(A, B) A##B
#define UE_PRIVATE_SCOPE_EXIT_JOIN(A, B) UE_PRIVATE_SCOPE_EXIT_JOIN_INNER(A, B)
/**
* Enables a lambda to be executed on scope exit.
*
* Example:
* {
* FileHandle* Handle = GetFileHandle();
* ON_SCOPE_EXIT
* {
* CloseFile(Handle);
* };
*
* DoSomethingWithFile( Handle );
*
* // File will be closed automatically no matter how the scope is exited, e.g.:
* // * Any return statement.
* // * break or continue (if the scope is a loop body).
* // * An exception is thrown outside the block.
* // * Execution reaches the end of the block.
* }
*/
#define ON_SCOPE_EXIT const auto UE_PRIVATE_SCOPE_EXIT_JOIN(ScopeGuard_, __LINE__) = ::scope_exit_support::scope_guard_syntax_support() + [&]()