Commit: 4328946e12df9e7a1410b40efc6e668e6914186e
Author: Jacques Lucke
Date:   Thu Jan 24 17:32:32 2019 +0100
Branches: functions
https://developer.blender.org/rB4328946e12df9e7a1410b40efc6e668e6914186e

work better with uninitialized memory + tests for SmallVector

===================================================================

M       source/blender/blenlib/BLI_small_vector.hpp
A       tests/gtests/blenlib/BLI_small_vector_test.cc
M       tests/gtests/blenlib/CMakeLists.txt

===================================================================

diff --git a/source/blender/blenlib/BLI_small_vector.hpp 
b/source/blender/blenlib/BLI_small_vector.hpp
index 59d309e6a66..28d9af735e0 100644
--- a/source/blender/blenlib/BLI_small_vector.hpp
+++ b/source/blender/blenlib/BLI_small_vector.hpp
@@ -3,6 +3,7 @@
 #include "BLI_utildefines.h"
 #include <cstdlib>
 #include <cstring>
+#include <memory>
 
 namespace BLI {
 
@@ -23,19 +24,12 @@ namespace BLI {
                }
 
                SmallVector(uint size)
+                       : SmallVector()
                {
-                       if (size > N) {
-                               this->m_elements = (T *)std::malloc(sizeof(T) * 
size);
-                               this->m_capacity = size;
-                       }
-                       else {
-                               this->m_elements = this->m_small_buffer;
-                               this->m_capacity = N;
-                       }
+                       this->reserve(size);
                        for (uint i = 0; i < size; i++) {
-                               this->m_elements[i] = T();
+                               this->append(T());
                        }
-                       this->m_size = size;
                }
 
                SmallVector(std::initializer_list<T> values)
@@ -144,13 +138,22 @@ namespace BLI {
                        }
 
                        this->m_capacity = min_capacity;
-                       uint new_byte_size = sizeof(T) * this->m_capacity;
-                       if (this->is_small()) {
-                               this->m_elements = (T 
*)std::malloc(new_byte_size);
+
+                       T *new_array = (T *)std::malloc(sizeof(T) * 
this->m_capacity);
+                       std::uninitialized_copy(
+                               std::make_move_iterator(this->begin()),
+                               std::make_move_iterator(this->end()),
+                               new_array);
+
+                       for (uint i = 0; i < this->m_size; i++) {
+                               (this->m_elements + i)->~T();
                        }
-                       else {
-                               this->m_elements = (T 
*)std::realloc(this->m_elements, new_byte_size);
+
+                       if (!this->is_small()) {
+                               std::free(this->m_elements);
                        }
+
+                       this->m_elements = new_array;
                }
 
                void free_own_buffer()
@@ -167,11 +170,11 @@ namespace BLI {
                {
                        if (other.is_small()) {
                                this->m_elements = this->m_small_buffer;
-                               std::memcpy(this->m_small_buffer, 
other.m_small_buffer, sizeof(T) * other.m_size);
+                               std::copy(other.begin(), other.end(), 
this->m_elements);
                        }
                        else {
                                this->m_elements = (T *)std::malloc(sizeof(T) * 
other.m_capacity);
-                               std::memcpy(this->m_elements, other.m_elements, 
other.m_size);
+                               std::uninitialized_copy(other.begin(), 
other.end(), this->m_elements);
                        }
 
                        this->m_capacity = other.m_capacity;
@@ -181,8 +184,11 @@ namespace BLI {
                void steal_from_other(SmallVector &&other)
                {
                        if (other.is_small()) {
+                               std::copy(
+                                       std::make_move_iterator(other.begin()),
+                                       std::make_move_iterator(other.end()),
+                                       this->m_small_buffer);
                                this->m_elements = this->m_small_buffer;
-                               std::memcpy(this->m_small_buffer, 
other.m_small_buffer, sizeof(T) * other.m_size);
                        }
                        else {
                                this->m_elements = other.m_elements;
diff --git a/tests/gtests/blenlib/BLI_small_vector_test.cc 
b/tests/gtests/blenlib/BLI_small_vector_test.cc
new file mode 100644
index 00000000000..13499be7e67
--- /dev/null
+++ b/tests/gtests/blenlib/BLI_small_vector_test.cc
@@ -0,0 +1,144 @@
+#include "testing/testing.h"
+#include "BLI_small_vector.hpp"
+
+using IntVector = BLI::SmallVector<int>;
+
+TEST(small_vector, DefaultConstructor)
+{
+       IntVector vec;
+       EXPECT_EQ(vec.size(), 0);
+}
+
+TEST(small_vector, SizeConstructor)
+{
+       IntVector vec(3);
+       EXPECT_EQ(vec.size(), 3);
+       EXPECT_EQ(vec[0], 0);
+       EXPECT_EQ(vec[1], 0);
+       EXPECT_EQ(vec[2], 0);
+}
+
+TEST(small_vector, InitializerListConstructor)
+{
+       IntVector vec = {1, 3, 4, 6};
+       EXPECT_EQ(vec.size(), 4);
+       EXPECT_EQ(vec[0], 1);
+       EXPECT_EQ(vec[1], 3);
+       EXPECT_EQ(vec[2], 4);
+       EXPECT_EQ(vec[3], 6);
+}
+
+TEST(small_vector, CopyConstructor)
+{
+       IntVector vec1 = {1, 2, 3};
+       IntVector vec2(vec1);
+       EXPECT_EQ(vec2.size(), 3);
+       EXPECT_EQ(vec2[0], 1);
+       EXPECT_EQ(vec2[1], 2);
+       EXPECT_EQ(vec2[2], 3);
+
+       vec1[1] = 5;
+       EXPECT_EQ(vec1[1], 5);
+       EXPECT_EQ(vec2[1], 2);
+}
+
+TEST(small_vector, MoveAssignment)
+{
+       IntVector vec = {1, 2};
+       EXPECT_EQ(vec.size(), 2);
+       EXPECT_EQ(vec[0], 1);
+       EXPECT_EQ(vec[1], 2);
+
+       vec = IntVector({5});
+       EXPECT_EQ(vec.size(), 1);
+       EXPECT_EQ(vec[0], 5);
+}
+
+TEST(small_vector, CopyAssignment)
+{
+       IntVector vec1 = {1, 2, 3};
+       IntVector vec2 = {4, 5};
+       EXPECT_EQ(vec1.size(), 3);
+       EXPECT_EQ(vec2.size(), 2);
+
+       vec2 = vec1;
+       EXPECT_EQ(vec2.size(), 3);
+
+       vec1[0] = 7;
+       EXPECT_EQ(vec1[0], 7);
+       EXPECT_EQ(vec2[0], 1);
+}
+
+TEST(small_vector, Append)
+{
+       IntVector vec;
+       vec.append(3);
+       vec.append(6);
+       vec.append(7);
+       EXPECT_EQ(vec.size(), 3);
+       EXPECT_EQ(vec[0], 3);
+       EXPECT_EQ(vec[1], 6);
+       EXPECT_EQ(vec[2], 7);
+}
+
+TEST(small_vector, Fill)
+{
+       IntVector vec(5);
+       vec.fill(3);
+       EXPECT_EQ(vec.size(), 5);
+       EXPECT_EQ(vec[0], 3);
+       EXPECT_EQ(vec[1], 3);
+       EXPECT_EQ(vec[2], 3);
+       EXPECT_EQ(vec[3], 3);
+       EXPECT_EQ(vec[4], 3);
+}
+
+TEST(small_vector, Iterator)
+{
+       IntVector vec({1, 4, 9, 16});
+       int i = 1;
+       for (int value : vec) {
+               EXPECT_EQ(value, i * i);
+               i++;
+       }
+}
+
+TEST(small_Vector, BecomeLarge)
+{
+       BLI::SmallVector<int, 4> vec;
+       for (int i = 0; i < 100; i++) {
+               vec.append(i * 5);
+       }
+       EXPECT_EQ(vec.size(), 100);
+       for (int i = 0; i < 100; i++) {
+               EXPECT_EQ(vec[i], i * 5);
+       }
+}
+
+IntVector return_by_value_helper()
+{
+       return IntVector({3, 5, 1});
+}
+
+TEST(small_vector, ReturnByValue)
+{
+       IntVector vec = return_by_value_helper();
+       EXPECT_EQ(vec.size(), 3);
+       EXPECT_EQ(vec[0], 3);
+       EXPECT_EQ(vec[1], 5);
+       EXPECT_EQ(vec[2], 1);
+}
+
+TEST(small_vector, VectorOfVectors_Append)
+{
+       BLI::SmallVector<IntVector> vec;
+       EXPECT_EQ(vec.size(), 0);
+
+       vec.append({1, 2});
+       vec.append({7, 8});
+       EXPECT_EQ(vec.size(), 2);
+       EXPECT_EQ(vec[0][0], 1);
+       EXPECT_EQ(vec[0][1], 2);
+       EXPECT_EQ(vec[1][0], 7);
+       EXPECT_EQ(vec[1][1], 8);
+}
\ No newline at end of file
diff --git a/tests/gtests/blenlib/CMakeLists.txt 
b/tests/gtests/blenlib/CMakeLists.txt
index e837f703423..4da1a42d7ec 100644
--- a/tests/gtests/blenlib/CMakeLists.txt
+++ b/tests/gtests/blenlib/CMakeLists.txt
@@ -55,6 +55,7 @@ BLENDER_TEST(BLI_math_geom "bf_blenlib")
 BLENDER_TEST(BLI_memiter "bf_blenlib")
 BLENDER_TEST(BLI_path_util "${BLI_path_util_extra_libs}")
 BLENDER_TEST(BLI_polyfill_2d "bf_blenlib")
+BLENDER_TEST(BLI_small_vector "bf_blenlib")
 BLENDER_TEST(BLI_stack "bf_blenlib")
 BLENDER_TEST(BLI_string "bf_blenlib")
 BLENDER_TEST(BLI_string_utf8 "bf_blenlib")

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to