
Hi, In Phoenix 3, is Actor assignable? This is necessary for filter_iterator/transform_iterator with Phoenix to be "neat" iterators. (Unfortunately, Actor is not assignable in Phoenix 2.) P.S. After writing this mail, I found this comment (What a coincidence ;-) #4853 (Actor is never assignable regardless of the template parameter) https://svn.boost.org/trac/boost/ticket/4853#comment:2 Comment (by theller): This is fixed in phoenix V3 So the answer to this question is YES. Thank you for great work, Thomas! Regards, Michel

Michel MORIN wrote:
Hi,
In Phoenix 3, is Actor assignable? This is necessary for filter_iterator/transform_iterator with Phoenix to be "neat" iterators. (Unfortunately, Actor is not assignable in Phoenix 2.)
P.S. After writing this mail, I found this comment (What a coincidence ;-)
Indeed.
#4853 (Actor is never assignable regardless of the template parameter) https://svn.boost.org/trac/boost/ticket/4853#comment:2 Comment (by theller): This is fixed in phoenix V3
So the answer to this question is YES. Thank you for great work, Thomas!
You are welcome! Glad I could help :)
Regards, Michel _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 1/20/2011 5:28 PM, Michel MORIN wrote:
Hi,
In Phoenix 3, is Actor assignable? This is necessary for filter_iterator/transform_iterator with Phoenix to be "neat" iterators. (Unfortunately, Actor is not assignable in Phoenix 2.)
Fixed this in phoenix-2 as well. That private assignment operator is a bug. I'm not sure how it got there. Anyway, whoever added the ticket, next time, please assign phoenix related tickets either to me or Thomas Heller. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

I have another question about Phoenix 3. Is the copy assignment of Actors no-op, or does it really copy the contents? Actor a; Actor b = ...; a = b; // no-op? If it is no-op, then the second assertion in the following code is not generally satisfied (the same code is attached in this mail): #include <boost/assert.hpp> #include <boost/iterator/transform_iterator.hpp> #include <boost/phoenix/core.hpp> #include <boost/phoenix/operator.hpp> template <typename Iterator> void test_forward_iterator(Iterator const& i) { Iterator j = i; BOOST_ASSERT(*j == *i); // OK Iterator k; k = i; BOOST_ASSERT(*k == *i); // Oops! } int main(int argc, char* argv[]) { using boost::phoenix::arg_names::_1; int ar[3] = {}; test_forward_iterator(boost::make_transform_iterator(ar, _1 + 5)); return 0; } So transform_iterator with Phoenix-3 Actors cannot satisfy even the ForwardIterator requirements. (In Phoenix 2, boost::phoenix::value<T> is not default constructible, and so the above iterator does not satisfy the ForwardIterator requirements too.) I wish transform_iterator with Phoenix Actors can be ForwardIterator, BidirectionalIterator and RandomAccessIterator :) Regards, Michel

On 1/21/2011 8:39 PM, Michel MORIN wrote:
I have another question about Phoenix 3. Is the copy assignment of Actors no-op, or does it really copy the contents?
Actor a; Actor b = ...; a = b; // no-op?
It should copy the contents. Thomas? [snip]
(In Phoenix 2, boost::phoenix::value<T> is not default constructible, and so the above iterator does not satisfy the ForwardIterator requirements too.)
That is true. phoenix::value is not default constructible. While it is easy to make it so, I'm not sure it is a good idea as it will potentially break existing code which holds values that are not default constructible. I'd argue that phoenix3 should follow. OTOH, I think a good compromise is to allow default construction on primitive types and POD structs. That will solve your problem. I can do that now with phoenix-2. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

