Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <mail@jlucke.com>2020-02-10 15:54:57 +0300
committerJacques Lucke <mail@jlucke.com>2020-02-10 16:09:01 +0300
commit68cc982dcb7c1063a96f7ec9b7ccb95da4919d6b (patch)
tree9d2076363b54cb6b6da96064453ac3499a5f65c8 /source/blender/blenlib/BLI_array_cxx.h
parent76208a5670bc9d70f99f22a3c49463959461b5c1 (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.h67
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