Boost logo

Boost Users :

Subject: [Boost-users] [MPL] initialization of member that might be non-copyable
From: Noah Roberts (roberts.noah_at_[hidden])
Date: 2011-03-25 16:48:54


I'm working on something similar to the construct devised in the MPL
book Section 9.5 (class composition). Some objects in the composed type
might require initialization. I've solved this problem.

However, in solving that problem I've now required that any type going
into the composition must be copyable. However, since the original
composition code doesn't make this requirement I've been trying to find
a way to retain the ability to contain types that are non-copyable.

Here's some code:

template < typename Field >
struct field_value
{
   typedef Field field;
   typedef typename Field::type ftype;
   ftype value;

   field_value(ftype const& t) : value(t) {}
   field_value() : value() {}
};

template < typename Field, typename ParamFields, typename Enable = void >
struct initializer
{
   template < typename Params >
   static typename Field::type apply(Params &)
   {
     return Field::type();
   }
};
template < typename Field, typename ParamFields >
struct initializer<Field,ParamFields, typename boost::enable_if<
boost::mpl::contains<typename Params::fields, typename
FieldValue::field> >::type >
{
   template < typename Params >
   static typename Field::type apply(Params & params)
   {
     return get<Field>(params);
   }
};

template < typename FieldValue, typename Params >
FieldValue init_field(Params & pars)
{
   return initializer<typename FieldValue::field, typename
Params::fields >::apply(pars);
}

template < typename FieldValue, typename More >
struct record_base : FieldValue, More
{
   template < typename Params >
   record_base(Params & pars)
     : FieldValue(init_field<FieldValue>(pars))
     , More(pars)
   {}

   record_base() : FieldValue(), More() {}
};
struct empty_record_base
{
   template < typename Ignored >
   empty_record_base(Ignored&){}
   empty_record_base() {}
};

template < typename MplSequence >
struct build_record
{
   typedef boost::mpl::placeholders::_1 _1;
   typedef boost::mpl::placeholders::_2 _2;

   typedef typename boost::mpl::fold
     <
       MplSequence
     , empty_record_base
     , record_base< field_value<_2>, _1 >
>::type type;

   // type should be record_base< field_value<field0>
   // , record_base< field_value<field1>
   // , ...
record_base<field_value<fieldN>, empty_record_base>
   // > ...
   // >
};

It's at this point:

   template < typename Params >
   record_base(Params & pars)
     : FieldValue(init_field<FieldValue>(pars))
     , More(pars)
   {}

That I need to apply something, I know not what, to correctly initialize
the field with either a parameter argument or nothing. I can't think of
any construct that would make that possible but I don't necessarily know
everything. Is there some way that this can be accomplished?


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