[Fusion] How to join more than two sequences
Hi All I've noticed the function "join" in the boost fusion library. However, it only joins two sequences. Was wondering whether there is (or can be easily made) a function that joins any number of sequences. For example: new_join(make_vector(1,2,3), make_vector(4,5), make_vector(6)) -> is the sequence 1,2,3,4,5,6 AND/OR (pass parameters in a sequence) new_join(make_vector(make_ vector(1,2,3), make_vector(4,5), make_vector(6))) -> is the sequence 1,2,3,4,5,6 I'd prefer both the first and second versions, but even one version would be ok. Thanks, Clinton
On 09/21/10 03:01, Clinton Mead wrote:
Hi All
I've noticed the function "join" in the boost fusion library. However, it only joins two sequences. Was wondering whether there is (or can be easily made) a function that joins any number of sequences. [snip] Couldn't fold be used to join any number of sequences?
-Larry
On 9/21/10 4:01 PM, Clinton Mead wrote:
Hi All
I've noticed the function "join" in the boost fusion library. However, it only joins two sequences. Was wondering whether there is (or can be easily made) a function that joins any number of sequences.
For example:
new_join(make_vector(1,2,3), make_vector(4,5), make_vector(6)) -> is the sequence 1,2,3,4,5,6
AND/OR (pass parameters in a sequence)
new_join(make_vector(make_ vector(1,2,3), make_vector(4,5), make_vector(6))) -> is the sequence 1,2,3,4,5,6
I'd prefer both the first and second versions, but even one version would be ok.
join(a, join(b, c)) Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
On Wed, Sep 22, 2010 at 1:22 AM, Larry Evans <cppljevans@suddenlink.net>wrote:
Couldn't fold be used to join any number of sequences?
-Larry
Hi Larry Something like? ? join_all(seq) { return fold(seq, vector<>(), join<?, ?>()); } Could you fill in the question marks?
On 09/21/10 19:31, Clinton Mead wrote:
On Wed, Sep 22, 2010 at 1:22 AM, Larry Evans <cppljevans@suddenlink.net <mailto:cppljevans@suddenlink.net>> wrote:
Couldn't fold be used to join any number of sequences?
-Larry
Hi Larry
Something like?
? join_all(seq) { return fold(seq, vector<>(), join<?, ?>()); }
Could you fill in the question marks?
To be honest, I really was only guessing fold would work. I've never actually used it do to something like this; hence, I'm not the best person to help you :( However, I'm wondering why: http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/algorithm/i... doesn't help oneself 'fill in the question marks'? -Larry
On 09/22/10 07:33, Larry Evans wrote:
On 09/21/10 19:31, Clinton Mead wrote:
On Wed, Sep 22, 2010 at 1:22 AM, Larry Evans <cppljevans@suddenlink.net <mailto:cppljevans@suddenlink.net>> wrote:
Couldn't fold be used to join any number of sequences?
-Larry
Hi Larry
Something like?
? join_all(seq) { return fold(seq, vector<>(), join<?, ?>()); }
Could you fill in the question marks?
To be honest, I really was only guessing fold would work. I've never actually used it do to something like this; hence, I'm not the best person to help you :(
However, I'm wondering why:
http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/algorithm/i...
doesn't help oneself 'fill in the question marks'?
The attachment shows my try; however, it fails to compile with the error: fold_join.cpp:87:47: instantiated from here /home/evansl/prog_dev/boost-svn/ro/trunk/boost/fusion/support/detail/category_of.hpp:15:38: error: 'const boost::fusion::joint_view<const boost::fusion::vector<>&, boost::fusion::vector<tu<int>, tu<char>, tu<double> >&>&' is not a class, struct, or union type Anyone have an idea what's wrong? -Larry
On 09/22/10 10:38, Larry Evans wrote: [snip]
The attachment shows my try; however, it fails to compile with the error:
fold_join.cpp:87:47: instantiated from here /home/evansl/prog_dev/boost-svn/ro/trunk/boost/fusion/support/detail/category_of.hpp:15:38: error: 'const boost::fusion::joint_view<const boost::fusion::vector<>&, boost::fusion::vector<tu<int>, tu<char>, tu<double> >&>&' is not a class, struct, or union type
Anyone have an idea what's wrong?
Using Christopher Schmidt's variadic fusion: http://svn.boost.org/svn/boost/sandbox/SOC/2009/fusion/ solves problem. With the attached and variadic fusion, output is: v1=(tu<1>(100) tu<1>(b) tu<1>(300.1)) v2=(tu<2>(100) tu<2>(b) tu<2>(300.1)) v3=(tu<3>(100) tu<3>(b) tu<3>(300.1)) fold(vv,state0,join_ftor())=(tu<1>(100) tu<1>(b) tu<1>(300.1) tu<2>(100) tu<2>(b) tu<2>(300.1) tu<3>(100) tu<3>(b) tu<3>(300.1))
On 09/29/10 11:45, Larry Evans wrote: [snip]
Using Christopher Schmidt's variadic fusion: http://svn.boost.org/svn/boost/sandbox/SOC/2009/fusion/ solves problem. Submitted bug:
Larry Evans schrieb:
On 09/29/10 11:45, Larry Evans wrote: [snip]
Using Christopher Schmidt's variadic fusion: http://svn.boost.org/svn/boost/sandbox/SOC/2009/fusion/ solves problem. Submitted bug:
I am not sure whether this is an actual bug. Your problem boils down to fusion::joint_view not supporting reference template type arguments. My port changed that, but that's an entirely new feature that was introduced to differentiate semantics for l- and rvalue sequences. All inbuilt views of Fusion implicitly use references to underlying *non-view* sequences. For example, in typedef fusion::vector<...> t1; typedef fusion::transform_view<t1, ...> t2; typedef fusion::joint_view<t1, t2> t3; t2 stores a reference to an instance of t1 and t3 stores a reference to an instance to t1, but stores the underlying instance of t2 by value. You can fix your example by removing the references to Lhs and Rhs before passing down to Fusion: namespace fold_join{struct join_ftor { template<typename Sig> struct result; template<typename Self, typename Lhs, typename Rhs> struct result<Self(Lhs,Rhs)> { typedef boost::fusion::joint_view< typename boost::remove_reference< Lhs >::type, typename boost::remove_reference< Rhs >::type > type; }; template<typename Lhs, typename Rhs> typename result<join_ftor const(Lhs&,Rhs&)>::type operator()(Lhs& lhs, Rhs& rhs)const { return boost::fusion::joint_view< Lhs, Rhs >(lhs,rhs); } };} A few remarks: You cannot use the function(!) fusion::join as it only accepts const-qualified sequences. See https://svn.boost.org/trac/boost/ticket/3954 for more information. The port has this 'fixed'. In your code you should use fusion::joint_view directly. It is definitely not a good idea to specialize boost::result_of with the signature of your functor. You should stick to the official protocol, that is defining a nested type 'result_type' or a nested template type 'result'. You should consider that the functor may be const- and/or even reference-qualified (in c++11) when passed to the result metafunction. See FCD 20.7.6.6 for more information. template<typename LhSequence, typename RhSequence> typename boost::result_of<join_ftor(LhSequence,RhSequence)>::type operator()(LhSequence& lhs, RhSequence& rhs)const is not a good idea as well, as LhSequence and RhSequence in join_ftor(LhSequence,RhSequence) loose cv-qualification. -Christopher
On 10/06/10 10:53, Christopher Schmidt wrote: [snip]
You can fix your example by removing the references to Lhs and Rhs before passing down to Fusion:
namespace fold_join{struct join_ftor { template<typename Sig> struct result;
template<typename Self, typename Lhs, typename Rhs> struct result<Self(Lhs,Rhs)> { typedef boost::fusion::joint_view< typename boost::remove_reference< Lhs >::type, typename boost::remove_reference< Rhs >::type > type; };
template<typename Lhs, typename Rhs> typename result<join_ftor const(Lhs&,Rhs&)>::type operator()(Lhs& lhs, Rhs& rhs)const { return boost::fusion::joint_view< Lhs, Rhs >(lhs,rhs); } };}
Thanks. I made the changes you suggest above; however, it still fails to compile without variadic fusion. The changed source is attached.
A few remarks:
You cannot use the function(!) fusion::join as it only accepts const-qualified sequences. See
https://svn.boost.org/trac/boost/ticket/3954
for more information. The port has this 'fixed'. In your code you should use fusion::joint_view directly.
Thanks.
It is definitely not a good idea to specialize boost::result_of with the signature of your functor. You should stick to the official protocol, that is defining a nested type 'result_type' or a nested template type 'result'.
The fusion html reference mentioned the in source comments after @brief the result_of specialization explain why I thought I had to specialize boost::result_of. IOW, the Table 1.37 here: http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/algorithm/i... lead me to this conclusion. If that's wrong, then maybe the fold.html should provide further clarification.
You should consider that the functor may be const- and/or even reference-qualified (in c++11) when passed to the result metafunction. See FCD 20.7.6.6 for more information.
template<typename LhSequence, typename RhSequence> typename boost::result_of<join_ftor(LhSequence,RhSequence)>::type operator()(LhSequence& lhs, RhSequence& rhs)const
is not a good idea as well, as LhSequence and RhSequence in join_ftor(LhSequence,RhSequence) loose cv-qualification.
-Christopher
Thanks very much for the explanation Christopher. -Larry
Larry Evans schrieb: [snip]
Thanks. I made the changes you suggest above; however, it still fails to compile without variadic fusion. The changed source is attached.
Argh, yes. That's a minor bug in 1.44; the propagation of the const-qualifier of the states in the result metafunction of fold is broken. That's fixed in 1.45 . Replace <boost/fusion/algorithm/iteration/detail/fold.hpp> with https://svn.boost.org/svn/boost/trunk/boost/fusion/algorithm/iteration/detai... and your code should compile fine.
[snip]
Thanks very much for the explanation Christopher.
No problem. -Christopher
On 10/06/10 12:55, Christopher Schmidt wrote: [snip]
Argh, yes. That's a minor bug in 1.44; the propagation of the const-qualifier of the states in the result metafunction of fold is broken. That's fixed in 1.45 . Replace
<boost/fusion/algorithm/iteration/detail/fold.hpp>
with
https://svn.boost.org/svn/boost/trunk/boost/fusion/algorithm/iteration/detai...
and your code should compile fine.
Confirmed. Thanks Christopher. -Larry
join(a, join(b, c))
Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
How would I write a function that takes a #defineable number of arguments for this (or alternatively or in addition, uses c++0x variadic arguments/templates). Could you fill in the gaps? e.g. template <class ARG1, ARG2, ...> ? join_args(?ARG1? a1, ?ARG2? a2, ...> ( return join(a1, join(a2, join(?))); ); AND/OR template <class... ARGS> ? join_args(ARGS&&... args) { ? };
participants (4)
-
Christopher Schmidt
-
Clinton Mead
-
Joel de Guzman
-
Larry Evans