diff options
author | Jacques Lucke <mail@jlucke.com> | 2020-02-10 15:54:57 +0300 |
---|---|---|
committer | Jacques Lucke <mail@jlucke.com> | 2020-02-10 16:09:01 +0300 |
commit | 68cc982dcb7c1063a96f7ec9b7ccb95da4919d6b (patch) | |
tree | 9d2076363b54cb6b6da96064453ac3499a5f65c8 /source/blender/blenlib/BLI_array_cxx.h | |
parent | 76208a5670bc9d70f99f22a3c49463959461b5c1 (diff) |
BLI: improve various C++ data structures
The changes come from the `functions` branch, where I'm using
these structures a lot.
This also includes a new `BLI::Optional<T>` type, which is similar
to `std::Optional<T>` which can be used when Blender starts using
C++17.
Diffstat (limited to 'source/blender/blenlib/BLI_array_cxx.h')
-rw-r--r-- | source/blender/blenlib/BLI_array_cxx.h | 67 |
1 files changed, 49 insertions, 18 deletions
diff --git a/source/blender/blenlib/BLI_array_cxx.h b/source/blender/blenlib/BLI_array_cxx.h index e987121d68c..adb00c95f28 100644 --- a/source/blender/blenlib/BLI_array_cxx.h +++ b/source/blender/blenlib/BLI_array_cxx.h @@ -31,23 +31,24 @@ namespace BLI { -template<typename T, typename Allocator = GuardedAllocator> class Array { +template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Array { private: T *m_data; uint m_size; Allocator m_allocator; + AlignedBuffer<sizeof(T) * N, alignof(T)> m_inline_storage; public: Array() { - m_data = nullptr; + m_data = this->inline_storage(); m_size = 0; } Array(ArrayRef<T> values) { m_size = values.size(); - m_data = this->allocate(m_size); + m_data = this->get_buffer_for_size(values.size()); uninitialized_copy_n(values.begin(), m_size, m_data); } @@ -57,8 +58,8 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { explicit Array(uint size) { - m_data = this->allocate(size); m_size = size; + m_data = this->get_buffer_for_size(size); for (uint i = 0; i < m_size; i++) { new (m_data + i) T(); @@ -67,8 +68,8 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { Array(uint size, const T &value) { - m_data = this->allocate(size); m_size = size; + m_data = this->get_buffer_for_size(size); uninitialized_fill_n(m_data, m_size, value); } @@ -77,30 +78,31 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { m_size = other.size(); m_allocator = other.m_allocator; - if (m_size == 0) { - m_data = nullptr; - return; - } - else { - m_data = this->allocate(m_size); - copy_n(other.begin(), m_size, m_data); - } + m_data = this->get_buffer_for_size(other.size()); + copy_n(other.begin(), m_size, m_data); } Array(Array &&other) noexcept { - m_data = other.m_data; m_size = other.m_size; m_allocator = other.m_allocator; - other.m_data = nullptr; + if (!other.uses_inline_storage()) { + m_data = other.m_data; + } + else { + m_data = this->get_buffer_for_size(m_size); + uninitialized_relocate_n(other.m_data, m_size, m_data); + } + + other.m_data = other.inline_storage(); other.m_size = 0; } ~Array() { destruct_n(m_data, m_size); - if (m_data != nullptr) { + if (!this->uses_inline_storage()) { m_allocator.deallocate((void *)m_data); } } @@ -142,12 +144,23 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { return *this; } + MutableArrayRef<T> as_mutable_ref() + { + return *this; + } + T &operator[](uint index) { BLI_assert(index < m_size); return m_data[index]; } + const T &operator[](uint index) const + { + BLI_assert(index < m_size); + return m_data[index]; + } + uint size() const { return m_size; @@ -189,14 +202,32 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { } private: + T *get_buffer_for_size(uint size) + { + if (size <= N) { + return this->inline_storage(); + } + else { + return this->allocate(size); + } + } + + T *inline_storage() const + { + return (T *)m_inline_storage.ptr(); + } + T *allocate(uint size) { return (T *)m_allocator.allocate_aligned( size * sizeof(T), std::alignment_of<T>::value, __func__); } -}; -template<typename T> using TemporaryArray = Array<T, TemporaryAllocator>; + bool uses_inline_storage() const + { + return m_data == this->inline_storage(); + } +}; } // namespace BLI |