Joel de Guzman wrote:
On 1/21/2011 8:39 PM, Michel MORIN wrote:
I have another question about Phoenix 3. Is the copy assignment of Actors no-op, or does it really copy the contents?
Actor a; Actor b = ...; a = b; // no-op?
It should copy the contents. Thomas?
Not really. It needs to create the assign actor (that means the expression template representing the assignment operation. It is neither a no-op nor is the assignment "executed". Remember the stuff about phoenix being lazy ;)?
[snip] (some code...) Michel, did you compile and run the code? It works like a charm. Here is why: Iterator is not a phoenix actor. It is a boost::transform_iterator<Phoenix Actor, int*>.
The only requirement the phoenix actors have to fullfill are those of a UnaryFunction. The type UnaryFunction must be Assignable, Copy Constructible, [...] A Phoenix Actor can never be (fully) Assignable. However, apart from this:
Actor a; Actor b = ...; a = b; // no-op?
It fulfills every other requirement of the Assignable concept[1].
(In Phoenix 2, boost::phoenix::value<T> is not default constructible, and so the above iterator does not satisfy the ForwardIterator requirements too.)
That is true. phoenix::value is not default constructible. While it is easy to make it so, I'm not sure it is a good idea as it will potentially break existing code which holds values that are not default constructible. I'd argue that phoenix3 should follow.
In phoenix 3 most actors are PODs ... making them default constructible.
OTOH, I think a good compromise is to allow default construction on primitive types and POD structs. That will solve your problem. I can do that now with phoenix-2.
Regards,

On 1/22/2011 8:17 PM, Thomas Heller wrote:
Joel de Guzman wrote:
On 1/21/2011 8:39 PM, Michel MORIN wrote:
I have another question about Phoenix 3. Is the copy assignment of Actors no-op, or does it really copy the contents?
Actor a; Actor b = ...; a = b; // no-op?
It should copy the contents. Thomas?
Not really. It needs to create the assign actor (that means the expression template representing the assignment operation. It is neither a no-op nor is the assignment "executed". Remember the stuff about phoenix being lazy ;)?
No! That's not the case here. There *is* still the immediate assignment operator being called when two actors are of the same type (e.g. when lhs and rhs are phoenix values). In these cases, a *is* assigned to *b*. Thus, for values, the contents are copied. Ditto for copy construction of course.
[snip] (some code...) Michel, did you compile and run the code? It works like a charm. Here is why: Iterator is not a phoenix actor. It is a boost::transform_iterator<Phoenix Actor, int*>.
The only requirement the phoenix actors have to fullfill are those of a UnaryFunction. The type UnaryFunction must be Assignable, Copy Constructible, [...]
A Phoenix Actor can never be (fully) Assignable. However, apart from this:
Actor a; Actor b = ...; a = b; // no-op?
It fulfills every other requirement of the Assignable concept[1].
(In Phoenix 2, boost::phoenix::value<T> is not default constructible, and so the above iterator does not satisfy the ForwardIterator requirements too.)
That is true. phoenix::value is not default constructible. While it is easy to make it so, I'm not sure it is a good idea as it will potentially break existing code which holds values that are not default constructible. I'd argue that phoenix3 should follow.
In phoenix 3 most actors are PODs ... making them default constructible.
OTOH, I think a good compromise is to allow default construction on primitive types and POD structs. That will solve your problem. I can do that now with phoenix-2.
Which *may* break existing code as mentioned above. Whether that's a big deal or not, I'm not so sure. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

On 1/22/2011 9:02 PM, Joel de Guzman wrote:
On 1/22/2011 8:17 PM, Thomas Heller wrote:
Joel de Guzman wrote:
On 1/21/2011 8:39 PM, Michel MORIN wrote:
I have another question about Phoenix 3. Is the copy assignment of Actors no-op, or does it really copy the contents?
Actor a; Actor b = ...; a = b; // no-op?
It should copy the contents. Thomas?
Not really. It needs to create the assign actor (that means the expression template representing the assignment operation. It is neither a no-op nor is the assignment "executed". Remember the stuff about phoenix being lazy ;)?
No! That's not the case here. There *is* still the immediate assignment operator being called when two actors are of the same type (e.g. when lhs and rhs are phoenix values). In these cases, a *is* assigned to *b*. Thus, for values, the contents are copied. Ditto for copy construction of course.
Oops, I meant b is assigned to a of course :-P Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

