Multi-Index: custom iterator
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
Sensei
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++)
Hi Sensei,
One easy way to get something roughly equivalent in many situations
to what you want is (warning, uncompiled):
template<typename Tag>
typename boost::multi_index::index
On 8/25/14, 9:14pm, Joaquin M Lopez Munoz wrote:
One easy way to get something roughly equivalent in many situations to what you want is (warning, uncompiled):
template<typename Tag> typename boost::multi_index::index
::index::const_iterator myfind(const DataStorage& s,unsigned int v) { return s.template get<Tag>().find(v); } ...
auto it=myfind<byMSB>(storage,MSB(value128bits));
myfind returns a different iterator type depending on the tag you specify when calling it.
Hi Joaquin, and thanks as usual!
I am trying your solution with a member function, but I get the
following error:
/Users/sensei/Documents/Projects/scratch/indexed/indexed/main.cpp:145:16: error:
no matching member function for call to 'myfind'
auto q = d.myfind<byMSB>(Data::storage(1, 30, 30));
~~^~~~~~~~~~~~~
/Users/sensei/Documents/Projects/scratch/indexed/indexed/main.cpp:125:5:
note: candidate template ignored: substitution failure [with Index =
byMSB]: no type named 'const_iterator' in
'boost::multi_index::index
Note that this is *not* the same as returning a custom iterator type that is able to traverse the different indices DataStorage is comprised of: in order to do that you need to implement an iterator class with *type erasure*, which has a run-time penalty and is not entirely trivial to write. If you want to know more about type-erasing iterators, take a look at, for instance, adobe::any_iterator:
I guess I won't be writing a type-erasure-based custom iterator: I don't
like run-time overhead if I can avoid this :)
Thanks!
=== SOURCE CODE ===
#include
Sensei
On 8/25/14, 9:14pm, Joaquin M Lopez Munoz wrote:
One easy way to get something roughly equivalent in many situations to what you want is (warning, uncompiled):
template<typename Tag> typename boost::multi_index::index
:: index::const_iterator myfind(const DataStorage& s,unsigned int v) { return s.template get<Tag>().find(v); } ...
auto it=myfind<byMSB>(storage,MSB(value128bits));
myfind returns a different iterator type depending on the tag you specify when calling it.
Hi Joaquin, and thanks as usual!
I am trying your solution with a member function, but I get the following error:
There was a typo in my uncompiled code. Rather than
typename boost::multi_index::index
participants (2)
-
Joaquin M Lopez Munoz
-
Sensei