[Bf-blender-cvs] [8ab87c1998e] functions: initial StringCollection class

Jacques Lucke noreply at git.blender.org
Wed May 15 17:17:02 CEST 2019


Commit: 8ab87c1998e4919fde5d8d13bfde593a10f8790c
Author: Jacques Lucke
Date:   Wed May 15 17:16:47 2019 +0200
Branches: functions
https://developer.blender.org/rB8ab87c1998e4919fde5d8d13bfde593a10f8790c

initial StringCollection class

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

M	source/blender/blenlib/BLI_small_vector.hpp
A	source/blender/blenlib/BLI_string_collection.hpp
M	source/blender/blenlib/BLI_string_ref.hpp
M	source/blender/blenlib/CMakeLists.txt
M	tests/gtests/blenlib/BLI_small_vector_test.cc
A	tests/gtests/blenlib/BLI_string_collection_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 fcdf23705dd..90273524ea9 100644
--- a/source/blender/blenlib/BLI_small_vector.hpp
+++ b/source/blender/blenlib/BLI_small_vector.hpp
@@ -129,6 +129,13 @@ template<typename T, uint N = 4> class SmallVector {
     }
   }
 
+  void extend(const T *start, uint amount)
+  {
+    for (uint i = 0; i < amount; i++) {
+      this->append(start[i]);
+    }
+  }
+
   void fill(const T &value)
   {
     for (uint i = 0; i < m_size; i++) {
diff --git a/source/blender/blenlib/BLI_string_collection.hpp b/source/blender/blenlib/BLI_string_collection.hpp
new file mode 100644
index 00000000000..c0180bef214
--- /dev/null
+++ b/source/blender/blenlib/BLI_string_collection.hpp
@@ -0,0 +1,71 @@
+#pragma once
+
+/* Utility classes to store multiple strings in a continuous
+ * memory buffer. */
+
+#include "BLI_string_ref.hpp"
+#include "BLI_small_vector.hpp"
+
+namespace BLI {
+
+class StringCollection {
+ private:
+  const char *m_data;
+  SmallVector<StringRefNull> m_strings;
+
+  StringCollection(StringCollection &other) = delete;
+
+ public:
+  StringCollection(const char *data, SmallVector<StringRefNull> strings)
+      : m_data(data), m_strings(std::move(strings))
+  {
+  }
+
+  ~StringCollection()
+  {
+    MEM_freeN((void *)m_data);
+  }
+
+  StringRefNull get_ref(uint index) const
+  {
+    return m_strings[index];
+  }
+
+  uint size() const
+  {
+    return m_strings.size();
+  }
+};
+
+class StringCollectionBuilder {
+ private:
+  SmallVector<char, 64> m_chars;
+  SmallVector<uint> m_offsets;
+
+ public:
+  StringCollectionBuilder() = default;
+
+  /* Returns the index in the final collection */
+  uint insert(StringRef ref)
+  {
+    m_offsets.append(m_chars.size());
+    m_chars.extend(ref.data(), ref.size());
+    m_chars.append('\0');
+    return m_offsets.size() - 1;
+  }
+
+  StringCollection *build()
+  {
+    char *data = (char *)MEM_mallocN(m_chars.size(), __func__);
+    memcpy(data, m_chars.begin(), m_chars.size());
+    SmallVector<StringRefNull> references;
+
+    for (uint start_offset : m_offsets) {
+      references.append(StringRefNull(data + start_offset));
+    }
+
+    return new StringCollection(data, references);
+  }
+};
+
+}  // namespace BLI
diff --git a/source/blender/blenlib/BLI_string_ref.hpp b/source/blender/blenlib/BLI_string_ref.hpp
index 1a214a29544..03b2afa64d2 100644
--- a/source/blender/blenlib/BLI_string_ref.hpp
+++ b/source/blender/blenlib/BLI_string_ref.hpp
@@ -1,7 +1,9 @@
 #pragma once
 
 /* Two types of string references. One that guarantees null termination
- * and one that does not. */
+ * and one that does not. The data referenced should be considered
+ * to be immutable. If we need a StringRef to a mutable string,
+ * a new class (e.g. MutableStringRef) should be implemented. */
 
 #include <cstring>
 #include <string>
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index b6b4a3e7647..21e584d2c80 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -251,6 +251,7 @@ set(SRC
   BLI_small_set.hpp
   BLI_small_set_vector.hpp
   BLI_small_stack.hpp
+  BLI_string_collection.hpp
   BLI_string_ref.hpp
   BLI_timeit.hpp
 )
diff --git a/tests/gtests/blenlib/BLI_small_vector_test.cc b/tests/gtests/blenlib/BLI_small_vector_test.cc
index 7dedd48e766..2bd943a5e0b 100644
--- a/tests/gtests/blenlib/BLI_small_vector_test.cc
+++ b/tests/gtests/blenlib/BLI_small_vector_test.cc
@@ -208,3 +208,15 @@ TEST(small_vector, AllEqual_True)
   bool result = IntVector::all_equal(a, b);
   EXPECT_TRUE(result);
 }
+
+TEST(small_vector, ExtendArray)
+{
+  int array[] = {3, 4, 5, 6};
+
+  IntVector a;
+  a.extend(array, 2);
+
+  EXPECT_EQ(a.size(), 2);
+  EXPECT_EQ(a[0], 3);
+  EXPECT_EQ(a[1], 4);
+}
diff --git a/tests/gtests/blenlib/BLI_string_collection_test.cc b/tests/gtests/blenlib/BLI_string_collection_test.cc
new file mode 100644
index 00000000000..8b0745e203a
--- /dev/null
+++ b/tests/gtests/blenlib/BLI_string_collection_test.cc
@@ -0,0 +1,50 @@
+#include "testing/testing.h"
+#include "BLI_string_collection.hpp"
+
+using BLI::StringCollection;
+using BLI::StringCollectionBuilder;
+
+TEST(string_collection, Empty)
+{
+  StringCollectionBuilder builder;
+
+  StringCollection *collection = builder.build();
+  EXPECT_EQ(collection->size(), 0);
+}
+
+TEST(string_collection, Single)
+{
+  StringCollectionBuilder builder;
+  builder.insert("Hello");
+
+  StringCollection *collection = builder.build();
+  EXPECT_EQ(collection->size(), 1);
+  EXPECT_EQ(collection->get_ref(0).size(), 5);
+  EXPECT_EQ(collection->get_ref(0).to_std_string(), "Hello");
+}
+
+TEST(string_collection, Multiple)
+{
+  StringCollectionBuilder builder;
+  EXPECT_EQ(builder.insert("asd"), 0);
+  EXPECT_EQ(builder.insert("qwef"), 1);
+  EXPECT_EQ(builder.insert("zxcvb"), 2);
+
+  StringCollection *collection = builder.build();
+  EXPECT_EQ(collection->size(), 3);
+  EXPECT_EQ(collection->get_ref(0).to_std_string(), "asd");
+  EXPECT_EQ(collection->get_ref(1).to_std_string(), "qwef");
+  EXPECT_EQ(collection->get_ref(2).to_std_string(), "zxcvb");
+}
+
+TEST(string_collection, CreatesCopy)
+{
+  const char *str = "Test";
+
+  StringCollectionBuilder builder;
+  builder.insert(str);
+
+  StringCollection *collection = builder.build();
+  EXPECT_EQ(collection->size(), 1);
+  EXPECT_NE(collection->get_ref(0).data(), str);
+}
diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt
index 477a99938ee..4fee8372ac7 100644
--- a/tests/gtests/blenlib/CMakeLists.txt
+++ b/tests/gtests/blenlib/CMakeLists.txt
@@ -70,6 +70,7 @@ BLENDER_TEST(BLI_small_stack "bf_blenlib")
 BLENDER_TEST(BLI_small_map "bf_blenlib")
 BLENDER_TEST(BLI_stack "bf_blenlib")
 BLENDER_TEST(BLI_string "bf_blenlib")
+BLENDER_TEST(BLI_string_collection "bf_blenlib")
 BLENDER_TEST(BLI_string_ref "bf_blenlib")
 BLENDER_TEST(BLI_string_utf8 "bf_blenlib")
 BLENDER_TEST(BLI_task "bf_blenlib;bf_intern_numaapi")



More information about the Bf-blender-cvs mailing list