Dear all,
I'm not yet satisfied with my MultiIndex games, so now I am trying to do
something that is purely cosmetic. However, I have *no idea* how I can
do this.
How can I build a custom iterator on a MultiIndex?
The objective is simple. As you may recall, I am building a MultiIndex
with 128 bits, indexing them by MSB, LSB, and HSB (in the middle). It
works like a charm.
Now I'd like to write something like this (or similar):
auto it = storage.myfind<byMSB>(MSB(value128bits));
for (; i != it.end(); i++)
In essence, I'd like to hide the get<> and everything I am using right
now (as shown below). So I need an iterator for this data structure:
typedef __uint128_t Storage;
// Indexing placeholders
struct byMSB { };
struct byHSB { };
struct byLSB { };
// Storage type with indexing
typedef boost::multi_index::multi_index_container<
Storage,
boost::multi_index::indexed_by<
// Hashed by subject/predicate/object
boost::multi_index::hashed_non_unique>, // 0
boost::multi_index::hashed_non_unique>, // 1
boost::multi_index::hashed_non_unique> // 2
>
> DataStorage;
DataStorage storage_;
With your suggestions I've achieved to find all items by MSB, but
sincerely, now I don't know how to write a custom iterator for this type.
The code for finding elements is this:
//typedef typename DataStorage::template nth_index<0>::type
byHashedIndex;
//typedef typename DataStorage::template index<byMSB>::type
byHashedIndex;
//byHashedIndex &p = storage_.template get<byMSB>();
auto &p = storage_.template get<byMSB>();
auto q = p.equal_range(subject(v));
while (q.first != q.second)
{
std::cout << " EQID " << *(q.first) << " | " <<
msb(*(q.first)) << " | " << hsb(*(q.first)) << " | " << lsb(*(q.first))
<< std::endl;
l.push_back(*(q.first));
q.first++;
}
Note: I *have* written iterators, but they were much easier (for
instance char*). This is far too complex for making my way on my own!
From the code above, I guess I have begin() and end() point to an
equal_range output .first and .second. But what will the "pointer" I
need in the iterator will be?
Of course, my first attempt is a complete failure:
// Iterator
template <class T>
class iterator : public std::iterator
{
typedef typename DataStorage::template index<T>::type
byHashedIndex;
byHashedIndex &p;
// Default constructor
iterator() : p(storage_.get<T>()) { };
// Copy constructor
iterator(const iterator& i) : p(i.p) { };
// Pre-increment ++it
iterator& operator++() { ++p; return *this; };
// Post-increment it++
iterator operator++(int) {iterator tmp(*this); operator++();
return tmp; };
// Equality
bool operator==(const iterator& rhs) { return p == rhs.p; };
// Non-equality
bool operator!=(const iterator& rhs) { return p != rhs.p; };
// Access
Storage& operator*() { return *p; };
// Difference
iterator operator-(int i) { return iterator(p - i); };
// Addition
iterator operator+(int i) { return iterator(p + i); };
};
Can you point me in the right direction?
Thanks!