Skip to content

Commit 343373b

Browse files
committed
Make disjoint set datastructure templatized over value type
with explicit instantiation
1 parent 6156813 commit 343373b

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

libsolutil/DisjointSet.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424

2525
using namespace solidity::util;
2626

27-
ContiguousDisjointSet::ContiguousDisjointSet(size_t const _numNodes):
27+
template<typename ValueType>
28+
ContiguousDisjointSet<ValueType>::ContiguousDisjointSet(size_t const _numNodes):
2829
m_parents(_numNodes),
2930
m_neighbors(_numNodes),
3031
m_sizes(_numNodes, static_cast<value_type>(1)),
@@ -35,9 +36,11 @@ ContiguousDisjointSet::ContiguousDisjointSet(size_t const _numNodes):
3536
std::iota(m_neighbors.begin(), m_neighbors.end(), 0);
3637
}
3738

38-
size_t ContiguousDisjointSet::numSets() const { return m_numSets; }
39+
template<typename ValueType>
40+
size_t ContiguousDisjointSet<ValueType>::numSets() const { return m_numSets; }
3941

40-
ContiguousDisjointSet::value_type ContiguousDisjointSet::find(value_type const _element) const
42+
template<typename ValueType>
43+
typename ContiguousDisjointSet<ValueType>::value_type ContiguousDisjointSet<ValueType>::find(value_type const _element) const
4144
{
4245
solAssert(_element < m_parents.size());
4346
// path halving
@@ -50,7 +53,8 @@ ContiguousDisjointSet::value_type ContiguousDisjointSet::find(value_type const _
5053
return rootElement;
5154
}
5255

53-
void ContiguousDisjointSet::merge(value_type const _x, value_type const _y, bool const _mergeBySize)
56+
template<typename ValueType>
57+
void ContiguousDisjointSet<ValueType>::merge(value_type const _x, value_type const _y, bool const _mergeBySize)
5458
{
5559
auto xRoot = find(_x);
5660
auto yRoot = find(_y);
@@ -69,17 +73,20 @@ void ContiguousDisjointSet::merge(value_type const _x, value_type const _y, bool
6973
--m_numSets;
7074
}
7175

72-
bool ContiguousDisjointSet::sameSubset(value_type const _x, value_type const _y) const
76+
template<typename ValueType>
77+
bool ContiguousDisjointSet<ValueType>::sameSubset(value_type const _x, value_type const _y) const
7378
{
7479
return find(_x) == find(_y);
7580
}
7681

77-
ContiguousDisjointSet::size_type ContiguousDisjointSet::sizeOfSubset(value_type const _x) const
82+
template<typename ValueType>
83+
typename ContiguousDisjointSet<ValueType>::size_type ContiguousDisjointSet<ValueType>::sizeOfSubset(value_type const _x) const
7884
{
7985
return m_sizes[find(_x)];
8086
}
8187

82-
std::set<ContiguousDisjointSet::value_type> ContiguousDisjointSet::subset(value_type const _x) const
88+
template<typename ValueType>
89+
std::set<typename ContiguousDisjointSet<ValueType>::value_type> ContiguousDisjointSet<ValueType>::subset(value_type const _x) const
8390
{
8491
solAssert(_x < m_parents.size());
8592
std::set<value_type> result{_x};
@@ -92,7 +99,8 @@ std::set<ContiguousDisjointSet::value_type> ContiguousDisjointSet::subset(value_
9299
return result;
93100
}
94101

95-
std::vector<std::set<ContiguousDisjointSet::value_type>> ContiguousDisjointSet::subsets() const
102+
template<typename ValueType>
103+
std::vector<std::set<typename ContiguousDisjointSet<ValueType>::value_type>> ContiguousDisjointSet<ValueType>::subsets() const
96104
{
97105
std::vector<std::set<value_type>> result;
98106
std::vector<std::uint8_t> visited(m_parents.size(), false);
@@ -107,3 +115,5 @@ std::vector<std::set<ContiguousDisjointSet::value_type>> ContiguousDisjointSet::
107115
}
108116
return result;
109117
}
118+
119+
template class solidity::util::ContiguousDisjointSet<std::uint32_t>;

libsolutil/DisjointSet.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ namespace solidity::util
3131
/// [1] https://en.wikipedia.org/wiki/Disjoint-set_data_structure
3232
/// [2] Tarjan, Robert E., and Jan Van Leeuwen. "Worst-case analysis of set union algorithms."
3333
/// Journal of the ACM (JACM) 31.2 (1984): 245-281.
34+
template<typename ValueType>
3435
class ContiguousDisjointSet
3536
{
3637
public:
3738
using size_type = size_t;
38-
using value_type = size_t;
39+
using value_type = ValueType;
3940

4041
/// Constructs a new disjoint set datastructure with `_numNodes` elements and each element in its own individual set
4142
explicit ContiguousDisjointSet(size_t _numNodes);

test/libsolutil/DisjointSet.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ BOOST_AUTO_TEST_SUITE(DisjointSetTest)
2929

3030
BOOST_AUTO_TEST_CASE(full_union)
3131
{
32-
ContiguousDisjointSet ds(10);
33-
for (size_t i = 1; i < 10; ++i)
32+
ContiguousDisjointSet<std::uint32_t> ds(10);
33+
for (std::uint32_t i = 1; i < 10; ++i)
3434
{
3535
BOOST_CHECK(!ds.sameSubset(0, i));
3636
ds.merge(0, i);
@@ -42,16 +42,16 @@ BOOST_AUTO_TEST_CASE(full_union)
4242
std::set<size_t> fullSet{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
4343
BOOST_CHECK_EQUAL_COLLECTIONS(subsets[0].begin(), subsets[0].end(), fullSet.begin(), fullSet.end());
4444

45-
for (size_t i = 1; i < 10; ++i) BOOST_CHECK_EQUAL(ds.find(0), ds.find(i));
45+
for (std::uint32_t i = 1; i < 10; ++i) BOOST_CHECK_EQUAL(ds.find(0), ds.find(i));
4646
}
4747

4848
BOOST_AUTO_TEST_CASE(pairs)
4949
{
50-
ContiguousDisjointSet ds(10);
50+
ContiguousDisjointSet<std::uint32_t> ds(10);
5151
BOOST_CHECK_EQUAL(ds.numSets(), 10);
5252
BOOST_CHECK_EQUAL(ds.subsets().size(), 10);
5353

54-
auto const checkPair = [&](size_t expectedNumSubsets, size_t x, size_t y)
54+
auto const checkPair = [&](size_t expectedNumSubsets, std::uint32_t x, std::uint32_t y)
5555
{
5656
BOOST_CHECK_EQUAL(ds.numSets(), expectedNumSubsets);
5757
BOOST_CHECK_EQUAL(ds.subsets().size(), expectedNumSubsets);
@@ -84,7 +84,7 @@ BOOST_AUTO_TEST_CASE(pairs)
8484

8585
BOOST_AUTO_TEST_CASE(merge_with_fixed_representative)
8686
{
87-
ContiguousDisjointSet ds(10);
87+
ContiguousDisjointSet<std::uint32_t> ds(10);
8888
ds.merge(5, 3, false);
8989
BOOST_CHECK_EQUAL(ds.find(5), 5);
9090
ds.merge(1, 2);

0 commit comments

Comments
 (0)