Search code examples
c++boostboost-mplboost-variant

Applying a boost::mpl::list to the template parameter of a type


I have a class that requires a boost::variant containing shared pointers to various types as follows:

template <typename ToySharedPtrVariant, typename ColorSharedPtrVariant>
class ToyPicker {
   typedef std::pair<
     ToySharedPtrVariant, 
     ColorSharedPtrVariant 
   > toyAndColorPair;
   typedef std::map<
     std::string,
     std::vector< 
       toyAndColoPair 
     > 
   > stringToToyColorPairMap;

   // ... methods that use the defined types...
}

This class currently requires template parameters of the following form to compile:

ToyPicker<
           boost::variant<
             boost::shared_ptr<ToyModel> 
           >,
           boost::variant<
             boost::shared_ptr<BlueToy>,
             boost::shared_ptr<RedToy>,
             boost::shared_ptr<GreenToy> 
           > 
         > toyPicker;

How do I use an mpl list so that I can allow the following much simpler definition for users, then convert it into the example format above inside my class implementation?

ToyPicker<
       boost::mpl::list<
         ToyModel
       >,
       boost::mpl::list<
         BlueToy,
         RedToy,
         GreenToy 
       > 
     > toyPicker;

Solution

  • Using boost::mpl::transform in conjunction with boost::make_variant_over does the trick :

    #include <boost/mpl/list.hpp>
    #include <boost/mpl/transform.hpp>
    #include <boost/shared_ptr.hpp>
    #include <boost/variant/variant.hpp>
    
    template<class T>
    struct add_shared_pointer
    {
        typedef boost::shared_ptr<T> type;
    };
    
    template<class Seq>
    struct shared_ptr_variant
    {
        typedef typename boost::make_variant_over<
                typename boost::mpl::transform<
                    Seq, add_shared_pointer<boost::mpl::_1>
                >::type
            >::type type;
    };