
on Mon Jul 14 2008, "vicente.botet" <vicente.botet-AT-wanadoo.fr> wrote:
Hello,
I'm doing a Locally Unique Identifier generator library. The DSL grammar is quite complex, so the use of optional class parameters seams unavoidable. I have started to use the Boost.Parameter Library as the Boost.Flyweight does.
I'm not familiar with Flyweight.
The flyweight class that takes 5 optional parameters and is currently declared as follows
<code> template< typename T, typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5 /**/>
I think there must be defaults for these arguments, probably parameter::void_, yes?
,
,
,
,
class flyweight { private: typedef parameter::parameters< parameter::optional< parameter::deduced<tag<> >, detail::is_tag<boost::mpl::_> parameter::optional< parameter::deduced<tracking<> >, is_tracking<boost::mpl::_> parameter::optional< parameter::deduced<factory<> >, is_factory<boost::mpl::_> parameter::optional< parameter::deduced<locking<> >, is_locking<boost::mpl::_> parameter::optional< parameter::deduced<holder<> >, is_holder<boost::mpl::_>
signature;
typedef typename signature::bind< Arg1,Arg2,Arg3,Arg4,Arg5
::type args; typedef typename parameter::binding< args,tag<>,mpl::na ::type tag_type; typedef typename parameter::binding< args,tracking<>,refcounted ::type tracking_policy; typedef typename parameter::binding< args,factory<>,hashed_factory<> ::type factory_specifier; typedef typename parameter::binding< args,locking<>,simple_locking ::type locking_policy; typedef typename parameter::binding< args,holder<>,static_holder ::type holder_specifier;
typedef parameter::parameters< parameter::optional< parameter::deduced< detail::unmatched_arg >, mpl::not_< mpl::or_< detail::is_tag<boost::mpl::_>, is_tracking<boost::mpl::_>, is_factory<boost::mpl::_>, is_locking<boost::mpl::_>, is_holder<boost::mpl::_> > >
unmatched_signature;
typedef typename unmatched_signature::bind< Arg1,Arg2,Arg3,Arg4,Arg5
::type unmatched_args; typedef typename parameter::binding< unmatched_args,detail::unmatched_arg, detail::unmatched_arg ::type unmatched_arg_detected; BOOST_STATIC_ASSERT((
Should use one of the MPL assertions, but anyway...
/* You have passed a type in the specification of a flyweight type that * could not be interpreted as a valid argument. */ is_same<unmatched_arg_detected,detail::unmatched_arg>::value)); ... </code>
I have made abstraction of the common structure of this code resulting on a 'expr' class. The boost::dsl::expr class has three parameters: * a tag for the expression * a vector of parameters specification, each one been either mandatory or optional, and containing a tag, a predicate stating if a parameter corresponds to the tag, and a default value for the optionals * a vector of the current parameters
The parameter associated to a given tag can be obtained using the get template function. For example to get the tracking parameter we can use:
typename base_type::template get<tracking<> >::type
All the implementation details are encapsulated on the expre class.
The flyweight class can then be rewriten as:
<code> <schnipp> </code>
BOOST_FLYWEIGHT_BASE is used to avoid repeating the long template expression
Rewriting so I can grok it... template < class T , class Arg1, class Arg2, class Arg3, class Arg4,class Arg5
struct flyweight_base { typedef dsl::expr< flyweight<T> , mpl::vector< dsl::optional<tag<>, detail::is_tag<mpl::_>, mpl::na > , dsl::optional<tracking<>, is_tracking<mpl::_>, refcounted > , dsl::optional<factory<>, is_factory<mpl::_>, hashed_factory<> > , dsl::optional<locking<>, is_locking<mpl::_>, simple_locking >, , dsl::optional<holder<>, is_holder<mpl::_>, static_holder > > , mpl::vector<Arg1,Arg2,Arg3,Arg4,Arg5> > type; }; template< typename T, typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5
class flyweight : public flyweight_base<T,Arg1,Arg2,Arg3,Arg4,Arg5>::type { typedef flyweight_base<T,Arg1,Arg2,Arg3,Arg4,Arg5>::type base_type; typedef typename base_type::template get< tag<> >::type tag_type; typedef typename base_type::template get< tracking<> >::type tracking_policy; typedef typename base_type::template get< factory<> >::type factory_specifier; typedef typename base_type::template get< locking<> >::type locking_policy; typedef typename base_type::template get< holder<> >::type holder_specifier; // ... }; So, what benefit, exactly, is the framework providing (e.g. is it providing the equivalent of the static assertion in the original code?), and what is the purpose of using derivation above?
I would like to know if there is an interest in such a class, and if it could be added to the parameters library?
Anything that makes declaring parameter-enabled classes simpler would be a welcome addition. However, I'm not yet sure what this is doing ;-) -- Dave Abrahams BoostPro Computing http://www.boostpro.com