forked from boostorg/fusion
fusion find_if loop unrolling and use of advance optimization for random traversal sequences
[SVN r37856]
This commit is contained in:
@ -1,5 +1,6 @@
|
|||||||
/*=============================================================================
|
/*=============================================================================
|
||||||
Copyright (c) 2001-2006 Joel de Guzman
|
Copyright (c) 2001-2006 Joel de Guzman
|
||||||
|
Copyright (c) 2007 Dan Marsden
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -16,18 +17,22 @@
|
|||||||
#include <boost/fusion/iterator/equal_to.hpp>
|
#include <boost/fusion/iterator/equal_to.hpp>
|
||||||
#include <boost/fusion/iterator/next.hpp>
|
#include <boost/fusion/iterator/next.hpp>
|
||||||
#include <boost/fusion/sequence/intrinsic/begin.hpp>
|
#include <boost/fusion/sequence/intrinsic/begin.hpp>
|
||||||
|
#include <boost/fusion/iterator/advance.hpp>
|
||||||
|
#include <boost/fusion/iterator/distance.hpp>
|
||||||
|
#include <boost/fusion/support/category_of.hpp>
|
||||||
|
#include <boost/mpl/eval_if.hpp>
|
||||||
|
#include <boost/mpl/identity.hpp>
|
||||||
|
|
||||||
namespace boost { namespace fusion { namespace detail
|
namespace boost { namespace fusion {
|
||||||
|
struct random_access_traversal_tag;
|
||||||
|
namespace detail
|
||||||
{
|
{
|
||||||
template <typename Iterator, typename Pred>
|
template <typename Iterator, typename Pred>
|
||||||
struct apply_filter
|
struct apply_filter
|
||||||
{
|
{
|
||||||
typedef typename
|
typedef typename mpl::apply1<
|
||||||
mpl::apply1<
|
Pred, typename result_of::value_of<Iterator>::type>::type type;
|
||||||
Pred
|
BOOST_STATIC_CONSTANT(int, value = type::value);
|
||||||
, typename result_of::value_of<Iterator>::type
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename First, typename Last, typename Pred>
|
template <typename First, typename Last, typename Pred>
|
||||||
@ -60,37 +65,166 @@ namespace boost { namespace fusion { namespace detail
|
|||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename First, typename Last,
|
||||||
|
typename Pred, bool>
|
||||||
|
struct choose_find_if;
|
||||||
|
|
||||||
|
template<typename First, typename Last, typename Pred>
|
||||||
|
struct choose_find_if<First, Last, Pred, false>
|
||||||
|
: main_find_if<First, Last, Pred>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename Iter, typename Pred, int n, int unrolling>
|
||||||
|
struct unroll_again;
|
||||||
|
|
||||||
|
template <typename Iter, typename Pred, int offset>
|
||||||
|
struct apply_offset_filter
|
||||||
|
{
|
||||||
|
typedef typename result_of::advance_c<Iter, offset>::type Shifted;
|
||||||
|
typedef typename
|
||||||
|
mpl::apply1<
|
||||||
|
Pred
|
||||||
|
, typename result_of::value_of<Shifted>::type
|
||||||
|
>::type
|
||||||
|
type;
|
||||||
|
BOOST_STATIC_CONSTANT(int, value = type::value);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iter, typename Pred, int n>
|
||||||
|
struct unrolled_find_if
|
||||||
|
{
|
||||||
|
typedef typename mpl::eval_if<
|
||||||
|
apply_filter<Iter, Pred>,
|
||||||
|
mpl::identity<Iter>,
|
||||||
|
mpl::eval_if<
|
||||||
|
apply_offset_filter<Iter, Pred, 1>,
|
||||||
|
result_of::advance_c<Iter, 1>,
|
||||||
|
mpl::eval_if<
|
||||||
|
apply_offset_filter<Iter, Pred, 2>,
|
||||||
|
result_of::advance_c<Iter, 2>,
|
||||||
|
mpl::eval_if<
|
||||||
|
apply_offset_filter<Iter, Pred, 3>,
|
||||||
|
result_of::advance_c<Iter, 3>,
|
||||||
|
unroll_again<
|
||||||
|
Iter,
|
||||||
|
Pred,
|
||||||
|
n,
|
||||||
|
4> > > > >::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iter, typename Pred>
|
||||||
|
struct unrolled_find_if<Iter, Pred, 3>
|
||||||
|
{
|
||||||
|
typedef typename mpl::eval_if<
|
||||||
|
apply_filter<Iter, Pred>,
|
||||||
|
mpl::identity<Iter>,
|
||||||
|
mpl::eval_if<
|
||||||
|
apply_offset_filter<Iter, Pred, 1>,
|
||||||
|
result_of::advance_c<Iter, 1>,
|
||||||
|
mpl::eval_if<
|
||||||
|
apply_offset_filter<Iter, Pred, 2>,
|
||||||
|
result_of::advance_c<Iter, 2>,
|
||||||
|
result_of::advance_c<Iter, 3> > > >::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iter, typename Pred>
|
||||||
|
struct unrolled_find_if<Iter, Pred, 2>
|
||||||
|
{
|
||||||
|
typedef typename mpl::eval_if<
|
||||||
|
apply_filter<Iter, Pred>,
|
||||||
|
mpl::identity<Iter>,
|
||||||
|
mpl::eval_if<
|
||||||
|
apply_offset_filter<Iter, Pred, 1>,
|
||||||
|
result_of::advance_c<Iter, 1>,
|
||||||
|
result_of::advance_c<Iter, 2> > >::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iter, typename Pred>
|
||||||
|
struct unrolled_find_if<Iter, Pred, 1>
|
||||||
|
{
|
||||||
|
typedef typename mpl::eval_if<
|
||||||
|
apply_filter<Iter, Pred>,
|
||||||
|
mpl::identity<Iter>,
|
||||||
|
result_of::advance_c<Iter, 1> >::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iter, typename Pred, int n, int unrolling>
|
||||||
|
struct unroll_again
|
||||||
|
{
|
||||||
|
typedef typename unrolled_find_if<
|
||||||
|
typename result_of::advance_c<Iter, unrolling>::type,
|
||||||
|
Pred,
|
||||||
|
n-unrolling>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iter, typename Pred>
|
||||||
|
struct unrolled_find_if<Iter, Pred, 0>
|
||||||
|
{
|
||||||
|
typedef Iter type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename First, typename Last, typename Pred>
|
||||||
|
struct choose_find_if<First, Last, Pred, true>
|
||||||
|
{
|
||||||
|
typedef typename result_of::distance<First, Last>::type N;
|
||||||
|
typedef typename unrolled_find_if<First, Pred, N::value>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename First, typename Last, typename Pred>
|
template <typename First, typename Last, typename Pred>
|
||||||
struct static_find_if
|
struct static_find_if
|
||||||
{
|
{
|
||||||
typedef typename
|
typedef typename
|
||||||
main_find_if<
|
choose_find_if<
|
||||||
First
|
First
|
||||||
, Last
|
, Last
|
||||||
, typename mpl::lambda<Pred>::type
|
, typename mpl::lambda<Pred>::type
|
||||||
|
, is_base_of<random_access_traversal_tag, typename traits::category_of<First>::type>::value
|
||||||
>::type
|
>::type
|
||||||
type;
|
type;
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
static type
|
static type
|
||||||
call(Iterator const& iter, mpl::true_)
|
recursive_call(Iterator const& iter, mpl::true_)
|
||||||
{
|
{
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
static type
|
static type
|
||||||
call(Iterator const& iter, mpl::false_)
|
recursive_call(Iterator const& iter, mpl::false_)
|
||||||
{
|
{
|
||||||
return call(fusion::next(iter));
|
return recursive_call(fusion::next(iter));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
static type
|
||||||
|
recursive_call(Iterator const& iter)
|
||||||
|
{
|
||||||
|
typedef result_of::equal_to<Iterator, type> found;
|
||||||
|
return recursive_call(iter, found());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator, typename Tag>
|
||||||
|
static type
|
||||||
|
choose_call(Iterator const& iter, Tag)
|
||||||
|
{
|
||||||
|
return recursive_call(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
static type
|
||||||
|
choose_call(Iterator const& iter, random_access_traversal_tag)
|
||||||
|
{
|
||||||
|
typedef typename result_of::distance<Iterator, type>::type N;
|
||||||
|
return fusion::advance<N>(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
static type
|
static type
|
||||||
call(Iterator const& iter)
|
call(Iterator const& iter)
|
||||||
{
|
{
|
||||||
typedef result_of::equal_to<Iterator, type> found;
|
return choose_call(iter, typename traits::category_of<Iterator>::type());
|
||||||
return call(iter, found());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user