mirror of https://github.com/KLayout/klayout.git
WIP: tl::BitSet plus tests
This commit is contained in:
parent
a8bedf7116
commit
100d861336
|
|
@ -11,6 +11,9 @@ FORMS =
|
|||
SOURCES = \
|
||||
tlAssert.cc \
|
||||
tlBase64.cc \
|
||||
tlBitSet.cc \
|
||||
tlBitSetMap.cc \
|
||||
tlBitSetMatch.cc \
|
||||
tlColor.cc \
|
||||
tlClassRegistry.cc \
|
||||
tlCopyOnWrite.cc \
|
||||
|
|
@ -62,6 +65,9 @@ HEADERS = \
|
|||
tlAlgorithm.h \
|
||||
tlAssert.h \
|
||||
tlBase64.h \
|
||||
tlBitSet.h \
|
||||
tlBitSetMap.h \
|
||||
tlBitSetMatch.h \
|
||||
tlColor.h \
|
||||
tlClassRegistry.h \
|
||||
tlCopyOnWrite.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,199 @@
|
|||
|
||||
/*
|
||||
|
||||
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 "tlBitSet.h"
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
static inline unsigned int nwords (BitSet::size_type size)
|
||||
{
|
||||
return (size + (sizeof (BitSet::data_type) * 8 - 1)) / (sizeof (BitSet::data_type) * 8);
|
||||
}
|
||||
|
||||
static inline unsigned int word (BitSet::size_type index)
|
||||
{
|
||||
return index / (sizeof (BitSet::data_type) * 8);
|
||||
}
|
||||
|
||||
static inline unsigned int bit (BitSet::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 (BitSet::data_type) * 8));
|
||||
}
|
||||
|
||||
BitSet &
|
||||
BitSet::operator= (const BitSet &other)
|
||||
{
|
||||
if (&other != this) {
|
||||
|
||||
clear ();
|
||||
|
||||
// reallocate
|
||||
m_size = other.m_size;
|
||||
unsigned int words = nwords (m_size);
|
||||
mp_data = new data_type[words];
|
||||
data_type *t = mp_data;
|
||||
data_type *s = other.mp_data;
|
||||
for (unsigned int i = 0; i < words; ++i) {
|
||||
*t++ = *s++;
|
||||
}
|
||||
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitSet &
|
||||
BitSet::operator= (BitSet &&other)
|
||||
{
|
||||
if (&other != this) {
|
||||
swap (other);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
BitSet::clear ()
|
||||
{
|
||||
if (mp_data) {
|
||||
delete [] mp_data;
|
||||
}
|
||||
mp_data = 0;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
void
|
||||
BitSet::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_data = new data_type[new_words];
|
||||
data_type *t = new_data;
|
||||
data_type *s = mp_data;
|
||||
unsigned int i;
|
||||
for (i = 0; i < words; ++i) {
|
||||
*t++ = *s++;
|
||||
}
|
||||
for (; i < new_words; ++i) {
|
||||
*t++ = 0;
|
||||
}
|
||||
delete mp_data;
|
||||
mp_data = new_data;
|
||||
m_size = size;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
BitSet::operator== (const BitSet &other) const
|
||||
{
|
||||
unsigned int words = nwords (m_size);
|
||||
unsigned int other_words = nwords (other.m_size);
|
||||
|
||||
const data_type *p = mp_data;
|
||||
const data_type *op = other.mp_data;
|
||||
unsigned int i;
|
||||
for (i = 0; i < words && i < other_words; ++i) {
|
||||
if (*p++ != *op++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (; i < words; ++i) {
|
||||
if (*p++ != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (; i < other_words; ++i) {
|
||||
if (0 != *op++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BitSet::operator< (const BitSet &other) const
|
||||
{
|
||||
unsigned int words = nwords (m_size);
|
||||
unsigned int other_words = nwords (other.m_size);
|
||||
|
||||
const data_type *p = mp_data;
|
||||
const data_type *op = other.mp_data;
|
||||
unsigned int i;
|
||||
for (i = 0; i < words && i < other_words; ++i, ++p, ++op) {
|
||||
if (*p != *op) {
|
||||
return *p < *op;
|
||||
}
|
||||
}
|
||||
for (; i < other_words; ++i, ++op) {
|
||||
if (0 != *op) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
BitSet::set (index_type index)
|
||||
{
|
||||
unsigned int wi = word (index);
|
||||
if (wi >= nwords (m_size)) {
|
||||
resize (index + 1);
|
||||
} else if (index >= m_size) {
|
||||
m_size = index + 1;
|
||||
}
|
||||
mp_data [wi] |= (1 << bit (index));
|
||||
}
|
||||
|
||||
void
|
||||
BitSet::reset (index_type index)
|
||||
{
|
||||
if (index < m_size) {
|
||||
unsigned int wi = word (index);
|
||||
mp_data [wi] &= ~(1 << bit (index));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
BitSet::operator[] (index_type index) const
|
||||
{
|
||||
if (index < m_size) {
|
||||
unsigned int wi = word (index);
|
||||
return (mp_data [wi] & (1 << bit (index))) != 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
|
||||
/*
|
||||
|
||||
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_tlBitSet
|
||||
#define HDR_tlBitSet
|
||||
|
||||
#include "tlCommon.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A bit set
|
||||
*
|
||||
* This object can store a set of n bits, each being true or false.
|
||||
* Essentially is it like a vector<bool>, but optimized to cooperate
|
||||
* with tl::BitSetMap and tl::BitSetMatch.
|
||||
*
|
||||
* Allocation is dynamic when a bit is accessed for write. Bits beyond the
|
||||
* size are treated as false.
|
||||
*/
|
||||
class TL_PUBLIC BitSet
|
||||
{
|
||||
public:
|
||||
typedef unsigned int index_type;
|
||||
typedef unsigned int size_type;
|
||||
typedef uint32_t data_type;
|
||||
|
||||
/**
|
||||
* @brief Default constructor: creates an empty bit set
|
||||
*/
|
||||
BitSet ()
|
||||
: mp_data (0), m_size (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates and initializes a bit set from a range of indexes
|
||||
* Every bit given by an index from the range is set.
|
||||
*/
|
||||
template <class Iter>
|
||||
BitSet (Iter from, Iter to)
|
||||
: mp_data (0), m_size (0)
|
||||
{
|
||||
set (from, to);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
BitSet (const BitSet &other)
|
||||
: mp_data (0), m_size (0)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move constructor
|
||||
*/
|
||||
BitSet (BitSet &&other)
|
||||
: mp_data (0), m_size (0)
|
||||
{
|
||||
operator= (std::move (other));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~BitSet ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
BitSet &operator= (const BitSet &other);
|
||||
|
||||
/**
|
||||
* @brief Move assignment
|
||||
*/
|
||||
BitSet &operator= (BitSet &&other);
|
||||
|
||||
/**
|
||||
* @brief Swaps the contents of this bit set with the other
|
||||
*/
|
||||
void swap (BitSet &other)
|
||||
{
|
||||
std::swap (mp_data, other.mp_data);
|
||||
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 BitSet &other) const;
|
||||
|
||||
/**
|
||||
* @brief Inequality
|
||||
*/
|
||||
bool operator!= (const BitSet &other) const
|
||||
{
|
||||
return !operator== (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Less operator
|
||||
*
|
||||
* The bits are compared in lexical order, first bit first.
|
||||
*/
|
||||
bool operator< (const BitSet &other) const;
|
||||
|
||||
/**
|
||||
* @brief Sets the given bit
|
||||
*/
|
||||
void set (index_type index);
|
||||
|
||||
/**
|
||||
* @brief Sets a range of bits
|
||||
* The indexes are taken from the sequence delivered by the iterator.
|
||||
*/
|
||||
template <class Iter>
|
||||
void set (Iter from, Iter to)
|
||||
{
|
||||
for (Iter i = from; i != to; ++i) {
|
||||
set (*i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets the given bit
|
||||
*/
|
||||
void reset (index_type index);
|
||||
|
||||
/**
|
||||
* @brief Resets a range of bits
|
||||
* The indexes are taken from the sequence delivered by the iterator.
|
||||
*/
|
||||
template <class Iter>
|
||||
void reset (Iter from, Iter to)
|
||||
{
|
||||
for (Iter i = from; i != to; ++i) {
|
||||
reset (*i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the values for a given bit
|
||||
*/
|
||||
void set_value (index_type index, bool f)
|
||||
{
|
||||
if (f) {
|
||||
set (index);
|
||||
} else {
|
||||
reset (index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the values for a range of bits
|
||||
* The indexes are taken from the sequence delivered by the iterator.
|
||||
*/
|
||||
template <class Iter>
|
||||
void set_value (Iter from, Iter to, bool f)
|
||||
{
|
||||
for (Iter i = from; i != to; ++i) {
|
||||
set_value (*i, f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a bit from the given index
|
||||
*/
|
||||
bool 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 bits are zero.
|
||||
*/
|
||||
bool is_empty () const
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the number of bits stored
|
||||
*
|
||||
* The number of bits is the highest bit written so far.
|
||||
*/
|
||||
size_type size () const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
private:
|
||||
data_type *mp_data;
|
||||
size_type m_size;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
|
||||
/*
|
||||
|
||||
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 "tlBitSet.h"
|
||||
#include "tlUnitTest.h"
|
||||
#include "tlString.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
TEST(1_Basic)
|
||||
{
|
||||
tl::BitSet bs;
|
||||
EXPECT_EQ (bs.is_empty (), true);
|
||||
EXPECT_EQ (bs.size (), 0u);
|
||||
EXPECT_EQ (l2s (bs), "");
|
||||
|
||||
bs.set (1);
|
||||
EXPECT_EQ (bs.size (), 2u);
|
||||
EXPECT_EQ (l2s (bs), "01");
|
||||
|
||||
bs.set (32);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "010000000000000000000000000000001");
|
||||
|
||||
bs.set (3);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (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");
|
||||
|
||||
bs.reset (128);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "010101110000000000000000000000001");
|
||||
|
||||
bs.reset (1);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "000101110000000000000000000000001");
|
||||
|
||||
bs.reset (indexes + 0, indexes + sizeof (indexes) / sizeof (indexes [0]));
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "000100000000000000000000000000001");
|
||||
|
||||
bs.set_value (0, true);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "100100000000000000000000000000001");
|
||||
|
||||
bs.set_value (indexes + 0, indexes + sizeof (indexes) / sizeof (indexes [0]), true);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "100101110000000000000000000000001");
|
||||
|
||||
bs.set_value (indexes + 0, indexes + sizeof (indexes) / sizeof (indexes [0]), false);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "100100000000000000000000000000001");
|
||||
|
||||
bs.set_value (0, false);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "000100000000000000000000000000001");
|
||||
|
||||
bs.clear ();
|
||||
EXPECT_EQ (bs.size (), 0u);
|
||||
EXPECT_EQ (l2s (bs), "");
|
||||
|
||||
bs.resize (6);
|
||||
EXPECT_EQ (bs.size (), 6u);
|
||||
EXPECT_EQ (l2s (bs), "000000");
|
||||
}
|
||||
|
||||
TEST(2_Equality)
|
||||
{
|
||||
tl::BitSet bs1, bs2, bs3;
|
||||
|
||||
EXPECT_EQ (bs1 == bs2, true);
|
||||
EXPECT_EQ (bs1 != bs2, false);
|
||||
|
||||
bs1.set (0);
|
||||
EXPECT_EQ (bs1 == bs2, false);
|
||||
EXPECT_EQ (bs1 != bs2, true);
|
||||
|
||||
bs1.set (32);
|
||||
EXPECT_EQ (bs1 == bs2, false);
|
||||
EXPECT_EQ (bs1 != bs2, true);
|
||||
|
||||
bs2.set (0);
|
||||
bs2.set (32);
|
||||
EXPECT_EQ (bs1 == bs2, true);
|
||||
EXPECT_EQ (bs1 == bs3, false);
|
||||
EXPECT_EQ (bs1 != bs2, false);
|
||||
EXPECT_EQ (bs1 != bs3, true);
|
||||
|
||||
bs1.reset (0);
|
||||
bs1.reset (32);
|
||||
EXPECT_EQ (bs1 == bs2, false);
|
||||
EXPECT_EQ (bs1 == bs3, true);
|
||||
EXPECT_EQ (bs1 != bs2, true);
|
||||
EXPECT_EQ (bs1 != bs3, false);
|
||||
}
|
||||
|
||||
TEST(3_Compare)
|
||||
{
|
||||
tl::BitSet bs1, bs2, bs3;
|
||||
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
|
||||
bs1.set (0);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs1.set (32);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs2 < bs1, true);
|
||||
|
||||
bs2.set (0);
|
||||
bs2.set (32);
|
||||
EXPECT_EQ (bs1 < bs2, false);
|
||||
EXPECT_EQ (bs1 < bs3, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
EXPECT_EQ (bs3 < bs1, true);
|
||||
|
||||
bs1.reset (0);
|
||||
bs1.reset (32);
|
||||
EXPECT_EQ (bs1 < bs2, true);
|
||||
EXPECT_EQ (bs1 < bs3, false);
|
||||
EXPECT_EQ (bs2 < bs1, false);
|
||||
EXPECT_EQ (bs3 < bs1, false);
|
||||
}
|
||||
|
||||
TEST(4_Assign)
|
||||
{
|
||||
tl::BitSet bs;
|
||||
EXPECT_EQ (l2s (bs), "");
|
||||
EXPECT_EQ (l2s (tl::BitSet (bs)), "");
|
||||
|
||||
bs.set (3);
|
||||
bs.set (32);
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "000100000000000000000000000000001");
|
||||
EXPECT_EQ (tl::BitSet (bs).size (), 33u);
|
||||
EXPECT_EQ (l2s (tl::BitSet (bs)), "000100000000000000000000000000001");
|
||||
|
||||
tl::BitSet bs2;
|
||||
bs2.swap (bs);
|
||||
EXPECT_EQ (bs.size (), 0u);
|
||||
EXPECT_EQ (bs2.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "");
|
||||
EXPECT_EQ (l2s (bs2), "000100000000000000000000000000001");
|
||||
|
||||
bs = bs2;
|
||||
EXPECT_EQ (bs.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs), "000100000000000000000000000000001");
|
||||
|
||||
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), "000100000000000000000000000000001");
|
||||
|
||||
tl::BitSet bs3 (std::move (bs2));
|
||||
EXPECT_EQ (bs2.size (), 0u);
|
||||
EXPECT_EQ (l2s (bs2), "");
|
||||
EXPECT_EQ (bs3.size (), 33u);
|
||||
EXPECT_EQ (l2s (bs3), "000100000000000000000000000000001");
|
||||
|
||||
bs.clear ();
|
||||
|
||||
unsigned int indexes[] = { 5, 6, 7 };
|
||||
bs = std::move (tl::BitSet (indexes + 0, indexes + sizeof (indexes) / sizeof (indexes [0])));
|
||||
EXPECT_EQ (bs.size (), 8u);
|
||||
EXPECT_EQ (l2s (bs), "00000111");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ include($$PWD/../../lib_ut.pri)
|
|||
SOURCES = \
|
||||
tlAlgorithmTests.cc \
|
||||
tlBase64Tests.cc \
|
||||
tlBitSetTests.cc \
|
||||
tlClassRegistryTests.cc \
|
||||
tlCommandLineParserTests.cc \
|
||||
tlColorTests.cc \
|
||||
|
|
|
|||
Loading…
Reference in New Issue