I had a similar problem - I needed to iterate over elements of a map and
find each element's index. It works by using template recursion, iterating
from the start of the sequence, with the exit specialization being when the
type of the current element being iterated over is the same as the type of
the element in the sequence you are working with.
A natural side effect of this is that the types in the sequence need to be
unique, otherwise later duplicate types will get their index to be the
index of the first element in the sequence with the same type.
Here is my code, it may help (I posted this on stackoverflow here:
http://stackoverflow.com/questions/11698413/find-the-index-of-an-element-in-...
)
#include <iostream>
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace fusion = boost::fusion;
namespace mpl = boost::mpl;
// given a field, returns a fusion pair of
template<class field>
struct make_pair
{
typedef typename fusion::result_of::make_pair::type type;
};
// given a sequence of fields, returns a fusion map which maps field
-> field::type
template
struct make_map
{
typedef typename fusion::result_of::as_map,
make_pairmpl::_1>::type>::type type;
};
//-------------------------------------------------------------------------------------------
// iterate through a fusion map to find the index of a given key
template
struct key_index
{
typedef typename fusion::result_of::next<iter>::type next_iter;
typedef typename fusion::result_of::key_of::type next_key;
enum { value = 1 + key_index::value };
};
template
struct key_index
{
enum { value = 0 };
};
//-------------------------------------------------------------------------------------------
// copy an element from a vector to a map, if the index in the vector exists
template
struct do_copy
{
template<typename T>
void operator()(const vector& v, const T& dest)
{
const_cast(dest) = fusion::at_c<index>(v);
}
};
template
struct do_copy