Joel de Guzman wrote:
On 1/22/2011 9:02 PM, Joel de Guzman wrote:
On 1/22/2011 8:17 PM, Thomas Heller wrote:
Joel de Guzman wrote:
On 1/21/2011 8:39 PM, Michel MORIN wrote:
I have another question about Phoenix 3. Is the copy assignment of Actors no-op, or does it really copy the contents?
Actor a; Actor b = ...; a = b; // no-op?
It should copy the contents. Thomas?
Not really. It needs to create the assign actor (that means the expression template representing the assignment operation. It is neither a no-op nor is the assignment "executed". Remember the stuff about phoenix being lazy ;)?
No! That's not the case here. There *is* still the immediate assignment operator being called when two actors are of the same type (e.g. when lhs and rhs are phoenix values). In these cases, a *is* assigned to *b*. Thus, for values, the contents are copied. Ditto for copy construction of course.
Oops, I meant b is assigned to a of course :-P
Seems like i don't stand a chance. I was trying to find a use case where you might want the lazy version of the assignment ... couldn't find one. Added the operator=(actor const&) to phoenix 3. Thanks for the hint. Regards, Thomas

On 1/22/2011 10:13 PM, Thomas Heller wrote:
Joel de Guzman wrote:
On 1/22/2011 9:02 PM, Joel de Guzman wrote:
On 1/22/2011 8:17 PM, Thomas Heller wrote:
Joel de Guzman wrote:
On 1/21/2011 8:39 PM, Michel MORIN wrote:
I have another question about Phoenix 3. Is the copy assignment of Actors no-op, or does it really copy the contents?
Actor a; Actor b = ...; a = b; // no-op?
It should copy the contents. Thomas?
Not really. It needs to create the assign actor (that means the expression template representing the assignment operation. It is neither a no-op nor is the assignment "executed". Remember the stuff about phoenix being lazy ;)?
No! That's not the case here. There *is* still the immediate assignment operator being called when two actors are of the same type (e.g. when lhs and rhs are phoenix values). In these cases, a *is* assigned to *b*. Thus, for values, the contents are copied. Ditto for copy construction of course.
Oops, I meant b is assigned to a of course :-P
Seems like i don't stand a chance. I was trying to find a use case where you might want the lazy version of the assignment ... couldn't find one. Added the operator=(actor const&) to phoenix 3.
Thanks for the hint.
But here's where it gets tricky: Even a slight change in type will make it lazy. Consider a: value<int> b: value<short>. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

Joel de Guzman wrote: <snip>
> > Actor a; > Actor b = ...; > a = b; // no-op?
It should copy the contents. Thomas?
Not really. It needs to create the assign actor (that means the expression template representing the assignment operation. It is neither a no-op nor is the assignment "executed". Remember the stuff about phoenix being lazy ;)?
No! That's not the case here. There *is* still the immediate assignment operator being called when two actors are of the same type (e.g. when lhs and rhs are phoenix values). In these cases, a *is* assigned to *b*. Thus, for values, the contents are copied. Ditto for copy construction of course. <snip>
Seems like i don't stand a chance. I was trying to find a use case where you might want the lazy version of the assignment ... couldn't find one. Added the operator=(actor const&) to phoenix 3.
Thanks for the hint.
But here's where it gets tricky: Even a slight change in type will make it lazy. Consider a: value<int> b: value<short>.
Ok ... we can't detect this (probably) in any sane manner. And it is not needed to fulfill the Assignable requirement.

On 1/22/2011 10:13 PM, Thomas Heller wrote:
Joel de Guzman wrote:
On 1/22/2011 9:02 PM, Joel de Guzman wrote:
On 1/22/2011 8:17 PM, Thomas Heller wrote:
Joel de Guzman wrote:
On 1/21/2011 8:39 PM, Michel MORIN wrote:
I have another question about Phoenix 3. Is the copy assignment of Actors no-op, or does it really copy the contents?
Actor a; Actor b = ...; a = b; // no-op?
It should copy the contents. Thomas?
Not really. It needs to create the assign actor (that means the expression template representing the assignment operation. It is neither a no-op nor is the assignment "executed". Remember the stuff about phoenix being lazy ;)?
No! That's not the case here. There *is* still the immediate assignment operator being called when two actors are of the same type (e.g. when lhs and rhs are phoenix values). In these cases, a *is* assigned to *b*. Thus, for values, the contents are copied. Ditto for copy construction of course.
Oops, I meant b is assigned to a of course :-P
Seems like i don't stand a chance. I was trying to find a use case where you might want the lazy version of the assignment ... couldn't find one. Added the operator=(actor const&) to phoenix 3.
Thanks for the hint.
BTW, don't forget to add the non-const overload as well. Proto is pretty finicky about this: operator=(actor& rhs) I know.. I've been there (with Spirit rules). If you don't do that, and your rhs is non-const, you'll get a lazy treatment! LOL :P Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

