|
Boost Users : |
Subject: Re: [Boost-users] [MPL] Applying a boost::mpl::list to the template parameter of a type.
From: Igor R (boost.lists_at_[hidden])
Date: 2010-12-18 13:22:33
> 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 one above inside my class?
> Â Â Â ToyPicker<
> Â Â Â Â Â Â boost::mpl::list<
> Â Â Â Â Â Â Â ToyModel
> Â Â Â Â Â Â >,
> Â Â Â Â Â Â boost::mpl::list<
> Â Â Â Â Â Â Â BlueToy,
> Â Â Â Â Â Â Â RedToy,
> Â Â Â Â Â Â Â GreenToy
> Â Â Â Â Â Â >
> Â Â Â Â Â > toyPicker;
If you got you right, you map a Model to a list of Colors, right?
I'm not a TMP expert, but I'd propose something like this:
#include <boost/mpl/map.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
using namespace boost::mpl;
using boost::shared_ptr;
using boost::variant;
using boost::make_variant_over;
// a metafunction that will map for us maps list<a, b,...> -->
list<shared_ptr<a>, shared_ptr<b>, ...>
template<class Seq, template<class> class Wrapper>
struct add_wrapper : transform<Seq, Wrapper<_> >{};
// now your picker class get template args of the form pair<model,
list<color1, color2,...> >
template<typename ModelColors>
struct picker
{
// wrapping the model with shared_ptr and variant manually
typedef variant<shared_ptr<typename ModelColors::first> > wrapped_model;
// applying our metafunction to the sequence of colors, then
applying make_variant_over
typedef typename make_variant_over<typename add_wrapper<typename
ModelColors::second, shared_ptr>::type>::type wrapped_colors;
wrapped_colors colors_;
wrapped_model model_;
};
struct Model1;
struct Color1;
struct Color2;
struct Color3;
int main(int argc, char* argv[])
{
picker<pair<Model1, list<Color1, Color2> > > p;
return 0;
}
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