HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Container for Sets of Integers

Submitted by: @import:stackexchange-codereview··
0
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

Solution

You should learn about 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.