DynamicArray.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #ifndef ANKI_UTIL_DYNAMIC_ARRAY_H
  2. #define ANKI_UTIL_DYNAMIC_ARRAY_H
  3. #include "anki/util/Allocator.h"
  4. namespace anki {
  5. /// @addtogroup util
  6. /// @{
  7. /// @addtogroup containers
  8. /// @{
  9. template<typename T, typename Alloc = Allocator<T>>
  10. class DynamicArray
  11. {
  12. public:
  13. typedef T Value;
  14. typedef Value* Iterator;
  15. typedef const Value* ConstIterator;
  16. typedef Value& Reference;
  17. typedef const Value& ConstReference;
  18. /// @name Constructors/destructor
  19. /// @{
  20. /// Default
  21. DynamicArray()
  22. {}
  23. /// Copy is deleted
  24. DynamicArray(const DynamicArray&) = delete;
  25. /// Move
  26. DynamicArray(DynamicArray&& other)
  27. : b(other.e), e(other.e), allocator(other.allocator)
  28. {
  29. other.b = nullptr;
  30. }
  31. /// Allocate the array
  32. DynamicArray(const PtrSize n, const Alloc& alloc = Alloc())
  33. : allocator(alloc)
  34. {
  35. resize(n);
  36. }
  37. ///
  38. DynamicArray(const Alloc& alloc)
  39. : allocator(alloc)
  40. {}
  41. /// Deallocate
  42. ~DynamicArray()
  43. {
  44. clear();
  45. }
  46. /// @}
  47. Reference operator[](const PtrSize n)
  48. {
  49. ANKI_ASSERT(b != nullptr);
  50. ANKI_ASSERT(n < getSize());
  51. return *(begin + n);
  52. }
  53. ConstReference operator[](const PtrSize n) const
  54. {
  55. ANKI_ASSERT(b != nullptr);
  56. ANKI_ASSERT(n < getSize());
  57. return *(begin + n);
  58. }
  59. /// Copy is not permited
  60. DynamicArray& operator=(const DynamicArray&) = delete;
  61. /// Move
  62. DynamicArray& operator=(DynamicArray&& other)
  63. {
  64. clear();
  65. b = other.b;
  66. e = other.e;
  67. allocator = b.allocator;
  68. other.b = nullptr;
  69. other.e = nullptr;
  70. return *this;
  71. }
  72. /// Make it compatible with the C++11 range based for loop
  73. Iterator begin()
  74. {
  75. ANKI_ASSERT(b != nullptr);
  76. return b;
  77. }
  78. /// Make it compatible with the C++11 range based for loop
  79. ConstIterator begin() const
  80. {
  81. ANKI_ASSERT(b != nullptr);
  82. return b;
  83. }
  84. /// Make it compatible with the C++11 range based for loop
  85. Iterator end()
  86. {
  87. ANKI_ASSERT(b != nullptr);
  88. return e;
  89. }
  90. /// Make it compatible with the C++11 range based for loop
  91. ConstIterator end() const
  92. {
  93. ANKI_ASSERT(b != nullptr);
  94. return e;
  95. }
  96. /// Get the elements count
  97. PtrSize getSize() const
  98. {
  99. return e - b;
  100. }
  101. /// Resize the array and call the constructors
  102. template<typename... Args>
  103. void resize(const PtrSize n, Args&&... args)
  104. {
  105. ANKI_ASSERT(b == nullptr && e == nullptr);
  106. ANKI_ASSERT(n > 0);
  107. // Allocate memory
  108. b = allocator.allocate(n);
  109. e = b + n;
  110. // Call the constructors
  111. for(PtrSize i = 0; i < n; i++)
  112. {
  113. allocator.construct(b + i, std::forward<Args>(args)...);
  114. }
  115. }
  116. /// Clear the array
  117. void clear()
  118. {
  119. if(b)
  120. {
  121. ANKI_ASSERT(e != nullptr);
  122. PtrSize n = getSize();
  123. ANKI_ASSERT(n > 0);
  124. // Call the destructors
  125. for(PtrSize i = 0; i < n; i++)
  126. {
  127. allocator.destroy(b + i);
  128. }
  129. // Deallocate the memory
  130. allocator.deallocate(b, n);
  131. // Reset the data
  132. b = nullptr;
  133. e = nullptr;
  134. }
  135. }
  136. private:
  137. Value* b = nullptr;
  138. Value* e = nullptr;
  139. Alloc allocator;
  140. };
  141. /// @}
  142. /// @}
  143. } // end namespace anki
  144. #endif