Boost logo

Boost :

Subject: Re: [boost] [parameter] some extensions to Boost.Parameter
From: David Abrahams (dave_at_[hidden])
Date: 2008-10-29 19:34:28


on Tue Oct 28 2008, "Stjepan Rajko" <stipe-AT-asu.edu> wrote:

> On Tue, Oct 28, 2008 at 2:08 PM, David Abrahams <dave_at_[hidden]> wrote:
>>
>> on Tue Oct 28 2008, "Stjepan Rajko" <stipe-AT-asu.edu> wrote:
>>
>>> I have found these extensions useful when
>>> using ArgumentPacks directly rather than using Boost.Parameter macros
>>> like BOOST_PARAMETER_FUNCTION, BOOST_PARAMETER_CONSTRUCTOR,... (I am
>>> using the library in this particular way because of reduced compile
>>> times
>>
>> That's a bit of a surprise. What kind of difference in compile time are
>> you seeing?
>>
>
> Nothing too dramatic. In the following experiment:
> http://article.gmane.org/gmane.comp.lib.boost.devel/178703
>
> ... the results for a simple test scenario gave the following times:
> user: [test_parameter_compilation.o] 0.000195
> system: [test_parameter_compilation.o] 0.000030
> user: [test_parameter_dispatch_compilation.o] 0.000555
> system: [test_parameter_dispatch_compilation.o] 0.000041
>
> test_parameter_compilation corresponds to using ArgumentPacks
> directly, and test_parameter_dispatch_compilation uses
> BOOST_PARAMETER_CONSTRUCTOR (perhaps for BOOST_PARAMETER_FUN the
> difference is even smaller or non-existent)
>
>>> and (IMO) cleaner library code
>>
>> Could you show some examples?
>>
>
> Sure. My use case is a GUI library that tries to make it easy to
> implement new widgets. Widgets can be put together by stacking
> behaviors in an inheritance chain. For example, a button uses the
> following base class:
>
> class button;
>
> typedef
> view::active_colored<
> view::solid_background<
> view::clickable<button,
> view::positioned<>
> > > > button_base_type;
>
> - each of the view:: templates listed adds a behavior to the button
> widget, and they are implemented by inheriting the next behavior in
> the chain (in this case, button will inherit active_colored which will
> inherit solid_background which will inherit clickable which will
> inherit positioned...). Here is the button constructor:
>
> class button : public button_base_type
> {
> public:
> typedef button_base_type base_type;
>
> template<typename ArgumentPack>
> button(const ArgumentPack &args)
> : button_base_type(args)
> {}
> ...
>
> I.e., the constructor takes an ArgumentPack and forwards it to its
> base class. The base class will perhaps pick off some arguments and
> forward the pack to its base, etc. For example, solid_background does
> this:
>
> template<typename BaseView=base>
> class solid_background : public BaseView
> {
> public:
> typedef BaseView base_type;
>
> template<typename ArgumentPack>
> solid_background(const ArgumentPack &args)
> : base_type(args)
> , m_background_color(args[_background])
> {}
> ...
>
> I have found that the direct use of ArgumentPacks makes this
> inheritance-chaining design quite nice/clean to implement. AFAICT,
> using the macro-based interface would have required two classes per
> view/behavior (an implementation class, and a class that uses
> BOOST_PARAMETER_CONSTRUCTOR) - this is because any of these classes
> can be the top-level class. That alone was reason enough for me not
> to investigate that route further - I'm not sure whether any
> difficulty would arise from having to specify that a class can receive
> a parameter intended for it, or intended for the base class.

I don't see why that means the top-level class needs to have an
ArgumentPack ctor.

class button : public button_base_type
{
 public:
     typedef button_base_type base_type;

     // takes up to 12 parameters
     MY_GUI_GENERATE_CTOR(button, 12, button_base_type);

>> Answers to these two questions could help me evaluate the merits of
>> integrating this functionality into the library.
>>
>>> (although user-side code takes a slight hit)).
>>
>> That shouldn't be necessary, even if you forego the macros.
>
> I think I'm stuck with requiring double parenthesis,

You shouldn't be.

> and I don't know how to take advantage of, e.g., deduced parameters.

They are only applicable when the types of possible arguments are
sharply distinct. Is that your situation?

>>> Here are brief descriptions of the extensions:
>>>
>>> *1* Keywords/Tags with fixed types
>>> These are intended for keywords/tags that are always associated with a
>>> certain type of argument. operator= of a fixed-type keyword always
>>> return a tagged argument whose value_type is the fixed type.
>>>
>>> This has the benefit of moving any type conversions to the call site,
>>
>> Might be interesting if we can integrate that into the macros for the
>> cases when you specify a fixed type. This sounds vaguely similar to
>> what we have to do for the Python binding functionality, except that we
>> do the "type fixing" post-facto.
>>
>
> I think this would be relatively easy and safe (in a non-breaking
> change sense) to add in.

Looking forward to seeing that.

>>> BOOST_PARAMETER_TYPED_NAME_WDEFAULT(label,const std::string,"")
>>>
>>> If a ArgumentPack args does not contain an explicit value for _label,
>>> args[_label] will return std::string(""). I'm not sure what the right
>>> response to e.g., args[label|"something"] should be.
>>
>> Compilation error?
>
> Perhaps. I think the alternative that Andrey Semashev suggested is
> also interesting, where "something" is chosen if the label is not
> explicitly provided.

Fine with me; that would've been the other obvious choice.

>> Ohhh.... so you're saying any two argument packs with the same keywords
>> and types would be inter-convertible, regardless of argument order?
>> That makes some sense.
>
>
> Yes - a source pack could be converted to a target pack type as long
> as the source contains a superset of the tags needed for the target
> (or any missing tags have a default-default value).

And, I hope, the types of the source pack have to be convertible to
the types of the target pack.

>>> *4* Overloading operator() for typed keywords
>>>
>>> Instead of writing, e.g.:
>>> window (( _size=size_type(100,100), _position=position_type(0,0) ))
>>> , we can write
>>> window (( _size(100,100), _position(0,0) ))
>>
>> Pretty cool.
>>
>> This looks like it overlaps with deduced parameters a lot, though.
>
> Yes, there is overlap. If deduced parameters were available (are
> they, without the macros?),

Yes.

> you could do:
>
> window (( size_type(100,100), position_type(0,0) ))
>
> except `window (( _size(100,100), _position(0,0) ))` would also work
> when size_type and position_type are the same type.

Yes.

>>> Please let me know if there is any interest.
>>
>> I'd have to see what Daniel thinks. It would also be interesting to
>> know if anyone else in the community has wanted this functionality.
>
> Thanks for taking a look!

Always nice to have someone else carrying our work forward!

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk