| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- #ifndef ANKI_UTIL_DYNAMIC_ARRAY_H
- #define ANKI_UTIL_DYNAMIC_ARRAY_H
- #include "anki/util/Allocator.h"
- namespace anki {
- /// @addtogroup util
- /// @{
- /// @addtogroup containers
- /// @{
- template<typename T, typename Alloc = Allocator<T>>
- class DynamicArray
- {
- public:
- typedef T Value;
- typedef Value* Iterator;
- typedef const Value* ConstIterator;
- typedef Value& Reference;
- typedef const Value& ConstReference;
- /// @name Constructors/destructor
- /// @{
- /// Default
- DynamicArray()
- {}
- /// Copy is deleted
- DynamicArray(const DynamicArray&) = delete;
- /// Move
- DynamicArray(DynamicArray&& other)
- : b(other.e), e(other.e), allocator(other.allocator)
- {
- other.b = nullptr;
- }
- /// Allocate the array
- DynamicArray(const PtrSize n, const Alloc& alloc = Alloc())
- : allocator(alloc)
- {
- resize(n);
- }
- ///
- DynamicArray(const Alloc& alloc)
- : allocator(alloc)
- {}
- /// Deallocate
- ~DynamicArray()
- {
- clear();
- }
- /// @}
- Reference operator[](const PtrSize n)
- {
- ANKI_ASSERT(b != nullptr);
- ANKI_ASSERT(n < getSize());
- return *(begin + n);
- }
- ConstReference operator[](const PtrSize n) const
- {
- ANKI_ASSERT(b != nullptr);
- ANKI_ASSERT(n < getSize());
- return *(begin + n);
- }
- /// Copy is not permited
- DynamicArray& operator=(const DynamicArray&) = delete;
- /// Move
- DynamicArray& operator=(DynamicArray&& other)
- {
- clear();
- b = other.b;
- e = other.e;
- allocator = b.allocator;
- other.b = nullptr;
- other.e = nullptr;
- return *this;
- }
- /// Make it compatible with the C++11 range based for loop
- Iterator begin()
- {
- ANKI_ASSERT(b != nullptr);
- return b;
- }
- /// Make it compatible with the C++11 range based for loop
- ConstIterator begin() const
- {
- ANKI_ASSERT(b != nullptr);
- return b;
- }
- /// Make it compatible with the C++11 range based for loop
- Iterator end()
- {
- ANKI_ASSERT(b != nullptr);
- return e;
- }
- /// Make it compatible with the C++11 range based for loop
- ConstIterator end() const
- {
- ANKI_ASSERT(b != nullptr);
- return e;
- }
- /// Get the elements count
- PtrSize getSize() const
- {
- return e - b;
- }
- /// Resize the array and call the constructors
- template<typename... Args>
- void resize(const PtrSize n, Args&&... args)
- {
- ANKI_ASSERT(b == nullptr && e == nullptr);
- ANKI_ASSERT(n > 0);
- // Allocate memory
- b = allocator.allocate(n);
- e = b + n;
- // Call the constructors
- for(PtrSize i = 0; i < n; i++)
- {
- allocator.construct(b + i, std::forward<Args>(args)...);
- }
- }
- /// Clear the array
- void clear()
- {
- if(b)
- {
- ANKI_ASSERT(e != nullptr);
- PtrSize n = getSize();
- ANKI_ASSERT(n > 0);
- // Call the destructors
- for(PtrSize i = 0; i < n; i++)
- {
- allocator.destroy(b + i);
- }
- // Deallocate the memory
- allocator.deallocate(b, n);
- // Reset the data
- b = nullptr;
- e = nullptr;
- }
- }
- private:
- Value* b = nullptr;
- Value* e = nullptr;
- Alloc allocator;
- };
- /// @}
- /// @}
- } // end namespace anki
- #endif
|