
On Sep 27, 2010, at 10:11 AM, Eric Niebler wrote:
On 9/27/2010 12:49 AM, David Abrahams wrote:
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?
It does. operator= doesn't know how to process the tree (that is, what the requirements are) until it looks at the top-most node type and dispatches to the correct helper functions. Those functions have their own requirements determined solely by the substructure of the trees they operate on.
For instance, take semantic actions, denoted by the subscript tag. If a subscript node appears anywhere in the tree, the right child of that node must satisfy the concept PolymorphicFunctionObject. rule::operator= will fail to compile if it does not; it has assumed that requirement as a result of the recursive function calls made within the body of operator=. I'd like to be able to check for that condition up front. I still don't know how using concepts.
On the face of it, it just seems a lot more likely that it simply requires its RHS to also be a SpiritParser.
Where a SpiritParser is ...?
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.
You haven't shown how the SpiritNode and SpiritParser concepts are related.
Of course not; you didn't say they were related. I just translated the constraints you wrote down into concepts-land.
There must be some recursive relationship, like "a SpiritParser is a SpiritNode<plus> /or/ a SpiritNode<right_shift> /or/ ..." It requires OR constraints
Do say that, you just use concept_maps to declare that SpiritNode<plus> models SpiritParser, etc.: concept_map SpiritParser<SpiritNode<plus> > { // ... } concept_map SpiritParser<SpiritNode<right_shift> > { // ... }
which, as Sebastian has pointed out, were yanked from the concepts proposal.
With good reason.
rule::operator= is an algorithm. The structure of the type on which it's parametrized and the grammar to which that type must conform together determine what the overall algorithm requirements are. It by necessity cannot be expressed without OR constraints.
I don't understand how you can come to that conclusion with such certainty, while at the same time declaring that you don't understand concepts.
What I seem to have is a situation where an algorithm has type requirements that cannot be expressed with concepts, so concepts cannot help me validate my type parameter.
I don't see it (yet), sorry. Am I missing something? -- Dave Abrahams BoostPro Computing http://boostpro.com