Boost logo

Boost :

Subject: Re: [boost] [guidelines] why template errors suck
From: David Abrahams (dave_at_[hidden])
Date: 2010-09-27 00:49:21


At Sun, 26 Sep 2010 22:31:54 -0400,
Eric Niebler wrote:
> On 9/26/2010 9:44 PM, David Abrahams wrote:
> > On Sep 26, 2010, at 8:55 AM, Eric Niebler wrote:
> >> On 9/25/2010 1:24 PM, David Abrahams wrote:
> >>> On Sep 24, 2010, at 11:51 PM, Eric Niebler wrote:
> >>>> On 9/24/2010 9:37 PM, David Abrahams wrote:
> >>>>
> >>>> Haha! No, not at all. Let's rephrase the problem a bit. If we still had
> >>>> C++0x concepts, what would the concept SpiritParser look like, such that
> >>>> we could define spirit::qi::rule::operator= such that it required its
> >>>> RHS to satisfy the SpiritParser concept?
> >>>
> >>> That's easy to answer; just look at the operations that
> >>> operator= et. al expect of such a type. Wouldn't SpiritParser
> >>> just be some simple refinement of Callable?
> >>
> >> No. rule::operator= expects SpiritParser to be a strongly-typed tree.
> >
> > Meaning? Spell it out and you have your requirements.
>
> Meaning:
>
> + If the topmost node has tag-type "plus", there must be exactly one
> child node that models SpiritParser
> + If the topmost node has tag-type "shift_right", there must be exactly
> two child nodes that model SpiritParser,
> + If the topmost node has tag-type "subscript", there must be a left
> node that models SpiritParser and a right node that models PhoenixLambda,
> ...
> etc, etc, etc, ad nauseum

No offense, but did you really answer the question I asked? Does
operator= actually use those requirements? On the face of it, it just
seems a lot more likely that it simply requires its RHS to also be a
SpiritParser.

> How do I express that as a concept?

Summoning up my dim memory of proposed concept notation (so there are
guaranteed nits to pick), that might translate into something like:

concept SpiritNode<typename Node, typename Tag>
{
}

template <class Node>
concept_map SpiritNode<typename Node, plus>
{
    requires SameType<Node::children,int_<1> >;
    typename child_t;
    requires SpiritParser<child_t>;
    child_t child;
}

template <class Node>
concept_map SpiritNode<typename Node, shift_right>
{
    requires SameType<Node::children,int_<2> >;
    typename child1_t;
    requires SpiritParser<child1_t>;
    typename child2_t;
    requires SpiritParser<child2_t>;

    child1_t child1;
    child2_t child2;
}

template <class Node>
concept_map SpiritNode<typename Node, subscript>
{
    requires SameType<Node::children,int_<2> >;
    typename child1_t;
    requires SpiritParser<child1_t>;
    typename child2_t;
    requires PhoenixLambda<child2_t>;

    child1_t child1;
    child2_t child2;
}

concept RHSOfAssign<typename X>
{
    typename tag_type; // Every RHSOfAssign has an associated tag_type
    requires SpiritNode<X, tag_type>;
}

This isn't really how concepts were "meant to be used," though.

-- 
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