#include <boost/foreach.hpp>
#include <boost/function.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/any.hpp>
#include <boost/bind.hpp>
#include <vector>
#include <typeinfo>
#include <map>
#include <iostream>
namespace
{
template <typename Types, typename ToType>
struct converters_map
{
typedef boost::function<ToType (boost::any)> converter;
typedef std::map<std::type_info const*, converter> map_type;
converters_map()
{
boost::mpl::for_each<Types>(inserter(m_map));
}
converter const& operator[](boost::any& val)
{
return m_map[&val.type()];
}
private:
map_type m_map;
struct inserter
{
template <typename FromType>
static ToType cast(boost::any& arg)
{
return boost::any_cast<FromType>(arg);
}
inserter(map_type& m): m(m) {}
template <typename Type>
void operator()(Type)
{
m[&typeid(Type)] = cast<Type>;
}
map_type& m;
};
};
}
template <typename Types, typename ToType>
ToType sum(std::vector<boost::any>& args)
{
converters_map<Types, ToType> map;
ToType result = ToType();
BOOST_FOREACH(boost::any& val, args)
{
assert(map[val] && "undefined converter");
result += map[val](val);
}
return result;
}
int main(int argc, char* argv[]) {
typedef boost::mpl::vector<int,long, float, double> types;
std::vector<boost::any> seq;
seq.push_back(boost::any( 1 ));
seq.push_back(boost::any( 2L ));
seq.push_back(boost::any( 3.0F ));
seq.push_back(boost::any( 4.0 ));
double result = sum<types, double>(seq);
std::cout << result << std::endl;
}