|
Boost : |
From: David Abrahams (david.abrahams_at_[hidden])
Date: 2001-07-21 12:15:44
[It would be polite to identify yourself by name in the future]
Since you asked, I have a set of functions that need to be evaluated
repeatedly. The set of functions is designated by a type_list of tags
identifying the particular functions. Each tag has an associated argument
which needs to be passed to the corresponding function. So, I need to
iterate over the type list of tags and call the designated functions with
the arguments stored in the associative container.
-Dave
Sample code is attached below.
----- Original Message -----
From: "HYS" <hys420_at_[hidden]>
> What are you trying to do with this 'map'?
-----------
#include <iostream>
#include <string>
#include <typeinfo>
#include <boost/type_traits/same_traits.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/compressed_pair.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/type_list.hpp>
template <class TypeMap, class Tag>
struct is_head_tag
{
typedef typename TypeMap::head_type head_type;
typedef typename head_type::first_type key_type;
enum { value = boost::is_same<Tag, key_type>::value };
};
template <bool found, class TypeMap, class Tag>
struct typemap_find_helper
{
typedef typename TypeMap::tail_type tail_type;
enum { found_next = is_head_tag<tail_type,Tag>::value };
typedef typemap_find_helper<found_next,tail_type,Tag> next_helper;
typedef typename next_helper::type type;
static type find(TypeMap& m) { return next_helper::find(m.tail); }
};
template <class TypeMap, class Tag>
struct typemap_find_helper<true,TypeMap,Tag>
{
typedef typename TypeMap::head_type head_type;
typedef typename head_type::second_type type;
static type find(TypeMap& m) { return m.head.second(); }
};
template <class TypeMap, class Tag>
struct typemap_find
{
enum { at_head = is_head_tag<TypeMap,Tag>::value };
typedef typemap_find_helper<at_head,TypeMap,Tag> helper;
typedef typename helper::type type;
static type find(TypeMap& m) { return helper::find(m); }
};
template <class TypeMap>
struct print_type : boost::mpl::expression_statement
{
template <class Key> struct body
{
typedef print_type<TypeMap> next_statement;
static inline void execute(TypeMap* m)
{
std::cout
<< "type = " << typeid(Key).name();
std::cout
<< ", value= " << typemap_find<TypeMap,Key>::find(*m)
<< std::endl;
}
};
};
#if defined(BOOST_NO_WORKING_IS_CONVERTIBLE_IMPLEMENTATION)
namespace boost {
namespace mpl {
template<class T>
struct is_expression_statement< print_type<T> >
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
} // namespace mpl
} // namespace boost
#endif
template <class TypeMap, class TypeList>
void print_values(TypeMap m, TypeList)
{
typedef boost::mpl::for_each<TypeList,print_type<TypeMap> > loop;
loop::execute(&m);
};
struct tag1 {};
struct tag2 {};
struct tag3 {};
int main()
{
print_values(
boost::tuples::make_tuple(
boost::compressed_pair<tag1,char>('$'),
boost::compressed_pair<tag2,int>(100),
boost::compressed_pair<tag3,std::string>(tag3(),"money")),
boost::mpl::type_list<tag2,tag1,tag3>());
};
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk