Allocator.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. /// \file
  4. /// @nobindfile
  5. #pragma once
  6. #ifdef URHO3D_IS_BUILDING
  7. #include "Urho3D.h"
  8. #else
  9. #include <Urho3D/Urho3D.h>
  10. #endif
  11. #include "../Base/PrimitiveTypes.h"
  12. #include <cstddef>
  13. namespace Urho3D
  14. {
  15. struct AllocatorNode;
  16. /// %Allocator memory block.
  17. struct AllocatorBlock
  18. {
  19. /// Size of a node.
  20. i32 nodeSize_;
  21. /// Number of nodes in this block.
  22. i32 capacity_;
  23. /// First free node.
  24. AllocatorNode* free_;
  25. /// Next allocator block.
  26. AllocatorBlock* next_;
  27. // Nodes follow
  28. };
  29. /// %Allocator node.
  30. struct AllocatorNode
  31. {
  32. /// Next free node.
  33. AllocatorNode* next_;
  34. // Data follows
  35. };
  36. /// Initialize a fixed-size allocator with the node size and initial capacity.
  37. URHO3D_API AllocatorBlock* AllocatorInitialize(i32 nodeSize, i32 initialCapacity = 1);
  38. /// Uninitialize a fixed-size allocator. Frees all blocks in the chain.
  39. URHO3D_API void AllocatorUninitialize(AllocatorBlock* allocator);
  40. /// Reserve a node. Creates a new block if necessary.
  41. URHO3D_API void* AllocatorReserve(AllocatorBlock* allocator);
  42. /// Free a node. Does not free any blocks.
  43. URHO3D_API void AllocatorFree(AllocatorBlock* allocator, void* ptr);
  44. /// %Allocator template class. Allocates objects of a specific class.
  45. template <class T> class Allocator
  46. {
  47. private:
  48. /// Allocator block.
  49. AllocatorBlock* allocator_;
  50. public:
  51. /// Construct.
  52. explicit Allocator(i32 initialCapacity = 0)
  53. : allocator_(nullptr)
  54. {
  55. if (initialCapacity)
  56. allocator_ = AllocatorInitialize((i32)sizeof(T), initialCapacity);
  57. }
  58. /// Destruct.
  59. ~Allocator()
  60. {
  61. AllocatorUninitialize(allocator_);
  62. }
  63. /// Prevent copy construction.
  64. Allocator(const Allocator<T>& rhs) = delete;
  65. /// Prevent assignment.
  66. Allocator<T>& operator =(const Allocator<T>& rhs) = delete;
  67. /// Reserve and default-construct an object.
  68. T* Reserve()
  69. {
  70. if (!allocator_)
  71. allocator_ = AllocatorInitialize((i32)sizeof(T));
  72. T* newObject = static_cast<T*>(AllocatorReserve(allocator_));
  73. new(newObject) T();
  74. return newObject;
  75. }
  76. /// Reserve and copy-construct an object.
  77. T* Reserve(const T& object)
  78. {
  79. if (!allocator_)
  80. allocator_ = AllocatorInitialize((i32)sizeof(T));
  81. T* newObject = static_cast<T*>(AllocatorReserve(allocator_));
  82. new(newObject) T(object);
  83. return newObject;
  84. }
  85. /// Destruct and free an object.
  86. void Free(T* object)
  87. {
  88. (object)->~T();
  89. AllocatorFree(allocator_, object);
  90. }
  91. };
  92. }