zip to shortest of collection of variable length seqs@

[SVN r35517]
This commit is contained in:
Dan Marsden
2006-10-07 15:43:33 +00:00
parent 7cd89c8d9c
commit 521574b39d
3 changed files with 36 additions and 56 deletions

View File

@ -9,12 +9,17 @@
#if !defined(FUSION_END_IMPL_20060123_2208) #if !defined(FUSION_END_IMPL_20060123_2208)
#define FUSION_END_IMPL_20060123_2208 #define FUSION_END_IMPL_20060123_2208
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/view/zip_view/zip_view_iterator_fwd.hpp> #include <boost/fusion/sequence/view/zip_view/zip_view_iterator_fwd.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/sequence/intrinsic/front.hpp>
#include <boost/fusion/iterator/advance.hpp>
#include <boost/fusion/algorithm/transformation/transform.hpp> #include <boost/fusion/algorithm/transformation/transform.hpp>
#include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_reference.hpp> #include <boost/type_traits/is_reference.hpp>
#include <boost/mpl/assert.hpp> #include <boost/mpl/assert.hpp>
#include <boost/mpl/min.hpp>
namespace boost { namespace fusion { namespace boost { namespace fusion {
@ -22,29 +27,30 @@ namespace boost { namespace fusion {
namespace detail namespace detail
{ {
struct poly_end template<typename M>
struct endpoints
{ {
template<typename SeqRef> template<typename SeqRef>
struct result struct result
: result_of::end<typename remove_reference<SeqRef>::type>
{ {
BOOST_MPL_ASSERT((is_reference<SeqRef>)); typedef typename remove_reference<SeqRef>::type Seq;
typedef typename result_of::begin<Seq>::type begin;
typedef typename result_of::advance<begin, M>::type type;
}; };
template<typename Seq> template<typename Seq>
typename result<Seq&>::type typename result<Seq&>::type
operator()(Seq& seq) const operator()(Seq& seq) const
{ {
return fusion::end(seq); return fusion::advance<M>(fusion::begin(seq));
} }
template<typename Seq> template<typename Seq>
typename result<Seq const&>::type typename result<Seq const&>::type
operator()(Seq const& seq) const operator()(Seq const& seq)
{ {
return fusion::end(seq); return fusion::advance<M>(fusion::begin(seq));
} }
}; };
} }
@ -60,19 +66,16 @@ namespace boost { namespace fusion {
struct apply struct apply
{ {
typedef zip_view_iterator< typedef zip_view_iterator<
typename result_of::transform<typename Sequence::sequences, detail::poly_end>::type, typename result_of::transform<typename Sequence::sequences, detail::endpoints<typename Sequence::size> >::type,
typename Sequence::category> type; typename Sequence::category> type;
static type static type
call(Sequence& sequence) call(Sequence& sequence)
{ {
return type( return type(
fusion::transform(sequence.sequences_, detail::poly_end())); fusion::transform(sequence.sequences_, detail::endpoints<typename Sequence::size>()));
} }
}; };
}; };
} }
}} }}

View File

@ -9,38 +9,9 @@
#if !defined(FUSION_SIZE_IMPL_20060124_0800) #if !defined(FUSION_SIZE_IMPL_20060124_0800)
#define FUSION_SIZE_IMPL_20060124_0800 #define FUSION_SIZE_IMPL_20060124_0800
#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/sequence/intrinsic/value_at.hpp>
#include <boost/fusion/algorithm/query/find_if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace boost { namespace fusion { namespace boost { namespace fusion {
struct zip_view_tag; struct zip_view_tag;
struct random_access_iterator_tag;
namespace detail
{
template<typename Sequence>
struct zip_view_size
{
typedef result_of::find_if<
typename Sequence::sequences,
is_same<traits::category_of<remove_reference<mpl::_> >, random_access_iterator_tag> > finder;
typedef typename remove_reference<typename mpl::eval_if<
result_of::equal_to<typename finder::type, typename result_of::end<typename Sequence::sequences>::type>,
result_of::value_at_c<typename Sequence::sequences, 0>,
result_of::deref<typename finder::type> >::type>::type best_sequence;
typedef typename fusion::result_of::size<best_sequence> type;
};
}
namespace extension namespace extension
{ {
@ -55,7 +26,7 @@ namespace boost { namespace fusion {
{ {
template<typename Sequence> template<typename Sequence>
struct apply struct apply
: detail::zip_view_size<Sequence>::type : Sequence::size
{}; {};
}; };
} }

View File

@ -44,22 +44,28 @@ namespace boost { namespace fusion {
: fusion::result_of::equal_to<typename fusion::result_of::find_if<Sequences, mpl::not_<is_reference<mpl::_> > >::type, typename fusion::result_of::end<Sequences>::type> : fusion::result_of::equal_to<typename fusion::result_of::find_if<Sequences, mpl::not_<is_reference<mpl::_> > >::type, typename fusion::result_of::end<Sequences>::type>
{}; {};
template<typename Sequences> struct seq_ref_size
struct all_same_size_impl
{ {
typedef mpl::transform_view<Sequences, fusion::result_of::size<remove_reference<mpl::_> > > sizes; template<typename Seq>
typedef typename mpl::at_c<sizes, 0>::type first_size; struct result
typedef mpl::iterator_range< : result_of::size<typename remove_reference<Seq>::type>
typename mpl::next<typename mpl::begin<sizes>::type>::type, {};
typename mpl::end<sizes>::type> remainder; };
typedef typename mpl::find_if<remainder, mpl::not_<is_same<mpl::_, first_size> > >::type found_difference;
typedef typename is_same<found_difference, typename mpl::end<remainder>::type>::type type; struct poly_min
{
template<typename Lhs, typename Rhs>
struct result
: mpl::min<Lhs, Rhs>
{};
}; };
template<typename Sequences> template<typename Sequences>
struct all_same_size struct min_size
: all_same_size_impl<Sequences>::type {
{}; typedef typename result_of::transform<Sequences, detail::seq_ref_size>::type sizes;
typedef typename result_of::fold<sizes, typename result_of::front<sizes>::type, detail::poly_min>::type type;
};
} }
struct zip_view_tag; struct zip_view_tag;
@ -69,12 +75,12 @@ namespace boost { namespace fusion {
struct zip_view : sequence_base< zip_view<Sequences> > struct zip_view : sequence_base< zip_view<Sequences> >
{ {
BOOST_MPL_ASSERT((detail::all_references<Sequences>)); BOOST_MPL_ASSERT((detail::all_references<Sequences>));
BOOST_MPL_ASSERT((detail::all_same_size<Sequences>));
typedef typename detail::strictest_traversal<Sequences>::type category; typedef typename detail::strictest_traversal<Sequences>::type category;
typedef zip_view_tag fusion_tag; typedef zip_view_tag fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef mpl::true_ is_view; typedef mpl::true_ is_view;
typedef typename fusion::result_of::as_vector<Sequences>::type sequences; typedef typename fusion::result_of::as_vector<Sequences>::type sequences;
typedef typename detail::min_size<Sequences>::type size;
zip_view( zip_view(
const Sequences& seqs) const Sequences& seqs)