mirror of
https://github.com/boostorg/fusion.git
synced 2025-07-21 16:22:45 +02:00
zip to shortest of collection of variable length seqs@
[SVN r35517]
This commit is contained in:
@ -9,12 +9,17 @@
|
||||
#if !defined(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/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/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/min.hpp>
|
||||
|
||||
namespace boost { namespace fusion {
|
||||
|
||||
@ -22,29 +27,30 @@ namespace boost { namespace fusion {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct poly_end
|
||||
template<typename M>
|
||||
struct endpoints
|
||||
{
|
||||
template<typename SeqRef>
|
||||
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>
|
||||
typename result<Seq&>::type
|
||||
operator()(Seq& seq) const
|
||||
{
|
||||
return fusion::end(seq);
|
||||
return fusion::advance<M>(fusion::begin(seq));
|
||||
}
|
||||
|
||||
template<typename Seq>
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
||||
static type
|
||||
call(Sequence& sequence)
|
||||
{
|
||||
return type(
|
||||
fusion::transform(sequence.sequences_, detail::poly_end()));
|
||||
fusion::transform(sequence.sequences_, detail::endpoints<typename Sequence::size>()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}}
|
||||
|
@ -9,38 +9,9 @@
|
||||
#if !defined(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 {
|
||||
|
||||
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
|
||||
{
|
||||
@ -55,7 +26,7 @@ namespace boost { namespace fusion {
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: detail::zip_view_size<Sequence>::type
|
||||
: Sequence::size
|
||||
{};
|
||||
};
|
||||
}
|
||||
|
@ -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>
|
||||
{};
|
||||
|
||||
template<typename Sequences>
|
||||
struct all_same_size_impl
|
||||
struct seq_ref_size
|
||||
{
|
||||
typedef mpl::transform_view<Sequences, fusion::result_of::size<remove_reference<mpl::_> > > sizes;
|
||||
typedef typename mpl::at_c<sizes, 0>::type first_size;
|
||||
typedef mpl::iterator_range<
|
||||
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;
|
||||
template<typename Seq>
|
||||
struct result
|
||||
: result_of::size<typename remove_reference<Seq>::type>
|
||||
{};
|
||||
};
|
||||
|
||||
struct poly_min
|
||||
{
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct result
|
||||
: mpl::min<Lhs, Rhs>
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Sequences>
|
||||
struct all_same_size
|
||||
: all_same_size_impl<Sequences>::type
|
||||
{};
|
||||
struct min_size
|
||||
{
|
||||
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;
|
||||
@ -69,12 +75,12 @@ namespace boost { namespace fusion {
|
||||
struct zip_view : sequence_base< zip_view<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 zip_view_tag fusion_tag;
|
||||
typedef fusion_sequence_tag tag; // this gets picked up by MPL
|
||||
typedef mpl::true_ is_view;
|
||||
typedef typename fusion::result_of::as_vector<Sequences>::type sequences;
|
||||
typedef typename detail::min_size<Sequences>::type size;
|
||||
|
||||
zip_view(
|
||||
const Sequences& seqs)
|
||||
|
Reference in New Issue
Block a user