patterncppMinor
Container for Sets of Integers
Viewed 0 times
integerssetsforcontainer
Problem
I implemented an unordered_set like container for storing small sets of unsigned integers. It uses a trivial hash table for lookups and an unordered array for quickly iterating over small sets.
I'm looking for suggestions on best practices and correctness.
```
#pragma once
#include
#include
#include
// T - Type of integer.
// N - Number of integers in the set from 0 to N-1
template class integer_set
{
private:
static constexpr T NOT_IN_SET = ~static_cast(0);
static const T MIN_SIZE_TO_SEARCH_INDEX;
public:
class iterator
{
public:
iterator(const iterator& it) = default;
iterator& operator=(const iterator& it) = default;
iterator();
iterator(const T* element);
bool operator==(const iterator& it) const;
bool operator!=(const iterator& it) const;
bool operator(const iterator& it) const;
bool operator=(const iterator& it) const;
T operator*() const;
T operator[](T i) const;
iterator& operator++();
iterator operator++(int);
iterator& operator--();
iterator operator--(int);
iterator operator+(T i) const;
iterator operator-(T i) const;
iterator& operator+=(T i);
iterator& operator-=(T i);
private:
const T* m_element;
};
public:
// The following are undefined if the set is empty:
// front()
// back()
// operator[]()
// min()
// max()
// random()
integer_set();
integer_set(const integer_set& set);
integer_set& operator=(const integer_set& set);
bool operator==(const integer_set& set) const;
bool operator!=(const integer_set& set) const;
bool operator=(const integer_set& set) const;
bool operator(const integer_set& set) const;
T front() const;
T back() const;
iterator begin() const;
iterator end() const;
iterator find(T v) const;
T operator[](T i) const;
T min() const;
T max() const;
template T random(URNG& gen) const;
T size() const;
bool empty() const;
bool contains(T v) const;
void clear();
void insert(T v);
v
I'm looking for suggestions on best practices and correctness.
```
#pragma once
#include
#include
#include
// T - Type of integer.
// N - Number of integers in the set from 0 to N-1
template class integer_set
{
private:
static constexpr T NOT_IN_SET = ~static_cast(0);
static const T MIN_SIZE_TO_SEARCH_INDEX;
public:
class iterator
{
public:
iterator(const iterator& it) = default;
iterator& operator=(const iterator& it) = default;
iterator();
iterator(const T* element);
bool operator==(const iterator& it) const;
bool operator!=(const iterator& it) const;
bool operator(const iterator& it) const;
bool operator=(const iterator& it) const;
T operator*() const;
T operator[](T i) const;
iterator& operator++();
iterator operator++(int);
iterator& operator--();
iterator operator--(int);
iterator operator+(T i) const;
iterator operator-(T i) const;
iterator& operator+=(T i);
iterator& operator-=(T i);
private:
const T* m_element;
};
public:
// The following are undefined if the set is empty:
// front()
// back()
// operator[]()
// min()
// max()
// random()
integer_set();
integer_set(const integer_set& set);
integer_set& operator=(const integer_set& set);
bool operator==(const integer_set& set) const;
bool operator!=(const integer_set& set) const;
bool operator=(const integer_set& set) const;
bool operator(const integer_set& set) const;
T front() const;
T back() const;
iterator begin() const;
iterator end() const;
iterator find(T v) const;
T operator[](T i) const;
T min() const;
T max() const;
template T random(URNG& gen) const;
T size() const;
bool empty() const;
bool contains(T v) const;
void clear();
void insert(T v);
v
Solution
You should learn about
It has almost everything you wants already with far less data storage. Encapsulate it inside your class to keep track of
But according to your real usage, it may be not even needed and a mere
Below is your test case translated with a bitset:
std::bitset.It has almost everything you wants already with far less data storage. Encapsulate it inside your class to keep track of
min, max and count in O(1) and write a custom iterator to list only the raised bits.But according to your real usage, it may be not even needed and a mere
std::bitset will be enough.Below is your test case translated with a bitset:
#include
#include
int main() {
std::cout set256;
using set256 = std::bitset;
std::cout << "byte count for 256 bits : " << sizeof(set256) << '\n';
set256 set1;
set1.set(144);
set1.set(255);
set1.set(0);
std::cout << "test separate bits : ";
std::cout << set1.test(0) << " ";
std::cout << set1.test(144) << " ";
std::cout << set1.test(255) << "\n";
std::cout << "count before after reset : ";
std::cout << set1.count() << " ";
set1.reset();
std::cout << set1.count() << "\n";
for(uint16_t i=30;i<100;i+=7)
set1.set(i);
set1.set(2);
set1.set(252);
for(uint16_t i=121;i<240;i+=3)
set1.set(i);
set256 set2;
set2.set(30);
auto inter = set1&set2;
std::cout << "test over an intersection : " << inter.test(30) << "\n";
set2 = set1;
set1 &= ~set2;
std::cout << "a complicated way to clear a bit set by anding a flipped copy : " << set1.count() << "\n";
return 0;
}Code Snippets
#include <bitset>
#include <iostream>
int main() {
std::cout << std::boolalpha;
//typedef integer_set<uint16_t,256> set256;
using set256 = std::bitset<256>;
std::cout << "byte count for 256 bits : " << sizeof(set256) << '\n';
set256 set1;
set1.set(144);
set1.set(255);
set1.set(0);
std::cout << "test separate bits : ";
std::cout << set1.test(0) << " ";
std::cout << set1.test(144) << " ";
std::cout << set1.test(255) << "\n";
std::cout << "count before after reset : ";
std::cout << set1.count() << " ";
set1.reset();
std::cout << set1.count() << "\n";
for(uint16_t i=30;i<100;i+=7)
set1.set(i);
set1.set(2);
set1.set(252);
for(uint16_t i=121;i<240;i+=3)
set1.set(i);
set256 set2;
set2.set(30);
auto inter = set1&set2;
std::cout << "test over an intersection : " << inter.test(30) << "\n";
set2 = set1;
set1 &= ~set2;
std::cout << "a complicated way to clear a bit set by anding a flipped copy : " << set1.count() << "\n";
return 0;
}Context
StackExchange Code Review Q#45689, answer score: 5
Revisions (0)
No revisions yet.