Boost logo

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