Hi Thomas, Thomas Heller wrote:
Michel, did you compile and run the code? It works like a charm.
Yes, I ran the code. The assertion failed on gcc 4.4, 4.5, 4.6. Could you please check that BOOST_ASSERT is not disabled? When I ran other similar codes, whether the assertion succeeds or not was very unstable (so I asked this question!), although the assertion in the attached code always failed. The behavior got changed before and after incrementing the iterator, and it seemed that compiler optimization also affected the results... Regards, Michel

Michel MORIN wrote:
Hi Thomas,
Thomas Heller wrote:
Michel, did you compile and run the code? It works like a charm.
Yes, I ran the code. The assertion failed on gcc 4.4, 4.5, 4.6. Could you please check that BOOST_ASSERT is not disabled?
Sorry for the confusion. It seems to produce right results clang.
When I ran other similar codes, whether the assertion succeeds or not was very unstable (so I asked this question!), although the assertion in the attached code always failed. The behavior got changed before and after incrementing the iterator, and it seemed that compiler optimization also affected the results...
Ok. I just committed the fix. Phoenix actors (in V3) are now Assignable.
Regards, Michel _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Joel de Guzman wrote:
On 1/21/2011 8:39 PM, Michel MORIN wrote:
(In Phoenix 2, boost::phoenix::value<T> is not default constructible, and so the above iterator does not satisfy the ForwardIterator requirements too.)
That is true. phoenix::value is not default constructible. While it is easy to make it so, I'm not sure it is a good idea as it will potentially break existing code which holds values that are not default constructible. I'd argue that phoenix3 should follow.
OTOH, I think a good compromise is to allow default construction on primitive types and POD structs. That will solve your problem. I can do that now with phoenix-2.
That makes my life easier :) May I ask you to do that? Thanks, Joel. Regards, Michel

On 1/23/2011 12:40 AM, Michel MORIN wrote:
Joel de Guzman wrote:
On 1/21/2011 8:39 PM, Michel MORIN wrote:
(In Phoenix 2, boost::phoenix::value<T> is not default constructible, and so the above iterator does not satisfy the ForwardIterator requirements too.)
That is true. phoenix::value is not default constructible. While it is easy to make it so, I'm not sure it is a good idea as it will potentially break existing code which holds values that are not default constructible. I'd argue that phoenix3 should follow.
OTOH, I think a good compromise is to allow default construction on primitive types and POD structs. That will solve your problem. I can do that now with phoenix-2.
That makes my life easier :) May I ask you to do that? Thanks, Joel.
Done. I added unconstrained default construction anyway as it seems to be the way forward to V3. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

Hi Joel, Joel de Guzman wrote:
OTOH, I think a good compromise is to allow default construction on primitive types and POD structs. That will solve your problem. I can do that now with phoenix-2.
That makes my life easier :) May I ask you to do that? Thanks, Joel.
Done. I added unconstrained default construction anyway as it seems to be the way forward to V3.
Thank you for doing this! I've tried to run the code with Phoenix 2, but got some errors. boost/spirit/home/phoenix/core/actor.hpp:91: error: 'Base' has not been declared boost/spirit/home/phoenix/core/actor.hpp:97: error: 'Base' has not been declared You mean 'Eval' here? After changing 'Base' to 'Eval', the code runs as my intention :) Regards, Michel

On 1/23/2011 1:36 PM, Michel MORIN wrote:
Hi Joel,
Joel de Guzman wrote:
OTOH, I think a good compromise is to allow default construction on primitive types and POD structs. That will solve your problem. I can do that now with phoenix-2.
That makes my life easier :) May I ask you to do that? Thanks, Joel.
Done. I added unconstrained default construction anyway as it seems to be the way forward to V3.
Thank you for doing this! I've tried to run the code with Phoenix 2, but got some errors.
boost/spirit/home/phoenix/core/actor.hpp:91: error: 'Base' has not been declared boost/spirit/home/phoenix/core/actor.hpp:97: error: 'Base' has not been declared
You mean 'Eval' here? After changing 'Base' to 'Eval', the code runs as my intention :)
That is correct. Sorry about that. Fixed. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
participants (3)
-
Joel de Guzman
-
Michel MORIN
-
Thomas Heller