Finally.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #pragma once
  2. struct Il2CppException;
  3. namespace il2cpp
  4. {
  5. namespace utils
  6. {
  7. NORETURN void RethrowException(Il2CppException* exception);
  8. template<typename FinallyBlock, bool isFault>
  9. struct FinallyHelper
  10. {
  11. public:
  12. inline FinallyHelper(FinallyBlock&& finallyBlock) :
  13. m_Exception(nullptr),
  14. // static cast to rvalue reference simulates std::move, as we don't want to include <utility> for all generated code
  15. m_FinallyBlock(static_cast<FinallyBlock &&>(finallyBlock))
  16. {
  17. }
  18. FinallyHelper(const FinallyHelper<FinallyBlock, isFault>&) = delete;
  19. FinallyHelper& operator=(const FinallyHelper<FinallyBlock, isFault>&) = delete;
  20. inline FinallyHelper(FinallyHelper<FinallyBlock, isFault>&& other) :
  21. m_FinallyBlock(static_cast<FinallyBlock &&>(other.m_FinallyBlock))
  22. {
  23. }
  24. inline FinallyHelper& operator=(FinallyHelper<FinallyBlock, isFault>&& other)
  25. {
  26. m_FinallyBlock = static_cast<FinallyBlock &&>(other.m_FinallyBlock);
  27. return *this;
  28. }
  29. inline ~FinallyHelper() noexcept(false)
  30. {
  31. if (isFault)
  32. {
  33. if (m_Exception != nullptr)
  34. {
  35. m_FinallyBlock();
  36. RethrowException(m_Exception);
  37. }
  38. }
  39. else
  40. {
  41. m_FinallyBlock();
  42. if (m_Exception != nullptr)
  43. RethrowException(m_Exception);
  44. }
  45. }
  46. inline void StoreException(Il2CppException* exception)
  47. {
  48. m_Exception = exception;
  49. }
  50. private:
  51. Il2CppException* m_Exception;
  52. FinallyBlock m_FinallyBlock;
  53. };
  54. template<typename FinallyBlock>
  55. inline FinallyHelper<FinallyBlock, false> Finally(FinallyBlock&& finallyBlock)
  56. {
  57. return FinallyHelper<FinallyBlock, false>(static_cast<FinallyBlock &&>(finallyBlock));
  58. }
  59. template<typename FinallyBlock>
  60. inline FinallyHelper<FinallyBlock, true> Fault(FinallyBlock&& finallyBlock)
  61. {
  62. return FinallyHelper<FinallyBlock, true>(static_cast<FinallyBlock &&>(finallyBlock));
  63. }
  64. }
  65. }