[Bf-blender-cvs] [4328946e12d] functions: work better with uninitialized memory + tests for SmallVector
Jacques Lucke
noreply at git.blender.org
Sun Feb 10 20:25:20 CET 2019
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")
More information about the Bf-blender-cvs
mailing list