-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbit_tuple_iterator.hpp
67 lines (54 loc) · 1.22 KB
/
bit_tuple_iterator.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// bit_tuple_iterator.hpp
//
// Generate all n-tuples where each element is drawn
// from the set {0,1}. The algorithm is based on
// incrementing a binary counter. (Note the difference
// to e.g. Gray code).
#ifndef BIT_TUPLE_ITERATOR_HPP
#define BIT_TUPLE_ITERATOR_HPP
#include <cstdint>
#include <numeric>
#include <type_traits>
#include <cassert>
#include <boost/iterator/iterator_facade.hpp>
template <typename T>
class bit_tuple_iterator
: public boost::iterator_facade <
bit_tuple_iterator<T>,
const T&,
boost::forward_traversal_tag
>
{
private:
static_assert(std::is_integral<T>::value, "T must be integral");
public:
bit_tuple_iterator() : end_(true), n_(0), p_(0) { }
explicit bit_tuple_iterator(int p) : end_(false), n_(0), p_(std::pow(2, p) - 1)
{
assert(p_ == std::pow(2, p) - 1 && "T not large enough to hold 2^p");
assert(p <= sizeof(T) * 8 && "T not large enough to hold n tuples");
assert(n_ == 0);
}
private:
friend class boost::iterator_core_access;
void increment()
{
if (p_ == n_)
{
end_ = true;
}
++n_;
}
bool equal(const bit_tuple_iterator& other) const
{
return end_ == other.end_;
}
const T& dereference() const
{
return n_;
}
bool end_;
T n_;
const T p_;
};
#endif