mirror of https://github.com/KLayout/klayout.git
String representation of tl::BitSet and tl::BitSetMask
This commit is contained in:
parent
8c596fddc3
commit
9d45a01abf
|
|
@ -45,6 +45,51 @@ static inline unsigned int bit (BitSet::size_type index)
|
||||||
return 31 - (index % (sizeof (BitSet::data_type) * 8));
|
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 &
|
||||||
BitSet::operator= (const BitSet &other)
|
BitSet::operator= (const BitSet &other)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace tl
|
namespace tl
|
||||||
{
|
{
|
||||||
|
|
@ -52,11 +53,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Default constructor: creates an empty bit set
|
* @brief Default constructor: creates an empty bit set
|
||||||
*/
|
*/
|
||||||
BitSet ()
|
BitSet ();
|
||||||
: mp_data (0), m_size (0)
|
|
||||||
{
|
|
||||||
// .. nothing yet ..
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates and initializes a bit set from a range of indexes
|
* @brief Creates and initializes a bit set from a range of indexes
|
||||||
|
|
@ -69,31 +66,32 @@ public:
|
||||||
set (from, to);
|
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
|
* @brief Copy constructor
|
||||||
*/
|
*/
|
||||||
BitSet (const BitSet &other)
|
BitSet (const BitSet &other);
|
||||||
: mp_data (0), m_size (0)
|
|
||||||
{
|
|
||||||
operator= (other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Move constructor
|
* @brief Move constructor
|
||||||
*/
|
*/
|
||||||
BitSet (BitSet &&other)
|
BitSet (BitSet &&other);
|
||||||
: mp_data (0), m_size (0)
|
|
||||||
{
|
/**
|
||||||
operator= (std::move (other));
|
* @brief Converts the bit set to a string
|
||||||
}
|
*/
|
||||||
|
std::string to_string () const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destructor
|
* @brief Destructor
|
||||||
*/
|
*/
|
||||||
~BitSet ()
|
~BitSet ();
|
||||||
{
|
|
||||||
clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Assignment
|
* @brief Assignment
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,73 @@ static inline unsigned int bit (BitSetMask::size_type index)
|
||||||
return 31 - (index % (sizeof (BitSetMask::data_type) * 8));
|
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 &
|
||||||
BitSetMask::operator= (const BitSetMask &other)
|
BitSetMask::operator= (const BitSetMask &other)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace tl
|
namespace tl
|
||||||
{
|
{
|
||||||
|
|
@ -59,37 +60,34 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Default constructor: creates an empty bit set
|
* @brief Default constructor: creates an empty bit set
|
||||||
*/
|
*/
|
||||||
BitSetMask ()
|
BitSetMask ();
|
||||||
: mp_data0 (0), mp_data1 (0), m_size (0)
|
|
||||||
{
|
/**
|
||||||
// .. nothing yet ..
|
* @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
|
* @brief Copy constructor
|
||||||
*/
|
*/
|
||||||
BitSetMask (const BitSetMask &other)
|
BitSetMask (const BitSetMask &other);
|
||||||
: mp_data0 (0), mp_data1 (0), m_size (0)
|
|
||||||
{
|
|
||||||
operator= (other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Move constructor
|
* @brief Move constructor
|
||||||
*/
|
*/
|
||||||
BitSetMask (BitSetMask &&other)
|
BitSetMask (BitSetMask &&other);
|
||||||
: mp_data0 (0), mp_data1 (0), m_size (0)
|
|
||||||
{
|
|
||||||
operator= (std::move (other));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destructor
|
* @brief Destructor
|
||||||
*/
|
*/
|
||||||
~BitSetMask ()
|
~BitSetMask ();
|
||||||
{
|
|
||||||
clear ();
|
/**
|
||||||
}
|
* @brief Converts the mask to a string
|
||||||
|
*/
|
||||||
|
std::string to_string () const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Assignment
|
* @brief Assignment
|
||||||
|
|
|
||||||
|
|
@ -29,31 +29,12 @@
|
||||||
|
|
||||||
static tl::BitSet bs (const char *s)
|
static tl::BitSet bs (const char *s)
|
||||||
{
|
{
|
||||||
tl::BitSet res;
|
return tl::BitSet (s);
|
||||||
for (unsigned int i = 0; *s; ++i, ++s) {
|
|
||||||
res.set (i);
|
|
||||||
if (*s == '0') {
|
|
||||||
res.reset (i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static tl::BitSetMask bsm (const char *s)
|
static tl::BitSetMask bsm (const char *s)
|
||||||
{
|
{
|
||||||
tl::BitSetMask res;
|
return tl::BitSetMask (s);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SetInserter
|
struct SetInserter
|
||||||
|
|
|
||||||
|
|
@ -29,36 +29,12 @@ namespace
|
||||||
|
|
||||||
static std::string l2s (const tl::BitSetMask &s)
|
static std::string l2s (const tl::BitSetMask &s)
|
||||||
{
|
{
|
||||||
std::string x;
|
return s.to_string ();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static tl::BitSet bs (const char *s)
|
static tl::BitSet bs (const char *s)
|
||||||
{
|
{
|
||||||
tl::BitSet res;
|
return tl::BitSet (s);
|
||||||
for (unsigned int i = 0; *s; ++i, ++s) {
|
|
||||||
res.set (i);
|
|
||||||
if (*s == '0') {
|
|
||||||
res.reset (i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(1_Basic)
|
TEST(1_Basic)
|
||||||
|
|
@ -67,22 +43,27 @@ TEST(1_Basic)
|
||||||
EXPECT_EQ (bs.is_empty (), true);
|
EXPECT_EQ (bs.is_empty (), true);
|
||||||
EXPECT_EQ (bs.size (), 0u);
|
EXPECT_EQ (bs.size (), 0u);
|
||||||
EXPECT_EQ (l2s (bs), "");
|
EXPECT_EQ (l2s (bs), "");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "");
|
||||||
|
|
||||||
bs.set (1, tl::BitSetMask::True);
|
bs.set (1, tl::BitSetMask::True);
|
||||||
EXPECT_EQ (bs.size (), 2u);
|
EXPECT_EQ (bs.size (), 2u);
|
||||||
EXPECT_EQ (l2s (bs), "X1");
|
EXPECT_EQ (l2s (bs), "X1");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "X1");
|
||||||
|
|
||||||
bs.set (32, tl::BitSetMask::False);
|
bs.set (32, tl::BitSetMask::False);
|
||||||
EXPECT_EQ (bs.size (), 33u);
|
EXPECT_EQ (bs.size (), 33u);
|
||||||
EXPECT_EQ (l2s (bs), "X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
EXPECT_EQ (l2s (bs), "X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||||
|
|
||||||
bs.set (3, tl::BitSetMask::False);
|
bs.set (3, tl::BitSetMask::False);
|
||||||
EXPECT_EQ (bs.size (), 33u);
|
EXPECT_EQ (bs.size (), 33u);
|
||||||
EXPECT_EQ (l2s (bs), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
EXPECT_EQ (l2s (bs), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||||
|
|
||||||
bs.set (128, tl::BitSetMask::Any);
|
bs.set (128, tl::BitSetMask::Any);
|
||||||
EXPECT_EQ (bs.size (), 33u);
|
EXPECT_EQ (bs.size (), 33u);
|
||||||
EXPECT_EQ (l2s (bs), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
EXPECT_EQ (l2s (bs), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSetMask (l2s (bs))), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||||
|
|
||||||
bs.clear ();
|
bs.clear ();
|
||||||
EXPECT_EQ (bs.size (), 0u);
|
EXPECT_EQ (bs.size (), 0u);
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,7 @@ namespace
|
||||||
|
|
||||||
static std::string l2s (const tl::BitSet &s)
|
static std::string l2s (const tl::BitSet &s)
|
||||||
{
|
{
|
||||||
std::string x;
|
return s.to_string ();
|
||||||
for (tl::BitSet::index_type i = 0; i < s.size (); ++i) {
|
|
||||||
x += s[i] ? "1" : "0";
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(1_Basic)
|
TEST(1_Basic)
|
||||||
|
|
@ -42,23 +38,28 @@ TEST(1_Basic)
|
||||||
EXPECT_EQ (bs.is_empty (), true);
|
EXPECT_EQ (bs.is_empty (), true);
|
||||||
EXPECT_EQ (bs.size (), 0u);
|
EXPECT_EQ (bs.size (), 0u);
|
||||||
EXPECT_EQ (l2s (bs), "");
|
EXPECT_EQ (l2s (bs), "");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "");
|
||||||
|
|
||||||
bs.set (1);
|
bs.set (1);
|
||||||
EXPECT_EQ (bs.size (), 2u);
|
EXPECT_EQ (bs.size (), 2u);
|
||||||
EXPECT_EQ (l2s (bs), "01");
|
EXPECT_EQ (l2s (bs), "01");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "01");
|
||||||
|
|
||||||
bs.set (32);
|
bs.set (32);
|
||||||
EXPECT_EQ (bs.size (), 33u);
|
EXPECT_EQ (bs.size (), 33u);
|
||||||
EXPECT_EQ (l2s (bs), "010000000000000000000000000000001");
|
EXPECT_EQ (l2s (bs), "010000000000000000000000000000001");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "010000000000000000000000000000001");
|
||||||
|
|
||||||
bs.set (3);
|
bs.set (3);
|
||||||
EXPECT_EQ (bs.size (), 33u);
|
EXPECT_EQ (bs.size (), 33u);
|
||||||
EXPECT_EQ (l2s (bs), "010100000000000000000000000000001");
|
EXPECT_EQ (l2s (bs), "010100000000000000000000000000001");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "010100000000000000000000000000001");
|
||||||
|
|
||||||
unsigned int indexes[] = { 5, 6, 7 };
|
unsigned int indexes[] = { 5, 6, 7 };
|
||||||
bs.set (indexes + 0, indexes + sizeof (indexes) / sizeof (indexes [0]));
|
bs.set (indexes + 0, indexes + sizeof (indexes) / sizeof (indexes [0]));
|
||||||
EXPECT_EQ (bs.size (), 33u);
|
EXPECT_EQ (bs.size (), 33u);
|
||||||
EXPECT_EQ (l2s (bs), "010101110000000000000000000000001");
|
EXPECT_EQ (l2s (bs), "010101110000000000000000000000001");
|
||||||
|
EXPECT_EQ (l2s (tl::BitSet (l2s (bs))), "010101110000000000000000000000001");
|
||||||
|
|
||||||
bs.reset (128);
|
bs.reset (128);
|
||||||
EXPECT_EQ (bs.size (), 33u);
|
EXPECT_EQ (bs.size (), 33u);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue