ResourceGuard.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #pragma once
  2. template<typename __ResourceTraits>
  3. class ResourceGuard {
  4. private:
  5. using HandleType = typename __ResourceTraits::HandleType;
  6. HandleType _Handle;
  7. bool _DismissFlag;
  8. public:
  9. ResourceGuard() noexcept :
  10. _Handle(__ResourceTraits::InvalidValue),
  11. _DismissFlag(false) {}
  12. explicit ResourceGuard(HandleType Handle) :
  13. _Handle(Handle),
  14. _DismissFlag(false) {}
  15. ResourceGuard(const ResourceGuard<__ResourceTraits>& Other) noexcept :
  16. _Handle(Other._Handle),
  17. _DismissFlag(false) {}
  18. ResourceGuard(ResourceGuard<__ResourceTraits>&& Other) noexcept :
  19. _Handle(Other._Handle),
  20. _DismissFlag(false) { Other._Handle = __ResourceTraits::InvalidValue; }
  21. ResourceGuard<__ResourceTraits>&
  22. operator=(const ResourceGuard<__ResourceTraits>& Other) noexcept {
  23. _Handle = Other._Handle;
  24. return *this;
  25. }
  26. ResourceGuard<__ResourceTraits>&
  27. operator=(ResourceGuard<__ResourceTraits>&& Other) noexcept {
  28. _Handle = Other._Handle;
  29. Other._Handle = __ResourceTraits::InvalidValue;
  30. return *this;
  31. }
  32. operator HandleType() const noexcept {
  33. return _Handle;
  34. }
  35. // Check if handle is a valid handle
  36. bool IsValid() const noexcept {
  37. return _Handle != __ResourceTraits::InvalidValue;
  38. }
  39. HandleType GetHandle() const noexcept {
  40. return _Handle;
  41. }
  42. // Abandon possession of the previous handle without any conditions
  43. // You must make sure that the previous handle has been released
  44. // OR has been possessed by others
  45. void TakeHoldOf(HandleType Handle) noexcept {
  46. _Handle = Handle;
  47. }
  48. // If dismiss, the handle won't be released when ResourceGuard is destructed.
  49. void Dismiss() noexcept {
  50. _DismissFlag = true;
  51. }
  52. // Cancel Dismiss() operation
  53. void DismissCancel() noexcept {
  54. _DismissFlag = false;
  55. }
  56. // Force release
  57. void Release() {
  58. if (_Handle != __ResourceTraits::InvalidValue) {
  59. __ResourceTraits::Releasor(_Handle);
  60. _Handle = __ResourceTraits::InvalidValue;
  61. }
  62. }
  63. ~ResourceGuard() {
  64. if (!_DismissFlag && _Handle != __ResourceTraits::InvalidValue) {
  65. __ResourceTraits::Releasor(_Handle);
  66. _Handle = __ResourceTraits::InvalidValue;
  67. }
  68. }
  69. };
  70. template<typename __ClassType>
  71. struct CppObjectTraits {
  72. using HandleType = __ClassType*;
  73. static inline const HandleType InvalidValue = nullptr;
  74. static inline void Releasor(HandleType pObject) {
  75. delete pObject;
  76. }
  77. };
  78. template<typename __ClassType>
  79. struct CppDynamicArrayTraits {
  80. using HandleType = __ClassType*;
  81. static inline const HandleType InvalidValue = nullptr;
  82. static inline void Releasor(HandleType pArray) {
  83. delete[] pArray;
  84. }
  85. };