
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<boost::multi_index::tag<byMSB>, boost::multi_index::global_fun<Storage, soSub, &Data::msb>>, // 0 boost::multi_index::hashed_non_unique<boost::multi_index::tag<byHSB>, boost::multi_index::global_fun<Storage, soPre, &Data::hsb>>, // 1 boost::multi_index::hashed_non_unique<boost::multi_index::tag<byLSB>, boost::multi_index::global_fun<Storage, soObj, &Data::lsb>> // 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<std::input_iterator_tag, Storage> { 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!