#pragma once struct Il2CppException; namespace il2cpp { namespace utils { NORETURN void RethrowException(Il2CppException* exception); template struct FinallyHelper { public: inline FinallyHelper(FinallyBlock&& finallyBlock) : m_Exception(nullptr), // static cast to rvalue reference simulates std::move, as we don't want to include for all generated code m_FinallyBlock(static_cast(finallyBlock)) { } FinallyHelper(const FinallyHelper&) = delete; FinallyHelper& operator=(const FinallyHelper&) = delete; inline FinallyHelper(FinallyHelper&& other) : m_FinallyBlock(static_cast(other.m_FinallyBlock)) { } inline FinallyHelper& operator=(FinallyHelper&& other) { m_FinallyBlock = static_cast(other.m_FinallyBlock); return *this; } inline ~FinallyHelper() noexcept(false) { if (isFault) { if (m_Exception != nullptr) { m_FinallyBlock(); RethrowException(m_Exception); } } else { m_FinallyBlock(); if (m_Exception != nullptr) RethrowException(m_Exception); } } inline void StoreException(Il2CppException* exception) { m_Exception = exception; } private: Il2CppException* m_Exception; FinallyBlock m_FinallyBlock; }; template inline FinallyHelper Finally(FinallyBlock&& finallyBlock) { return FinallyHelper(static_cast(finallyBlock)); } template inline FinallyHelper Fault(FinallyBlock&& finallyBlock) { return FinallyHelper(static_cast(finallyBlock)); } } }