|
Boost : |
From: Larry Evans (cppljevans_at_[hidden])
Date: 2008-03-30 14:29:25
On 03/22/08 22:26, Eric Niebler wrote:
> Steven Watanabe wrote:
>> AMDG
>>
>> Larry Evans wrote:
>>> To make x2 compile, add an extra {}, IOW
>>>
>>> x2 = { { {1}, {1} } }
>>>
>>> where the extran {} is for expr2::args.
>>>
>>> So, the cost of this extra indirection is
>>> 1 more curly braces in
>>> every expr initializer list?
>>>
>> Exactly. If you recall I said that it changes the interface. Not
>> that it doesn't work. In short, the existence of the "private"
>> partially specialized version of expr would not entirely be an
>> implementation detail.
>>
>> This may also add overhead because of the extra template.
>> On the other hand, it may compile faster because the operator()
>> overloads don't need to be duplicated.
>>
>> Oh. I just realized that this would also force expr::make to change.
>> expr::make() takes a number of arguments equal to the arity so it
>> needs to be in the private struct as well. I'm afraid that this would
>> ripple across the library, and turn out to be a not so minor change,
after
>> all.
>
>
> Yes, I've played with a similar design, and I've found it to cause
> initialization to be rather tricky. Consider the following
> initializations today:
>
> terminal<int>::type t = {1};
> plus<
> terminal<int>::type
> , terminal<int>::type
> >::type u = {{1}, {1}};
>
> That's fairly straightforward. With an extra set of braces with each
> expr, it becomes the rather unwieldy:
>
> terminal<int>::type t = {{1}};
> plus<
> terminal<int>::type
> , terminal<int>::type
> >::type u = {{{{1}}, {{1}}}};
>
> That hurts my eyes.
>
The file, expk_test.zip here:
http://www.boost-consulting.com/vault/index.php?&directory=Strings%20-%20Text%20Processing
Contains a prototype where tags contain the arity. This prototype
enables initialization like:
<===== cut here =======
using namespace boost::proto;
typedef
tags::tag_kind_arity<tags::tag2<tags::tag2_shift_right>,tags::tag_valu,2>
tag_shift_right_2;
expk<tag_shift_right_2,args2<int,int> > shift_right_int_int={1,2};
>===== cut here =======
Now if, instead of args2<int,int>, there was
args2<terminal<int>,terminal<int> >, I'm assuming it would behave like
the current:
u = {{1}, {1}}
I tried to figure out if putting arity in tags would prevent some
specialization on arity which proto currently uses to do it's work. I
guessed that maybe this specialization was used in or_ or and_;
however, when I looked in matches.hpp, all I found (that was relevant,
AFAICT) was:
// and_ and or_ implementation
template<bool B, typename Expr, typename G0>
struct or1
: mpl::bool_<B>
{
typedef G0 which;
};
template<bool B>
struct and1
: mpl::bool_<B>
{};
and I couldn't figure out how it works. I would have guessed there
would be some specialization on the bool B template parameter, but
apparently not.
Eric, could you mention the code where specialization on arity is used
and how it works. I might could figure it out eventually, but I'm
guessing others, in the future, might like to understand this also,
and this information, documented somewhere in an implementation or
design guide, would be *real* handy.
Of course, I realize you're in the middle of analyzing all the proto
reviews, but eventually, getting this information about how it works
would be quite helpful.
TIA
-regards,
Larry
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk