
on Thu Oct 30 2008, "Stjepan Rajko" <stipe-AT-asu.edu> wrote:
On Wed, Oct 29, 2008 at 4:34 PM, David Abrahams <dave@boostpro.com> wrote:
on Tue Oct 28 2008, "Stjepan Rajko" <stipe-AT-asu.edu> wrote:
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.
Every class needs a constructor that takes an ArgumentPack because it can be inherited from, and needs to be able to receive the ArgumentPack from the derived class. If I wanted to allow users to call the constructor in a more friendly way, then every class that could be a top-level class would also need a constructor like you suggest below (and 'every class' would need to turn into a pair of classes because we can't delegate to another constructor in the same class, no?).
Ideally, I would want to allow things like this:
typedef view::solid_background< view::positioned<> > colored_block;
some_window << new colored_block(...);
BUT... I might have other reasons why I might require a boiler-plate top-level class, in which case I might do something like what you suggest below.
Sorry, maybe I didn't understand correctly, but I thought classes like button below were "top level" and were not chained like the elements of button_base_type. If that's wrong *and* classes like button have interesting construction behavior of their own, then yes, they would have to both pass argument packs through and have a base class to which they can delegate "real" construction.
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);
does MY_GUI_GENERATE_CTOR expand to
template<typename T0> button(const T0 &t0) : button_base_type((t0)) {}
template<typename T0, typename T1> button(const T0 &t0, const T1 &t1) : button_base_type((t0, t1)) {}
...
?
Something like that.
[...]
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?
No, I was just curious in general.
Look at the documentation for Boost.Python's def(...) function and class_<...> template.
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.
I'm sorry, I think I misunderstood your comment. I thought you were talking about adding something to the library that allows things like BOOST_PARAMETER_TYPED_NAME(arg, int) - which is easy and I have done. But are you talking about
BOOST_PARAMETER_FUNCTION( (void), foo, tag, (required (arg, int) ) (optional (arg2, double, 1.5) ) )
... and how the expansion of that could be altered?
Yes.
I looked at the preprocessing file but got pretty lost, I think it might take me a while before I understand how it works.
Daniel is responsible for most of that code; maybe he can help.
[...]
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.
I've been using this with typed keywords, in which the types should be identical if the tags match. When conversions are necessary, because tagged_argument stores the argument by reference you end up with a dangling reference because the converted temporary goes out of scope before the function actually gets called. If you wanted conversions, you would need tagged_argument to store by value at least in this case (in which case it might be more efficient for arg_list to store the tagged_argument by reference... but I'm not sure whether that would run into the same temporary lifetime problems or other issues).
Hm.
[...]
Yes, there is overlap. If deduced parameters were available (are they, without the macros?),
Yes.
How?
Sorry, no time to explain right now, but you can see examples in libs/parameter/test/deduced.cpp and libs/parameter/test/deduced_dependent_predicate.cpp. I suggest also reading the reference docs on ParameterSpec's -- Dave Abrahams BoostPro Computing http://www.boostpro.com