Boost logo

Boost Users :

From: François Duranleau (duranlef_at_[hidden])
Date: 2006-04-23 00:39:31


On Sat, 22 Apr 2006, Andrew Schweitzer wrote:

> François Duranleau wrote:
>>
>> for ( variables_map::iterator i = vm.begin() ; i != vm.end() ; ++ i )
>> {
>> //...
>> }
>
> I tried that... but the map is filled with "any" values. You can dump
> the argument names, but I don't see a way to dump their values in a
> for-loop. Is there a way?

Use .as<> based on typeid? e.g.

for ( variables_map::iterator i = vm.begin() ; i != vm.end() ; ++ i )
{
     const variable_value& v = i->second ;
     if ( ! v.empty() )
     {
         const ::std::type_info& type = v.value().type() ;
         if ( type == typeid( ::std::string ) )
         {
             const ::std::string& val = v.as< ::std::string >() ;
             // ...
         }
         else if ( type == typeid( int ) )
         {
             int val = v.as< int >() ;
             // ...
         }
         // etc.
     }
}

Or you could create a map of actions to do with a given type, e.g.

struct type_info_compare
{
     bool operator () ( const ::std::type_info* lhs ,
                        const ::std::type_info* rhs ) const
     {
         return lhs->before( * rhs ) ;
     }
} ;

::std::map< const ::std::type_info* ,
             ::boost::function< void ( const variable_value& ) > ,
             type_info_compare >
     action_map ;

The map you could be built with something like this (a simple output
example):

template < typename T >
struct output_value
{
     void operator () ( const variable_value& v ) const
     {
         ::std::cout << v.as< T >() << ::std::endl ;
     }
} ;

//...

action_map[ & typeid( ::std::string ) ] = output_value< ::std::string >() ;
action_map[ & typeid( int ) ] = output_value< int >() ;
// etc.

And then:

for ( variables_map::iterator i = vm.begin() ; i != vm.end() ; ++ i )
{
     const variable_value& v = i->second ;
     if ( ! v.empty() )
     {
         ::std::cout << i->first << "=" ;
         action_map[ & v.value().type() ]( v ) ;
     }
}

This makes the iteration cleaner, but you need to build the map, which,
depending on what you want to do, may be easier/cleaner or not than a big
sequence of if/else as my first example in the for loop.

Most probably there are even better solutions than that. Anybody else has
an idea?

-- 
François Duranleau
LIGUM, Université de Montréal
"Le manque de culture générale est une source de grands désastres. [...]
  On constate de façon continue de véritables désastres qui ne sont causés
  que par une méconnaissance absolue du passé et de l'histoire."
                                                       - Bertrand Tavernier

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net