fusion find_if loop unrolling and use of advance optimization for random traversal sequences

[SVN r37856]
This commit is contained in:
Dan Marsden
2007-06-01 22:47:49 +00:00
parent a4268d3cf9
commit d2f019514e

View File

@ -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());
} }
}; };