mirror of https://github.com/KLayout/klayout.git
WIP: tl::BitSetMask
This commit is contained in:
parent
100d861336
commit
7219742b87
|
|
@ -13,7 +13,7 @@ SOURCES = \
|
|||
tlBase64.cc \
|
||||
tlBitSet.cc \
|
||||
tlBitSetMap.cc \
|
||||
tlBitSetMatch.cc \
|
||||
tlBitSetMask.cc \
|
||||
tlColor.cc \
|
||||
tlClassRegistry.cc \
|
||||
tlCopyOnWrite.cc \
|
||||
|
|
@ -67,7 +67,7 @@ HEADERS = \
|
|||
tlBase64.h \
|
||||
tlBitSet.h \
|
||||
tlBitSetMap.h \
|
||||
tlBitSetMatch.h \
|
||||
tlBitSetMask.h \
|
||||
tlColor.h \
|
||||
tlClassRegistry.h \
|
||||
tlCopyOnWrite.h \
|
||||
|
|
|
|||
|
|
@ -231,6 +231,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
friend class BitSetMask;
|
||||
|
||||
data_type *mp_data;
|
||||
size_type m_size;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,291 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2024 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "tlCommon.h"
|
||||
|
||||
#include "tlBitSetMask.h"
|
||||
#include "tlBitSet.h"
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
static inline unsigned int nwords (BitSetMask::size_type size)
|
||||
{
|
||||
return (size + (sizeof (BitSetMask::data_type) * 8 - 1)) / (sizeof (BitSetMask::data_type) * 8);
|
||||
}
|
||||
|
||||
static inline unsigned int word (BitSetMask::size_type index)
|
||||
{
|
||||
return index / (sizeof (BitSetMask::data_type) * 8);
|
||||
}
|
||||
|
||||
static inline unsigned int bit (BitSetMask::size_type index)
|
||||
{
|
||||
// first bit is the highest bit, so that comparing the uint's is good enough
|
||||
// for lexical order.
|
||||
return 31 - (index % (sizeof (BitSetMask::data_type) * 8));
|
||||
}
|
||||
|
||||
BitSetMask &
|
||||
BitSetMask::operator= (const BitSetMask &other)
|
||||
{
|
||||
if (&other != this) {
|
||||
|
||||
clear ();
|
||||
|
||||
// reallocate
|
||||
m_size = other.m_size;
|
||||
unsigned int words = nwords (m_size);
|
||||
mp_data0 = new data_type[words];
|
||||
mp_data1 = new data_type[words];
|
||||
data_type *t0 = mp_data0;
|
||||
data_type *s0 = other.mp_data0;
|
||||
data_type *t1 = mp_data1;
|
||||
data_type *s1 = other.mp_data1;
|
||||
for (unsigned int i = 0; i < words; ++i) {
|
||||
*t0++ = *s0++;
|
||||
*t1++ = *s1++;
|
||||
}
|
||||
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitSetMask &
|
||||
BitSetMask::operator= (BitSetMask &&other)
|
||||
{
|
||||
if (&other != this) {
|
||||
swap (other);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
BitSetMask::clear ()
|
||||
{
|
||||
if (mp_data0) {
|
||||
delete [] mp_data0;
|
||||
}
|
||||
mp_data0 = 0;
|
||||
if (mp_data1) {
|
||||
delete [] mp_data1;
|
||||
}
|
||||
mp_data1 = 0;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
void
|
||||
BitSetMask::resize (size_type size)
|
||||
{
|
||||
if (size > m_size) {
|
||||
|
||||
unsigned int words = nwords (m_size);
|
||||
unsigned int new_words = nwords (size);
|
||||
|
||||
if (new_words > words) {
|
||||
|
||||
// reallocate
|
||||
data_type *new_data0 = new data_type[new_words];
|
||||
data_type *new_data1 = new data_type[new_words];
|
||||
data_type *t0 = new_data0;
|
||||
data_type *s0 = mp_data0;
|
||||
data_type *t1 = new_data1;
|
||||
data_type *s1 = mp_data1;
|
||||
unsigned int i;
|
||||
for (i = 0; i < words; ++i) {
|
||||
*t0++ = *s0++;
|
||||
*t1++ = *s1++;
|
||||
}
|
||||
for (; i < new_words; ++i) {
|
||||
// corresponds to "Any"
|
||||
*t0++ = 0;
|
||||
*t1++ = 0;
|
||||
}
|
||||
delete mp_data0;
|
||||
mp_data0 = new_data0;
|
||||
delete mp_data1;
|
||||
mp_data1 = new_data1;
|
||||
m_size = size;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
BitSetMask::operator== (const BitSetMask &other) const
|
||||
{
|
||||
unsigned int words = nwords (m_size);
|
||||
unsigned int other_words = nwords (other.m_size);
|
||||
|
||||
const data_type *p0 = mp_data0;
|
||||
const data_type *p1 = mp_data1;
|
||||
const data_type *op0 = other.mp_data0;
|
||||
const data_type *op1 = other.mp_data1;
|
||||
unsigned int i;
|
||||
for (i = 0; i < words && i < other_words; ++i) {
|
||||
if (*p0++ != *op0++) {
|
||||
return false;
|
||||
}
|
||||
if (*p1++ != *op1++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (; i < words; ++i) {
|
||||
if (*p0++ != 0) {
|
||||
return false;
|
||||
}
|
||||
if (*p1++ != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (; i < other_words; ++i) {
|
||||
if (0 != *op0++) {
|
||||
return false;
|
||||
}
|
||||
if (0 != *op1++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the most significant bit of a bit set
|
||||
*
|
||||
* For example b:00101101 will give b:00100000.
|
||||
*/
|
||||
static inline BitSetMask::data_type msb_only (BitSetMask::data_type value)
|
||||
{
|
||||
const unsigned int smax = sizeof (BitSetMask::data_type) * 8;
|
||||
|
||||
BitSetMask::data_type m = value;
|
||||
for (unsigned int s = 1; s < smax; s *= 2) {
|
||||
m |= (m >> s);
|
||||
}
|
||||
return value & ~(m >> 1);
|
||||
}
|
||||
|
||||
bool
|
||||
BitSetMask::operator< (const BitSetMask &other) const
|
||||
{
|
||||
unsigned int words = nwords (m_size);
|
||||
unsigned int other_words = nwords (other.m_size);
|
||||
|
||||
const data_type *p0 = mp_data0;
|
||||
const data_type *p1 = mp_data1;
|
||||
const data_type *op0 = other.mp_data0;
|
||||
const data_type *op1 = other.mp_data1;
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < words && i < other_words; ++i, ++p0, ++p1, ++op0, ++op1) {
|
||||
data_type diff = (*p0 ^ *op0) | (*p1 ^ *op1);
|
||||
if (diff) {
|
||||
// compare the most significant position of the differences by value
|
||||
data_type mb = msb_only (diff);
|
||||
unsigned int m = ((*p0 & mb) != 0 ? 1 : 0) + ((*p1 & mb) != 0 ? 2 : 0);
|
||||
unsigned int om = ((*op0 & mb) != 0 ? 1 : 0) + ((*op1 & mb) != 0 ? 2 : 0);
|
||||
return m < om;
|
||||
}
|
||||
}
|
||||
|
||||
// the remaining part of other is simply checked for
|
||||
// not being zero
|
||||
for (; i < other_words; ++i, ++op0, ++op1) {
|
||||
if (0 != *op0 || 0 != *op1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
BitSetMask::set (index_type index, mask_type mask)
|
||||
{
|
||||
if (index >= m_size && mask == Any) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int wi = word (index);
|
||||
if (wi >= nwords (m_size)) {
|
||||
resize (index + 1);
|
||||
} else if (index >= m_size) {
|
||||
m_size = index + 1;
|
||||
}
|
||||
|
||||
unsigned int mi = (unsigned int) mask;
|
||||
data_type bm = (1 << bit (index));
|
||||
if (mi & 1) {
|
||||
mp_data0 [wi] |= bm;
|
||||
} else {
|
||||
mp_data0 [wi] &= ~bm;
|
||||
}
|
||||
if (mi & 2) {
|
||||
mp_data1 [wi] |= bm;
|
||||
} else {
|
||||
mp_data1 [wi] &= ~bm;
|
||||
}
|
||||
}
|
||||
|
||||
BitSetMask::mask_type
|
||||
BitSetMask::operator[] (index_type index) const
|
||||
{
|
||||
if (index < m_size) {
|
||||
unsigned int wi = word (index);
|
||||
data_type bm = (1 << bit (index));
|
||||
unsigned int mi = ((mp_data0 [wi] & bm) != 0 ? 1 : 0) | ((mp_data1 [wi] & bm) != 0 ? 2 : 0);
|
||||
return mask_type (mi);
|
||||
} else {
|
||||
return Any;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
BitSetMask::match (const tl::BitSet &bs) const
|
||||
{
|
||||
unsigned nw_bs = nwords (bs.m_size);
|
||||
unsigned nw = nwords (m_size);
|
||||
|
||||
const tl::BitSet::data_type *d0 = mp_data0, *d1 = mp_data1;
|
||||
const tl::BitSet::data_type *s = bs.mp_data;
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < nw_bs && i < nw; ++i, ++d0, ++d1, ++s) {
|
||||
tl::BitSet::data_type d = *s;
|
||||
// A "true" in place of "false expected" gives "no match"
|
||||
if ((*d0 & d) != 0) {
|
||||
return false;
|
||||
}
|
||||
// A "false" in place of "true expected" gives "no match"
|
||||
if ((*d1 & ~d) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// as "not set" corresponds to "Any", we can stop here and have a match.
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2024 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_tlBitSetMask
|
||||
#define HDR_tlBitSetMask
|
||||
|
||||
#include "tlCommon.h"
|
||||
#include "tlBitSet.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A bit set
|
||||
*
|
||||
* This object can store a mask for a bit set.
|
||||
* Each element of the mask corresponds to one bit. Each element can be "True"
|
||||
* (matching to true), "False" (matching to false), "Any" matching to true
|
||||
* or false and "Never" matches neither to true nor false.
|
||||
*
|
||||
* A bit set match can be matched against a bit set and will return true if
|
||||
* the bit set corresponds to the mask.
|
||||
*
|
||||
* Allocation is dynamic when a mask element is accessed for write. Bits beyond the
|
||||
* size are treated as "Any".
|
||||
*/
|
||||
class TL_PUBLIC BitSetMask
|
||||
{
|
||||
public:
|
||||
typedef enum { Any = 0, False = 1, True = 2, Never = 3 } mask_type;
|
||||
|
||||
typedef tl::BitSet::index_type index_type;
|
||||
typedef tl::BitSet::size_type size_type;
|
||||
typedef tl::BitSet::data_type data_type;
|
||||
|
||||
/**
|
||||
* @brief Default constructor: creates an empty bit set
|
||||
*/
|
||||
BitSetMask ()
|
||||
: mp_data0 (0), mp_data1 (0), m_size (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
BitSetMask (const BitSetMask &other)
|
||||
: mp_data0 (0), mp_data1 (0), m_size (0)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move constructor
|
||||
*/
|
||||
BitSetMask (BitSetMask &&other)
|
||||
: mp_data0 (0), mp_data1 (0), m_size (0)
|
||||
{
|
||||
operator= (std::move (other));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~BitSetMask ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
BitSetMask &operator= (const BitSetMask &other);
|
||||
|
||||
/**
|
||||
* @brief Move assignment
|
||||
*/
|
||||
BitSetMask &operator= (BitSetMask &&other);
|
||||
|
||||
/**
|
||||
* @brief Swaps the contents of this bit set with the other
|
||||
*/
|
||||
void swap (BitSetMask &other)
|
||||
{
|
||||
std::swap (mp_data0, other.mp_data0);
|
||||
std::swap (mp_data1, other.mp_data1);
|
||||
std::swap (m_size, other.m_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears this bit set
|
||||
*/
|
||||
void clear ();
|
||||
|
||||
/**
|
||||
* @brief Sizes the bit set to "size" bits
|
||||
*
|
||||
* New bits are set to false.
|
||||
*/
|
||||
void resize (size_type size);
|
||||
|
||||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
bool operator== (const BitSetMask &other) const;
|
||||
|
||||
/**
|
||||
* @brief Inequality
|
||||
*/
|
||||
bool operator!= (const BitSetMask &other) const
|
||||
{
|
||||
return !operator== (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Less operator
|
||||
*
|
||||
* The bits are compared in lexical order, first bit first.
|
||||
*/
|
||||
bool operator< (const BitSetMask &other) const;
|
||||
|
||||
/**
|
||||
* @brief Sets the mask for the given bit
|
||||
*/
|
||||
void set (index_type index, mask_type mask);
|
||||
|
||||
/**
|
||||
* @brief Gets a mask from the given bit
|
||||
*/
|
||||
mask_type operator[] (index_type index) const;
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the set is empty
|
||||
*
|
||||
* "empty" means, no bits have been written yet. "empty" does NOT mean
|
||||
* all masks are of some specific value.
|
||||
*/
|
||||
bool is_empty () const
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the number of bits for the mask stored
|
||||
*
|
||||
* The number of bits is the highest bit written so far.
|
||||
*/
|
||||
size_type size () const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Matches the given bit set against this mask
|
||||
*/
|
||||
bool match (const tl::BitSet &) const;
|
||||
|
||||
private:
|
||||
data_type *mp_data0, *mp_data1;
|
||||
size_type m_size;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2024 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "tlBitSetMask.h"
|
||||
#include "tlUnitTest.h"
|
||||
#include "tlString.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
TEST(1_Basic)
|
||||
{
|
||||
tl::BitSetMask bs;
|
||||
EXPECT_EQ (bs.is_empty (), true);
|
||||
EXPECT_EQ (bs.size (), 0u);
|
||||
EXPECT_EQ (l2s (bs), "");
|
||||
|
||||
bs.set (1, tl::BitSetMask::True);
|
||||
EXPECT_EQ (bs.size (), 2u);
|
||||
EXPECT_EQ (l2s (bs), "X1");
|
||||
|
||||
bs.set (32, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||
|
||||
bs.set (3, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||
|
||||
bs.set (128, tl::BitSetMask::Any);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "X1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||
|
||||
bs.clear ();
|
||||
EXPECT_EQ (bs.size (), 0u);
|
||||
EXPECT_EQ (l2s (bs), "");
|
||||
|
||||
bs.resize (6);
|
||||
EXPECT_EQ (bs.size (), 6u);
|
||||
EXPECT_EQ (l2s (bs), "XXXXXX");
|
||||
}
|
||||
|
||||
TEST(2_Equality)
|
||||
{
|
||||
tl::BitSetMask bs1, bs2, bs3;
|
||||
|
||||
EXPECT_EQ (bs1 == bs2, true);
|
||||
EXPECT_EQ (bs1 != bs2, false);
|
||||
|
||||
bs1.set (0, tl::BitSetMask::True);
|
||||
EXPECT_EQ (bs1 == bs2, false);
|
||||
EXPECT_EQ (bs1 != bs2, true);
|
||||
|
||||
bs1.set (32, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs1 == bs2, false);
|
||||
EXPECT_EQ (bs1 != bs2, true);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::True);
|
||||
bs2.set (32, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs1 == bs2, true);
|
||||
EXPECT_EQ (bs1 == bs3, false);
|
||||
EXPECT_EQ (bs1 != bs2, false);
|
||||
EXPECT_EQ (bs1 != bs3, true);
|
||||
|
||||
bs1.set (0, tl::BitSetMask::Any);
|
||||
bs1.set (32, tl::BitSetMask::Any);
|
||||
EXPECT_EQ (bs1 == bs2, false);
|
||||
EXPECT_EQ (bs1 == bs3, true);
|
||||
EXPECT_EQ (bs1 != bs2, true);
|
||||
EXPECT_EQ (bs1 != bs3, false);
|
||||
}
|
||||
|
||||
TEST(3_Compare)
|
||||
{
|
||||
tl::BitSetMask bs1, bs2, bs3;
|
||||
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs1.set (0, tl::BitSetMask::True);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs1.set (32, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs2.set (32, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs1 < bs3, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
EXPECT_EQ (bs3 < bs1, true);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::True);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs1 < bs3, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
EXPECT_EQ (bs3 < bs1, true);
|
||||
|
||||
bs1.set (0, tl::BitSetMask::Any);
|
||||
bs1.set (32, tl::BitSetMask::Any);
|
||||
EXPECT_EQ (bs1 < bs2, true);
|
||||
EXPECT_EQ (bs1 < bs3, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
EXPECT_EQ (bs3 < bs1, false);
|
||||
|
||||
bs1.clear ();
|
||||
bs2.clear ();
|
||||
bs1.set (0, tl::BitSetMask::Any);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::Any);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs1 < bs2, true);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::True);
|
||||
EXPECT_EQ (bs1 < bs2, true);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::Never);
|
||||
EXPECT_EQ (bs1 < bs2, true);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs1.set (0, tl::BitSetMask::False);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::Any);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::True);
|
||||
EXPECT_EQ (bs1 < bs2, true);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::Never);
|
||||
EXPECT_EQ (bs1 < bs2, true);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs1.set (0, tl::BitSetMask::True);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::Any);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::True);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::Never);
|
||||
EXPECT_EQ (bs1 < bs2, true);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs1.set (0, tl::BitSetMask::Never);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::Any);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::True);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs2.set (0, tl::BitSetMask::Never);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
}
|
||||
|
||||
TEST(4_Assign)
|
||||
{
|
||||
tl::BitSetMask bs;
|
||||
EXPECT_EQ (l2s (bs), "");
|
||||
EXPECT_EQ (l2s (tl::BitSetMask (bs)), "");
|
||||
|
||||
bs.set (3, tl::BitSetMask::True);
|
||||
bs.set (32, tl::BitSetMask::False);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "XXX1XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||
EXPECT_EQ (tl::BitSetMask (bs).size (), 33u);
|
||||
EXPECT_EQ (l2s (tl::BitSetMask (bs)), "XXX1XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||
|
||||
tl::BitSetMask bs2;
|
||||
bs2.swap (bs);
|
||||
EXPECT_EQ (bs.size (), 0u);
|
||||
EXPECT_EQ (bs2.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "");
|
||||
EXPECT_EQ (l2s (bs2), "XXX1XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||
|
||||
bs = bs2;
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "XXX1XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||
|
||||
bs2.clear ();
|
||||
EXPECT_EQ (bs2.size (), 0u);
|
||||
EXPECT_EQ (l2s (bs2), "");
|
||||
|
||||
bs2 = std::move (bs);
|
||||
EXPECT_EQ (bs.size (), 0u);
|
||||
EXPECT_EQ (l2s (bs), "");
|
||||
EXPECT_EQ (bs2.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs2), "XXX1XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||
|
||||
tl::BitSetMask bs3 (std::move (bs2));
|
||||
EXPECT_EQ (bs2.size (), 0u);
|
||||
EXPECT_EQ (l2s (bs2), "");
|
||||
EXPECT_EQ (bs3.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs3), "XXX1XXXXXXXXXXXXXXXXXXXXXXXXXXXX0");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ include($$PWD/../../lib_ut.pri)
|
|||
SOURCES = \
|
||||
tlAlgorithmTests.cc \
|
||||
tlBase64Tests.cc \
|
||||
tlBitSetMaskTests.cc \
|
||||
tlBitSetTests.cc \
|
||||
tlClassRegistryTests.cc \
|
||||
tlCommandLineParserTests.cc \
|
||||
|
|
|
|||
Loading…
Reference in New Issue