String representation of tl::BitSet and tl::BitSetMask

This commit is contained in:
Matthias Koefferlein 2024-08-29 21:30:21 +02:00
parent 8c596fddc3
commit 9d45a01abf
7 changed files with 161 additions and 90 deletions

View File

@ -45,6 +45,51 @@ static inline unsigned int bit (BitSet::size_type index)
return 31 - (index % (sizeof (BitSet::data_type) * 8));
}
BitSet::BitSet ()
: mp_data (0), m_size (0)
{
// .. nothing yet ..
}
BitSet::BitSet (const std::string &s)
: mp_data (0), m_size (0)
{
index_type bit = 0;
for (const char *cp = s.c_str (); *cp; ++cp, ++bit) {
set_value (bit, *cp == '1');
}
}
BitSet::BitSet (const BitSet &other)
: mp_data (0), m_size (0)
{
operator= (other);
}
BitSet::BitSet (BitSet &&other)
: mp_data (0), m_size (0)
{
operator= (std::move (other));
}
std::string
BitSet::to_string () const
{
std::string r;
r.reserve (m_size);
for (index_type i = 0; i < m_size; ++i) {
r += operator[] (i) ? '1' : '0';
}
return r;
}
BitSet::~BitSet ()
{
clear ();
}
BitSet &
BitSet::operator= (const BitSet &other)
{

View File

@ -28,6 +28,7 @@
#include <cstdint>
#include <algorithm>
#include <string>
namespace tl
{
@ -52,11 +53,7 @@ public:
/**
* @brief Default constructor: creates an empty bit set
*/
BitSet ()
: mp_data (0), m_size (0)
{
// .. nothing yet ..
}
BitSet ();
/**
* @brief Creates and initializes a bit set from a range of indexes
@ -69,31 +66,32 @@ public:
set (from, to);
}
/**
* @brief Creates a bit set from a string
*
* In the string, a '0' character is for False, '1' for True.
*/
BitSet (const std::string &s);
/**
* @brief Copy constructor
*/
BitSet (const BitSet &other)
: mp_data (0), m_size (0)
{
operator= (other);
}
BitSet (const BitSet &other);
/**
* @brief Move constructor
*/
BitSet (BitSet &&other)
: mp_data (0), m_size (0)
{
operator= (std::move (other));
}
BitSet (BitSet &&other);
/**
* @brief Converts the bit set to a string
*/
std::string to_string () const;
/**
* @brief Destructor
*/
~BitSet ()
{
clear ();
}
~BitSet ();
/**
* @brief Assignment

View File

@ -46,6 +46,73 @@ static inline unsigned int bit (BitSetMask::size_type index)
return 31 - (index % (sizeof (BitSetMask::data_type) * 8));
}
BitSetMask::BitSetMask ()
: mp_data0 (0), mp_data1 (0), m_size (0)
{
// .. nothing yet ..
}
BitSetMask::BitSetMask (const std::string &s)
: mp_data0 (0), mp_data1 (0), m_size (0)
{
index_type bit = 0;
for (const char *cp = s.c_str (); *cp; ++cp, ++bit) {
mask_type m = Any;
if (*cp == '0') {
m = False;
} else if (*cp == '1') {
m = True;
} else if (*cp == '-') {
m = Never;
}
set (bit, m);
}
}
BitSetMask::BitSetMask (const BitSetMask &other)
: mp_data0 (0), mp_data1 (0), m_size (0)
{
operator= (other);
}
BitSetMask::BitSetMask (BitSetMask &&other)
: mp_data0 (0), mp_data1 (0), m_size (0)
{
operator= (std::move (other));
}
BitSetMask::~BitSetMask ()
{
clear ();
}
std::string
BitSetMask::to_string () const
{
std::string r;
r.reserve (m_size);
for (index_type i = 0; i < m_size; ++i) {
switch (operator[] (i)) {
case False:
r += '0';
break;
case True:
r += '1';
break;
case Never:
r += '-';
break;
case Any:
default:
r += 'X';
break;
}
}
return r;
}
BitSetMask &
BitSetMask::operator= (const BitSetMask &other)
{

View File

@ -29,6 +29,7 @@
#include <cstdint>
#include <algorithm>
#include <string>
namespace tl
{
@ -59,37 +60,34 @@ public:
/**
* @brief Default constructor: creates an empty bit set
*/
BitSetMask ()
: mp_data0 (0), mp_data1 (0), m_size (0)
{
// .. nothing yet ..
}
BitSetMask ();
/**
* @brief Creates a bit set mask from a string
*
* In the string, a '0' character is for False, '1' for True, 'X' for Any and '-' for Never.
*/
BitSetMask (const std::string &s);
/**
* @brief Copy constructor
*/
BitSetMask (const BitSetMask &other)
: mp_data0 (0), mp_data1 (0), m_size (0)
{
operator= (other);
}
BitSetMask (const BitSetMask &other);
/**
* @brief Move constructor
*/
BitSetMask (BitSetMask &&other)
: mp_data0 (0), mp_data1 (0), m_size (0)
{
operator= (std::move (other));
}
BitSetMask (BitSetMask &&other);
/**
* @brief Destructor
*/
~BitSetMask ()
{
clear ();
}
~BitSetMask ();
/**
* @brief Converts the mask to a string
*/
std::string to_string () const;
/**
* @brief Assignment

View File

@ -29,31 +29,12 @@
static tl::BitSet bs (const char *s)
{
tl::BitSet res;
for (unsigned int i = 0; *s; ++i, ++s) {
res.set (i);
if (*s == '0') {
res.reset (i);
}
}
return res;
return tl::BitSet (s);
}
static tl::BitSetMask bsm (const char *s)
{
tl::BitSetMask res;
for (unsigned int i = 0; *s; ++i, ++s) {
if (*s == '0') {
res.set (i, tl::BitSetMask::False);
} else if (*s == '1') {
res.set (i, tl::BitSetMask::True);
} else if (*s == 'X') {
res.set (i, tl::BitSetMask::Any);
} else if (*s == '-') {
res.set (i, tl::BitSetMask::Never);
}
}
return res;
return tl::BitSetMask (s);
}
struct SetInserter

View File

@ -29,36 +29,12 @@ namespace
static std::string l2s (const tl::BitSetMask &s)
{
std::string x;
for (tl::BitSetMask::index_type i = 0; i < s.size (); ++i) {
switch (s[i]) {
case tl::BitSetMask::Any:
x += "X";
break;
case tl::BitSetMask::True:
x += "1";
break;
case tl::BitSetMask::False:
x += "0";
break;
default:
x += "-";
break;
}
}
return x;
return s.to_string ();
}
static tl::BitSet bs (const char *s)
{
tl::BitSet res;
for (unsigned int i = 0; *s; ++i, ++s) {
res.set (i);
if (*s == '0') {
res.reset (i);
}
}
return res;
return tl::BitSet (s);
}
TEST(1_Basic)
@ -67,22 +43,27 @@ TEST(1_Basic)
EXPECT_EQ (bs.is_empty (), true);
EXPECT_EQ (bs.size (), 0u);
EXPECT_EQ (l2s (bs), "");
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "");
bs.set (1, tl::BitSetMask::True);
EXPECT_EQ (bs.size (), 2u);
EXPECT_EQ (l2s (bs), "X1");
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "X1");
bs.set (32, tl::BitSetMask::False);
EXPECT_EQ (bs.size (), 33u);
EXPECT_EQ (l2s (bs), "X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
bs.set (3, tl::BitSetMask::False);
EXPECT_EQ (bs.size (), 33u);
EXPECT_EQ (l2s (bs), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
bs.set (128, tl::BitSetMask::Any);
EXPECT_EQ (bs.size (), 33u);
EXPECT_EQ (l2s (bs), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
bs.clear ();
EXPECT_EQ (bs.size (), 0u);

View File

@ -29,11 +29,7 @@ namespace
static std::string l2s (const tl::BitSet &s)
{
std::string x;
for (tl::BitSet::index_type i = 0; i < s.size (); ++i) {
x += s[i] ? "1" : "0";
}
return x;
return s.to_string ();
}
TEST(1_Basic)
@ -42,23 +38,28 @@ TEST(1_Basic)
EXPECT_EQ (bs.is_empty (), true);
EXPECT_EQ (bs.size (), 0u);
EXPECT_EQ (l2s (bs), "");
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "");
bs.set (1);
EXPECT_EQ (bs.size (), 2u);
EXPECT_EQ (l2s (bs), "01");
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "01");
bs.set (32);
EXPECT_EQ (bs.size (), 33u);
EXPECT_EQ (l2s (bs), "010000000000000000000000000000001");
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "010000000000000000000000000000001");
bs.set (3);
EXPECT_EQ (bs.size (), 33u);
EXPECT_EQ (l2s (bs), "010100000000000000000000000000001");
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "010100000000000000000000000000001");
unsigned int indexes[] = { 5, 6, 7 };
bs.set (indexes + 0, indexes + sizeof (indexes) / sizeof (indexes [0]));
EXPECT_EQ (bs.size (), 33u);
EXPECT_EQ (l2s (bs), "010101110000000000000000000000001");
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "010101110000000000000000000000001");
bs.reset (128);
EXPECT_EQ (bs.size (), 33u);