[Bf-blender-cvs] [8024da670c2] functions: testing initial bit array ref implementation

Jacques Lucke noreply at git.blender.org
Tue Sep 10 17:12:49 CEST 2019


Commit: 8024da670c26b0695d85631ce0b4200166de5c33
Author: Jacques Lucke
Date:   Tue Sep 10 17:02:23 2019 +0200
Branches: functions
https://developer.blender.org/rB8024da670c26b0695d85631ce0b4200166de5c33

testing initial bit array ref implementation

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

A	source/blender/blenlib/BLI_bit_array_ref.hpp
A	tests/gtests/blenlib/BLI_bit_array_ref_test.cc
M	tests/gtests/blenlib/CMakeLists.txt

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

diff --git a/source/blender/blenlib/BLI_bit_array_ref.hpp b/source/blender/blenlib/BLI_bit_array_ref.hpp
new file mode 100644
index 00000000000..8149fa0a0e7
--- /dev/null
+++ b/source/blender/blenlib/BLI_bit_array_ref.hpp
@@ -0,0 +1,100 @@
+#pragma once
+
+#include "BLI_utildefines.h"
+#include "BLI_math_base.h"
+
+namespace BLI {
+
+class BitReference {
+ private:
+  uint8_t *m_ptr;
+  uint8_t m_bit_mask;
+
+ public:
+  BitReference(uint8_t *ptr, uint8_t bit_mask) : m_ptr(ptr), m_bit_mask(bit_mask)
+  {
+    BLI_assert(is_power_of_2_i(bit_mask));
+  }
+
+  bool is_set() const
+  {
+    return *m_ptr & m_bit_mask;
+  }
+
+  void set()
+  {
+    *m_ptr |= m_bit_mask;
+  }
+
+  void unset()
+  {
+    *m_ptr &= ~m_bit_mask;
+  }
+};
+
+class MutableBitArrayRef {
+ private:
+  uint8_t *m_data = nullptr;
+  uint m_offset = 0;
+  uint m_size = 0;
+
+ public:
+  MutableBitArrayRef() = default;
+
+  MutableBitArrayRef(uint8_t *data, uint size) : m_data(data), m_offset(0), m_size(size)
+  {
+  }
+
+  MutableBitArrayRef(uint8_t *data, uint offset, uint size)
+      : m_data(data), m_offset(offset), m_size(size)
+  {
+  }
+
+  explicit MutableBitArrayRef(uint8_t &data)
+      : m_data(&data), m_offset(0), m_size(sizeof(uint8_t) * 8)
+  {
+  }
+
+  MutableBitArrayRef slice(uint start, uint size) const
+  {
+    BLI_assert(start + size <= m_size || size == 0);
+    return MutableBitArrayRef(m_data, m_offset + start, size);
+  }
+
+  uint size() const
+  {
+    return m_size;
+  }
+
+  BitReference operator[](uint index)
+  {
+    BLI_assert(index < m_size);
+    uint bit_index = m_offset + index;
+    uint8_t *ptr = m_data + bit_index / 8;
+    uint8_t offset = bit_index % 8;
+    uint8_t bit_mask = 1 << offset;
+    return BitReference(ptr, bit_mask);
+  }
+
+  const BitReference operator[](uint index) const
+  {
+    return (*const_cast<MutableBitArrayRef *>(this))[index];
+  }
+
+  bool is_set(uint index) const
+  {
+    return (*this)[index].is_set();
+  }
+
+  void set(uint index)
+  {
+    return (*this)[index].set();
+  }
+
+  void unset(uint index)
+  {
+    return (*this)[index].unset();
+  }
+};
+
+};  // namespace BLI
diff --git a/tests/gtests/blenlib/BLI_bit_array_ref_test.cc b/tests/gtests/blenlib/BLI_bit_array_ref_test.cc
new file mode 100644
index 00000000000..14d78e47de4
--- /dev/null
+++ b/tests/gtests/blenlib/BLI_bit_array_ref_test.cc
@@ -0,0 +1,100 @@
+#include "testing/testing.h"
+#include "BLI_bit_array_ref.hpp"
+
+using namespace BLI;
+
+TEST(mutable_bit_array_ref, Constructor)
+{
+  uint8_t value = 0;
+  MutableBitArrayRef ref(value);
+
+  EXPECT_EQ(ref.size(), 8);
+  EXPECT_FALSE(ref[0].is_set());
+  EXPECT_FALSE(ref[1].is_set());
+  EXPECT_FALSE(ref[2].is_set());
+  EXPECT_FALSE(ref[3].is_set());
+  EXPECT_FALSE(ref[4].is_set());
+  EXPECT_FALSE(ref[5].is_set());
+  EXPECT_FALSE(ref[6].is_set());
+  EXPECT_FALSE(ref[7].is_set());
+}
+
+TEST(mutable_bit_array_ref, Constructor2)
+{
+  uint8_t value = 130;
+  MutableBitArrayRef ref(value);
+  EXPECT_EQ(ref.size(), 8);
+
+  EXPECT_FALSE(ref[0].is_set());
+  EXPECT_TRUE(ref[1].is_set());
+  EXPECT_FALSE(ref[2].is_set());
+  EXPECT_FALSE(ref[3].is_set());
+  EXPECT_FALSE(ref[4].is_set());
+  EXPECT_FALSE(ref[5].is_set());
+  EXPECT_FALSE(ref[6].is_set());
+  EXPECT_TRUE(ref[7].is_set());
+}
+
+TEST(mutable_bit_array_ref, SetBitInByte)
+{
+  uint8_t value = 0;
+  MutableBitArrayRef ref(value);
+
+  ref[0].set();
+  EXPECT_EQ(value, 1);
+  ref[4].set();
+  EXPECT_EQ(value, 17);
+  ref[2].set();
+  EXPECT_EQ(value, 21);
+}
+
+TEST(mutable_bit_array_ref, UnsetBitInByte)
+{
+  uint8_t value = 0xFF;
+  MutableBitArrayRef ref(value);
+
+  ref[7].unset();
+  EXPECT_EQ(value, 127);
+  ref[2].unset();
+  EXPECT_EQ(value, 123);
+  ref[0].unset();
+  EXPECT_EQ(value, 122);
+}
+
+TEST(mutable_bit_array_ref, Slice)
+{
+  uint8_t value[4] = {0};
+  MutableBitArrayRef ref(value, 32);
+
+  EXPECT_EQ(ref.size(), 32);
+  auto sliced_ref = ref.slice(10, 5);
+  EXPECT_EQ(sliced_ref.size(), 5);
+  sliced_ref[2].set();
+  EXPECT_EQ(value[1], 16);
+}
+
+TEST(mutable_bit_array_ref, IsSet)
+{
+  uint8_t value[2] = {0};
+  value[0] = 0b00100110;
+  value[1] = 0b10000100;
+  MutableBitArrayRef ref(value, 16);
+
+  EXPECT_FALSE(ref.is_set(0));
+  EXPECT_FALSE(ref.is_set(3));
+  EXPECT_FALSE(ref.is_set(4));
+  EXPECT_FALSE(ref.is_set(6));
+  EXPECT_FALSE(ref.is_set(7));
+  EXPECT_FALSE(ref.is_set(8));
+  EXPECT_FALSE(ref.is_set(9));
+  EXPECT_FALSE(ref.is_set(11));
+  EXPECT_FALSE(ref.is_set(12));
+  EXPECT_FALSE(ref.is_set(13));
+  EXPECT_FALSE(ref.is_set(14));
+
+  EXPECT_TRUE(ref.is_set(1));
+  EXPECT_TRUE(ref.is_set(2));
+  EXPECT_TRUE(ref.is_set(5));
+  EXPECT_TRUE(ref.is_set(10));
+  EXPECT_TRUE(ref.is_set(15));
+}
diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt
index 95f2281fc9d..483406ccace 100644
--- a/tests/gtests/blenlib/CMakeLists.txt
+++ b/tests/gtests/blenlib/CMakeLists.txt
@@ -41,6 +41,7 @@ endif()
 BLENDER_TEST(BLI_array_store "bf_blenlib")
 BLENDER_TEST(BLI_array_utils "bf_blenlib")
 BLENDER_TEST(BLI_array_ref "bf_blenlib")
+BLENDER_TEST(BLI_bit_array_ref "bf_blenlib")
 BLENDER_TEST(BLI_chained_strings "bf_blenlib")
 BLENDER_TEST(BLI_chunked_range "bf_blenlib")
 BLENDER_TEST(BLI_delaunay_2d "bf_blenlib")



More information about the Bf-blender-cvs mailing list