Define BitString and BitStringBuffer
BitString is a general purpose class providing the ability to manipulate
individual bits within an allocated section of contiguous memory. A
BitString does not allocate or maintain the memory that it manipulates.
BitStringBuffer is a BitString that allocates and maintains the memory
that it manipulates.
Signed-off-by: Ben Tyner <ben.tyner@ibm.com>
Change-Id: I64e691a169d571dc1fd435a30b666312854346ac
diff --git a/test/bit_string_test.cpp b/test/bit_string_test.cpp
new file mode 100644
index 0000000..8320d97
--- /dev/null
+++ b/test/bit_string_test.cpp
@@ -0,0 +1,169 @@
+#include <hei_user_defines.hpp>
+#include <util/hei_bit_string.hpp>
+#include "gtest/gtest.h"
+
+using namespace libhei;
+
+static constexpr uint32_t UINT8_BIT_LEN = (sizeof(uint8_t) * 8);
+static constexpr uint32_t UINT64_BIT_LEN = (sizeof(uint64_t) * 8);
+
+// setBit()
+// clearBit()
+// setAll()
+// clearAll()
+// isBitSet()
+// getSetCount()
+// isZero()
+TEST( BitStringTest, TestSet1 )
+{
+ BitStringBuffer bs(UINT64_BIT_LEN);
+ uint32_t i;
+
+ // set all bits in ascending order
+ for(i = 0; i < UINT64_BIT_LEN; i++)
+ {
+ // Make sure bit gets set and set count
+ // is increasing
+ bs.setBit(i);
+ ASSERT_TRUE(bs.isBitSet(i));
+ ASSERT_EQ(bs.getSetCount(), i+1);
+ }
+ // all bits should be set at this point
+ ASSERT_EQ(bs.getFieldRight(0,64), UINT64_MAX);
+ ASSERT_EQ(bs.getFieldLeft(0,64), UINT64_MAX);
+
+ // test clearAll(), setAll()
+ bs.clearAll();
+ ASSERT_TRUE(bs.isZero());
+ bs.setAll();
+ ASSERT_EQ(bs.getSetCount(), UINT64_BIT_LEN);
+
+ // clear all bits in descending order
+ for(i = UINT64_BIT_LEN; 0 != i; i--)
+ {
+ // make sure bit gets cleared and set count
+ // is decreasing
+ ASSERT_EQ(bs.getSetCount(), i);
+ bs.clearBit(i-1);
+ ASSERT_FALSE(bs.isBitSet(i-1));
+ }
+ // all bits should be clear at this point
+ ASSERT_EQ(bs.getSetCount(), 0u);
+ ASSERT_EQ(bs.getFieldRight(0,64), 0u);
+ ASSERT_EQ(bs.getFieldLeft(0,64), 0u);
+ ASSERT_TRUE(bs.isZero());
+}
+
+// setPattern()
+TEST( BitStringTest, TestSet2 )
+{
+ BitStringBuffer bs(UINT64_BIT_LEN);
+ uint64_t field = 0xaaaaaaaaaaaaaaaa;
+
+ bs.setPattern(field);
+ ASSERT_EQ(field, bs.getFieldRight(0, 64));
+ ASSERT_EQ(field, bs.getFieldLeft(0, 64));
+
+ bs.clearAll();
+ ASSERT_TRUE(bs.isZero());
+
+ bs.setPattern(0xaa, 8);
+ ASSERT_EQ(field, bs.getFieldRight(0, 64));
+ ASSERT_EQ(field, bs.getFieldLeft(0, 64));
+
+ bs.clearAll();
+ ASSERT_TRUE(bs.isZero());
+
+ bs.setPattern(0, 64, 0xaaaa, 16);
+ ASSERT_EQ(field, bs.getFieldRight(0, 64));
+ ASSERT_EQ(field, bs.getFieldLeft(0, 64));
+}
+
+// setString()
+TEST( BitStringTest, TestSet3 )
+{
+ BitStringBuffer bsb_dest(64);
+ BitStringBuffer bsb_src(64);
+
+ bsb_dest.clearAll();
+ ASSERT_TRUE(bsb_dest.isZero());
+
+ bsb_src.setAll();
+ ASSERT_EQ(64u, bsb_src.getSetCount());
+
+ bsb_dest.setString(bsb_src);
+ ASSERT_FALSE(bsb_dest.isZero());
+ ASSERT_EQ(bsb_dest.getFieldRight(0, 64), bsb_src.getFieldRight(0,64));
+ ASSERT_EQ(bsb_dest.getFieldLeft(0, 64), bsb_src.getFieldLeft(0,64));
+}
+
+// maskString()
+TEST( BitStringTest, TestSet4 )
+{
+ BitStringBuffer bsb(64);
+ bsb.setAll();
+ ASSERT_EQ(64u, bsb.getSetCount());
+
+ BitStringBuffer bsb_mask(64);
+ bsb_mask.setFieldRight(0, 64, 0xaaaaaaaaaaaaaaaa);
+
+ bsb.maskString(bsb_mask);
+ ASSERT_EQ(bsb.getFieldRight(0, 64), 0x5555555555555555u);
+}
+
+// setFieldRight()
+// setFieldLeft()
+// getFielRight()
+// getFieldLeft()
+TEST( BitStringTest, TestSet5 )
+{
+ uint64_t field = 0x1234567890abcdef;
+ BitStringBuffer bsb(64);
+
+ // set bitstring to low end of field
+ bsb.setFieldRight(0, 32, field);
+ ASSERT_EQ(field << 32, bsb.getFieldLeft(0,32));
+
+ // set bitstring to high end of field
+ bsb.setFieldLeft(0, 32, field);
+ ASSERT_EQ(field >> 32, bsb.getFieldRight(0,32));
+
+ // increasing offset
+ for(uint32_t i = 0; i < UINT64_BIT_LEN; i++)
+ {
+ // increasing length
+ for(uint32_t j = 1; j <= UINT64_BIT_LEN - i; j++)
+ {
+ bsb.clearAll();
+ bsb.setFieldRight(i, j, UINT64_MAX);
+
+ // verify
+ ASSERT_EQ(bsb.getFieldRight(i, j), \
+ UINT64_MAX >> (UINT64_BIT_LEN - j));
+
+ }
+ }
+ for(uint32_t i = 0; i < UINT64_BIT_LEN; i++)
+ {
+ // set 1 bit at offset i
+ bsb.clearAll();
+ bsb.setFieldRight(i, 1, 1);
+
+ // verify bit is set
+ ASSERT_EQ(bsb.getFieldRight(0, 64), (uint64_t)1 << \
+ (UINT64_BIT_LEN - i - 1));
+ }
+}
+
+// operator >>
+// operator <<
+TEST( BitStringTest, TestSet6 )
+{
+ uint64_t field = 0x1234567890abcdef;
+ BitStringBuffer bsb(64);
+
+ bsb.setFieldRight(0, 64, field);
+ ASSERT_EQ(field, bsb.getFieldRight(0, 64));
+ ASSERT_EQ(field >> 32, (bsb >> 32).getFieldRight(0, 64));
+ ASSERT_EQ(field << 32, (bsb << 32).getFieldRight(0, 64));
+}
diff --git a/test/meson.build b/test/meson.build
index 6cc59ae..a4e13ea 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -1,3 +1,18 @@
# build simulator
subdir('simulator')
+# supporting files that need compiled/linked
+test_src = ['../src/util/hei_bit_string.cpp']
+
+# build g-test framework unit tests
+gtests = ['bit_string_test']
+
+gtest = dependency('gtest', main : true, required : false, method : 'system')
+
+if gtest.found()
+ foreach g : gtests
+ test(g, executable(g.underscorify(), g + '.cpp', test_src, \
+ dependencies : gtest, \
+ include_directories : incdir))
+ endforeach
+endif