AutoAllocatorObjectPtr.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace Memory
  7. {
  8. // This object ensures DeleteObject (AllocatorDelete) for an allocator allocated object.
  9. template <typename T, typename TAllocator>
  10. class AutoAllocatorObjectPtr : public BasePtr<T>
  11. {
  12. private:
  13. typedef typename AllocatorInfo<TAllocator, T>::AllocatorType AllocatorType;
  14. AllocatorType* m_allocator;
  15. public:
  16. AutoAllocatorObjectPtr(T* ptr, AllocatorType* allocator) : BasePtr<T>(ptr), m_allocator(allocator)
  17. {
  18. Assert(allocator);
  19. }
  20. ~AutoAllocatorObjectPtr()
  21. {
  22. Clear();
  23. }
  24. private:
  25. void Clear()
  26. {
  27. if (this->ptr != nullptr)
  28. {
  29. DeleteObject<TAllocator>(m_allocator, this->ptr);
  30. this->ptr = nullptr;
  31. }
  32. }
  33. };
  34. // The version of AutoArrayPtr that uses allocator to release the memory.
  35. template <typename T, typename TAllocator>
  36. class AutoAllocatorArrayPtr : public BasePtr<T>
  37. {
  38. protected:
  39. typedef typename AllocatorInfo<TAllocator, T>::AllocatorType AllocatorType;
  40. size_t m_elementCount;
  41. AllocatorType* m_allocator;
  42. public:
  43. AutoAllocatorArrayPtr(T * ptr, size_t elementCount, AllocatorType* allocator) : BasePtr(ptr), m_elementCount(elementCount), m_allocator(allocator)
  44. {
  45. Assert(allocator);
  46. }
  47. ~AutoAllocatorArrayPtr()
  48. {
  49. Clear();
  50. }
  51. // Do not support "operator=(T* ptr)". The new ptr may have a different elementCount.
  52. private:
  53. void Clear()
  54. {
  55. if (this->ptr != nullptr)
  56. {
  57. DeleteArray<TAllocator>(m_allocator, this->m_elementCount, this->ptr);
  58. this->ptr = nullptr;
  59. }
  60. }
  61. };
  62. // This version of AutoArrayPtr points to an array of AllocatorObject pointers (T*). It ensures AllocatorDelete
  63. // each AllocatorObject pointer contained in the array, before deleting the array itself.
  64. //
  65. // Template parameter:
  66. // T The object type allocated from allocator. The array contains T*.
  67. // TAllocator The allocator type used to allocate/free the objects.
  68. // ArrayAllocator The allocator type used to allocate/free the array.
  69. //
  70. template <typename T, typename TAllocator, typename ArrayAllocator = typename ForceNonLeafAllocator<TAllocator>::AllocatorType>
  71. class AutoAllocatorObjectArrayPtr : public AutoAllocatorArrayPtr<T*, ArrayAllocator>
  72. {
  73. typedef AutoAllocatorArrayPtr<T*, ArrayAllocator> Base;
  74. public:
  75. AutoAllocatorObjectArrayPtr(T** ptr, size_t elementCount, typename Base::AllocatorType* allocator) :
  76. AutoAllocatorArrayPtr(ptr, elementCount, allocator)
  77. {
  78. }
  79. ~AutoAllocatorObjectArrayPtr()
  80. {
  81. Clear();
  82. }
  83. // Do not support "operator=(T* ptr)". The new ptr may have a different elementCount.
  84. private:
  85. void Clear()
  86. {
  87. if (this->ptr != nullptr)
  88. {
  89. for (size_t i = 0; i < this->m_elementCount; i++)
  90. {
  91. if (this->ptr[i] != nullptr)
  92. {
  93. DeleteObject<TAllocator>(this->m_allocator, this->ptr[i]);
  94. this->ptr[i] = nullptr;
  95. }
  96. }
  97. }
  98. }
  99. };
  100. }