[Fusion] fusion::traits::is_sequence <-> mpl::is_sequence?
Hi, If I am trying to make a fusion sequence mpl compatible, do I need to specialize mpl::is_sequence as well? I had expected that the following should be true: BOOST_MPL_ASSERT(( fusion::traits::is_sequence<myseq> )); BOOST_MPL_ASSERT(( mpl::is_sequence<myseq> )); But the compilation fails on the second line. I've also defined begin using the fusion extension mechanism for this sequence. Thanks! Sohail
Hi, Sohail Somani wrote:
If I am trying to make a fusion sequence mpl compatible, do I need to specialize mpl::is_sequence as well?
No. mpl::is_sequence just checks whether mpl::begin returns mpl::void_ (in this case it's not an MPL Sequence).
I had expected that the following should be true:
BOOST_MPL_ASSERT(( fusion::traits::is_sequence<myseq> )); BOOST_MPL_ASSERT(( mpl::is_sequence<myseq> ));
It is - once you bring the part of MPL support in that enables you to use MPL Tag Dispatched Metafunctions on Fusion sequences: #include <boost/fusion/sequence/intrinsic/mpl.hpp>
But the compilation fails on the second line.
That breakage should be intentional to make sure that mpl::is_sequence won't start lying, otherwise a Fusion Sequence can be both an MPL Sequence and not an MPL Sequence in the same program (see attached code). Note that I fixed that problem very recently, so maybe your version of mpl::is_sequence is still just lying. For a recent CVS snapshot, Fusion sequences are always MPL Sequences. They can be incompletely defined, however (and in this case your compiler hopefully tells you that begin_impl<fusion_sequence_tag> is an incomplete type). Regards, Tobias P.S.: The attached code will intentionally fail to compile if your snapshot of Fusion is up to date. #include <boost/mpl/is_sequence.hpp> #include <boost/fusion/sequence/container/vector.hpp> #include <iostream> bool is_seq_tu1() { return boost::mpl::is_sequence< boost::fusion::vector<int> >::value; } bool is_seq_tu2(); int main() { if (is_seq_tu1() != is_seq_tu2()) { std::cout << "ODR violation missed by the linker" << std::endl; return 1; } else { std::cout << "Fine." << std::endl; return 0; } } #include <boost/mpl/is_sequence.hpp> #include <boost/fusion/sequence/container/vector.hpp> #include <boost/fusion/sequence/intrinsic/mpl.hpp> bool is_seq_tu2() { return boost::mpl::is_sequence< boost::fusion::vector<int> >::value; }
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Tobias Schwinger Sohail Somani wrote:
If I am trying to make a fusion sequence mpl compatible, do I need to specialize mpl::is_sequence as well?
No. mpl::is_sequence just checks whether mpl::begin returns mpl::void_ (in this case it's not an MPL Sequence). -------------- Thank you for your reply. If I do what you suggest (include intrinsic/mpl), it still doesn't compile. I checked fusion::result_of::begin<myseq>::type was correct but mpl::begin<type>::type is still void_. I'm sure I'm doing something wrong, but I can't figure out what! The example you attached did fail to compile with an incomplete type message. Thanks again, Sohail
Sohail Somani wrote:
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Tobias Schwinger
Sohail Somani wrote:
If I am trying to make a fusion sequence mpl compatible, do I need to specialize mpl::is_sequence as well?
No. mpl::is_sequence just checks whether mpl::begin returns mpl::void_ (in this case it's not an MPL Sequence).
--------------
Thank you for your reply. If I do what you suggest (include intrinsic/mpl), it still doesn't compile. I checked fusion::result_of::begin<myseq>::type was correct but mpl::begin<type>::type is still void_. I'm sure I'm doing something wrong, but I can't figure out what!
I guess you have to make sure that mpl::sequence_tag returns fusion::fusion_sequence_tag. An easy way to do it is to add a 'tag' type member. struct my_seq { typedef fusion::fusion_sequence_tag tag; // ... Regards, Tobias
Tobias Schwinger wrote:
Sohail Somani wrote:
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Tobias Schwinger
Sohail Somani wrote:
If I am trying to make a fusion sequence mpl compatible, do I need to specialize mpl::is_sequence as well?
No. mpl::is_sequence just checks whether mpl::begin returns mpl::void_ (in this case it's not an MPL Sequence).
--------------
Thank you for your reply. If I do what you suggest (include intrinsic/mpl), it still doesn't compile. I checked fusion::result_of::begin<myseq>::type was correct but mpl::begin<type>::type is still void_. I'm sure I'm doing something wrong, but I can't figure out what!
I guess you have to make sure that mpl::sequence_tag returns fusion::fusion_sequence_tag. An easy way to do it is to add a 'tag' type member.
struct my_seq { typedef fusion::fusion_sequence_tag tag; // ...
Sidenote: Although all Sequences provided by Fusion are MPL Sequences (because of that 'tag' type member), it is possible to /write/ a Fusion Sequence that is not an MPL Sequence by omitting that type member... Regards, Tobias
On 1/19/07, Tobias Schwinger <tschwinger@isonews2.com> wrote:
Sidenote: Although all Sequences provided by Fusion are MPL Sequences (because of that 'tag' type member), it is possible to /write/ a Fusion Sequence that is not an MPL Sequence by omitting that type member...
Is there / should there be a base class that fusion sequences should derive from to ensure some of the fundamentals are there? Tony
Gottlob Frege wrote:
On 1/19/07, *Tobias Schwinger* <tschwinger@isonews2.com <mailto:tschwinger@isonews2.com>> wrote:
Sidenote: Although all Sequences provided by Fusion are MPL Sequences (because of that 'tag' type member), it is possible to /write/ a Fusion Sequence that is not an MPL Sequence by omitting that type member...
Is there / should there be a base class that fusion sequences should derive from to ensure some of the fundamentals are there?
Yes, there is. But it's provided only to make life easier. It is not required. The class is sequence_facade (in fusion/sequence/). It is a fairly recent addition, however, and is not documented nor tested yet. I believe it is not yet ready for prime time, unlike its counterpart iterator_facade which is already deployed to adapt a couple of non-native iterators (e.g. std::pair, boost:: array, boost::tuple, etc.). If anyone wants to proceed with its development, email me privately. It's a fairly simple adapter class. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
Tobias Schwinger wrote:
I guess you have to make sure that mpl::sequence_tag returns fusion::fusion_sequence_tag. An easy way to do it is to add a 'tag' type member.
struct my_seq { typedef fusion::fusion_sequence_tag tag; // ...
Sidenote: Although all Sequences provided by Fusion are MPL Sequences (because of that 'tag' type member), it is possible to /write/ a Fusion Sequence that is not an MPL Sequence by omitting that type member...
That supports my quick theories. For Sohail, who's doing a non-intrusive adaptation, he'll need to specialize the mpl::sequence_tag. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Joel de Guzman That supports my quick theories. For Sohail, who's doing a non-intrusive adaptation, he'll need to specialize the mpl::sequence_tag. ------ I think I'll stick with fusion::result_of for now ;)
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Sohail Somani Sent: Sat 1/20/2007 8:48 AM To: boost-users@lists.boost.org; boost-users@lists.boost.org Subject: Re: [Boost-users] [Fusion]fusion::traits::is_sequence<->mpl::is_sequence? -----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Joel de Guzman That supports my quick theories. For Sohail, who's doing a non-intrusive adaptation, he'll need to specialize the mpl::sequence_tag. ------ I think I'll stick with fusion::result_of for now ;) ------ I take that back! I do need some of the mpl algorithms. Anyway, while it may not seem that much (I'm a total metaprogramming noob), my progress is below. I can safely say that there haven't been too many frustrations, which surprises me. If I had the mpl book (/me shakes fist @ chapters.ca), I probably would have gotten through it faster. Now what I need is to use max_element on the argument position of all the placeholders and we're done! template<int NumPlaceholders, typename BindExpression> void count_placeholders(BindExpression) { typedef typename boost::bind_arg_sequence<BindExpression>::type bind_arg_sequence; typedef typename result_of::filter_if < bind_arg_sequence , boost::is_placeholder<mpl::_1> >::type placeholders; BOOST_STATIC_ASSERT(( result_of::size<placeholders>::value == NumPlaceholders)); } void fn_0(){} void fn_1(int){} void fn_2(int,int){} MPL_TEST_CASE() { count_placeholders<0>(boost::bind(&fn_0)); count_placeholders<2>(boost::bind(&fn_2,_1,_2)); }
Sohail Somani wrote:
I think I'll stick with fusion::result_of for now ;)
------
I take that back! I do need some of the mpl algorithms.
I wonder whether you need Fusion at all for this and similar tasks... maybe we just need to make the bind argument list an MPL sequence (not hard once you have the element extraction partial specializations in place) and stick to MPL algorithms.
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Peter Dimov Sent: Sat 1/20/2007 9:42 AM To: boost-users@lists.boost.org Subject: Re: [Boost-users][Fusion]fusion::traits::is_sequence<->mpl::is_sequence? Sohail Somani wrote:
I think I'll stick with fusion::result_of for now ;)
------
I take that back! I do need some of the mpl algorithms.
I wonder whether you need Fusion at all for this and similar tasks... maybe we just need to make the bind argument list an MPL sequence (not hard once you have the element extraction partial specializations in place) and stick to MPL algorithms. ----- In this case, probably. I don't know if there are any issues with using the fusion->mpl dispatch though. It is possible for someone to use fusion sequences + _bi::value to do things at runtime as well though you typically wouldn't do anything with placeholders. Not knowing enough about mpl, I don't know if it is possible with mpl as well. Sohail
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Peter Dimov Sent: Sat 1/20/2007 9:42 AM To: boost-users@lists.boost.org Subject: Re: [Boost-users][Fusion]fusion::traits::is_sequence<->mpl::is_sequence? Sohail Somani wrote:
I think I'll stick with fusion::result_of for now ;)
------
I take that back! I do need some of the mpl algorithms.
I wonder whether you need Fusion at all for this and similar tasks... maybe we just need to make the bind argument list an MPL sequence (not hard once you have the element extraction partial specializations in place) and stick to MPL algorithms. ----- I should add that the partial specializations were in no way the hard part :) Atleast for me!
Peter Dimov wrote:
Sohail Somani wrote:
I think I'll stick with fusion::result_of for now ;)
------
I take that back! I do need some of the mpl algorithms.
I wonder whether you need Fusion at all for this and similar tasks... maybe we just need to make the bind argument list an MPL sequence (not hard once you have the element extraction partial specializations in place) and stick to MPL algorithms.
If it was a solution for this case alone, yes, however: 1) The level of difficulty is at least the same 2) You can do a lot more with fusion than with mpl alone -> e.g. at one point, you'll definitely want to get the actual values and manipulate them from your algorithms. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Joel de Guzman If it was a solution for this case alone, yes, however: 1) The level of difficulty is at least the same 2) You can do a lot more with fusion than with mpl alone -> e.g. at one point, you'll definitely want to get the actual values and manipulate them from your algorithms. ---------- This is just it. One can imagine specializing for the type of binded function and/or perhaps logging all the arguments of a certain type. Sohail
Sohail Somani wrote:
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Joel de Guzman
If it was a solution for this case alone, yes, however: 1) The level of difficulty is at least the same 2) You can do a lot more with fusion than with mpl alone -> e.g. at one point, you'll definitely want to get the actual values and manipulate them from your algorithms.
----------
This is just it. One can imagine specializing for the type of binded function and/or perhaps logging all the arguments of a certain type.
Not to mention my ultimate objective: Full and total unification of bind/lambda/phoenix. Fusion is the perfect infrastructure for that to finally happen. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Joel de Guzman
This is just it. One can imagine specializing for the type of binded function and/or perhaps logging all the arguments of a certain type.
Not to mention my ultimate objective: Full and total unification of bind/lambda/phoenix. Fusion is the perfect infrastructure for that to finally happen. ---- Don't forget function. I'm sure that could benefit as well. PS: Now that you've told everyone your plan to take over the world, you have to change it.
Sohail Somani wrote:
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Tobias Schwinger
Sohail Somani wrote:
If I am trying to make a fusion sequence mpl compatible, do I need to specialize mpl::is_sequence as well?
No. mpl::is_sequence just checks whether mpl::begin returns mpl::void_ (in this case it's not an MPL Sequence).
--------------
Thank you for your reply. If I do what you suggest (include intrinsic/mpl), it still doesn't compile. I checked fusion::result_of::begin<myseq>::type was correct but mpl::begin<type>::type is still void_. I'm sure I'm doing something wrong, but I can't figure out what!
The example you attached did fail to compile with an incomplete type message.
The semantics of mpl::is_sequence is: typedef not_< is_same< begin<T>::type,void_ > >::type c; That would be true for adapted fusion sequences if you include at least: #include <boost/fusion/sequence/intrinsic/mpl/begin.hpp> or, as Tobias suggested: #include <boost/fusion/sequence/intrinsic/mpl.hpp> which brings in all of them. <----------------> I'm not entirely sure, but my analysis is that: I think that the problem in your case is that mpl::begin<T> relies on proper mpl tag dispatching through mpl::sequence_tag<T>. For native fusion sequences, this would do the right thing. For adapted sequences, this is most probably not doing the right thing. Try to see if specializing that to return fusion::fusion_sequence_tag will solve the problem. If it does, then we'll think of a way to accommodate that in the equation. The basic question here is: should an adapted fusion sequence automatically be an mpl::sequence. The answer, as of now is "no". That can easily change, however, since fusion already has the right facilities to make it so. Yet, this issue needs more deliberation and thought, but my initial reaction is that the answer should be "yes". Having said that, I should point out that there should also be a way to disable this automatic fusion->mpl adaptation. There are cases where the fusion mpl intrinsics give the wrong (or inefficient) behavior. Eric (Niebler) pointed me to one such case (I'm CC'ing Eric). I think now that the solution to this issue is to (again) specialize mpl::sequence_tag<T> to not return fusion::fusion_sequence_tag and do the dispatching of mpl intrinsics manually. Again, this is just my quick analysis. I haven't done any code experiments to support my theories. Perhaps others are wiser than I am or have more time to look into this can prove me wrong. Nevertheless, I'll note this and add it in my todo list. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
-----Original Message----- From: boost-users-bounces@lists.boost.org on behalf of Joel de Guzman Try to see if specializing that to return fusion::fusion_sequence_tag will solve the problem. If it does, then we'll think of a way to accommodate that in the equation. ---------- That did solve the problem, but I decided to forgo mpl for now.
participants (5)
-
Gottlob Frege
-
Joel de Guzman
-
Peter Dimov
-
Sohail Somani
-
Tobias Schwinger