loop unrolling for compile time perf in any, all and none

[SVN r37820]
This commit is contained in:
Dan Marsden
2007-05-30 06:56:32 +00:00
parent da31732ca3
commit a4268d3cf9
6 changed files with 198 additions and 81 deletions

View File

@ -1,15 +1,14 @@
/*============================================================================= /*=============================================================================
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)
==============================================================================*/ ==============================================================================*/
#if !defined(FUSION_ALL_05052005_1238) #if !defined(BOOST_FUSION_ALL_05052005_1238)
#define FUSION_ALL_05052005_1238 #define BOOST_FUSION_ALL_05052005_1238
#include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/algorithm/query/detail/all.hpp> #include <boost/fusion/algorithm/query/detail/all.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion
@ -27,13 +26,7 @@ namespace boost { namespace fusion
inline bool inline bool
all(Sequence const& seq, F f) all(Sequence const& seq, F f)
{ {
return detail::all( return detail::all(seq, f, typename traits::category_of<Sequence>::type());
fusion::begin(seq)
, fusion::end(seq)
, f
, result_of::equal_to<
typename result_of::begin<Sequence>::type
, typename result_of::end<Sequence>::type>());
} }
}} }}

View File

@ -1,6 +1,7 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2005 Eric Niebler Copyright (c) 2005 Eric Niebler
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)
@ -8,9 +9,7 @@
#if !defined(FUSION_ANY_05052005_1230) #if !defined(FUSION_ANY_05052005_1230)
#define FUSION_ANY_05052005_1230 #define FUSION_ANY_05052005_1230
#include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/algorithm/query/detail/any.hpp> #include <boost/fusion/algorithm/query/detail/any.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion
@ -28,13 +27,7 @@ namespace boost { namespace fusion
inline bool inline bool
any(Sequence const& seq, F f) any(Sequence const& seq, F f)
{ {
return detail::any( return detail::any(seq, f, typename traits::category_of<Sequence>::type());
fusion::begin(seq)
, fusion::end(seq)
, f
, result_of::equal_to<
typename result_of::begin<Sequence>::type
, typename result_of::end<Sequence>::type>());
} }
}} }}

View File

@ -1,39 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
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)
==============================================================================*/
#if !defined(FUSION_NONE_07062005_1126)
#define FUSION_NONE_07062005_1126
#include <boost/mpl/bool.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/deref.hpp>
namespace boost { namespace fusion { namespace detail
{
template <typename First, typename Last, typename F>
inline bool
none(First const&, Last const&, F const&, mpl::true_)
{
return true;
}
template <typename First, typename Last, typename F>
inline bool
none(First const& first, Last const& last, F& f, mpl::false_)
{
typename result_of::deref<First>::type x = *first;
return !f(x) &&
detail::none(
fusion::next(first)
, last
, f
, result_of::equal_to<typename result_of::next<First>::type, Last>());
}
}}}
#endif

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)
@ -8,31 +9,118 @@
#define FUSION_ALL_05052005_1237 #define FUSION_ALL_05052005_1237
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/advance.hpp>
#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/iterator/deref.hpp> #include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/distance.hpp>
namespace boost { namespace fusion { namespace detail namespace boost { namespace fusion { namespace detail
{ {
template <typename First, typename Last, typename F> template <typename First, typename Last, typename F>
inline bool inline bool
all(First const&, Last const&, F const&, mpl::true_) linear_all(First const&, Last const&, F const&, mpl::true_)
{ {
return true; return true;
} }
template <typename First, typename Last, typename F> template <typename First, typename Last, typename F>
inline bool inline bool
all(First const& first, Last const& last, F& f, mpl::false_) linear_all(First const& first, Last const& last, F& f, mpl::false_)
{ {
typename result_of::deref<First>::type x = *first; typename result_of::deref<First>::type x = *first;
return f(x) && return f(x) &&
detail::all( detail::linear_all(
fusion::next(first) fusion::next(first)
, last , last
, f , f
, result_of::equal_to<typename result_of::next<First>::type, Last>()); , result_of::equal_to<typename result_of::next<First>::type, Last>());
} }
template <typename Sequence, typename F, typename Tag>
inline bool
all(Sequence const& seq, F f, Tag)
{
return detail::linear_all(
fusion::begin(seq)
, fusion::end(seq)
, f
, result_of::equal_to<
typename result_of::begin<Sequence>::type
, typename result_of::end<Sequence>::type>());
}
template<int N>
struct unrolled_all
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return
f(*it) &&
f(*fusion::advance_c<1>(it))&&
f(*fusion::advance_c<2>(it)) &&
f(*fusion::advance_c<3>(it)) &&
detail::unrolled_all<N-4>::call(fusion::advance_c<4>(it), f);
}
};
template<>
struct unrolled_all<3>
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return
f(*it) &&
f(*fusion::advance_c<1>(it)) &&
f(*fusion::advance_c<2>(it));
}
};
template<>
struct unrolled_all<2>
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return
f(*it) &&
f(*fusion::advance_c<1>(it));
}
};
template<>
struct unrolled_all<1>
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return f(*it);
}
};
template<>
struct unrolled_all<0>
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return false;
}
};
template <typename Sequence, typename F>
inline bool
all(Sequence const& seq, F f, random_access_traversal_tag)
{
typedef typename result_of::begin<Sequence>::type begin;
typedef typename result_of::end<Sequence>::type end;
return detail::unrolled_all<result_of::distance<begin, end>::value>::call(
fusion::begin(seq), f);
}
}}} }}}
#endif #endif

View File

@ -1,6 +1,7 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2005 Eric Niebler Copyright (c) 2005 Eric Niebler
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)
@ -9,31 +10,120 @@
#define FUSION_ANY_05052005_1229 #define FUSION_ANY_05052005_1229
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/advance.hpp>
#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/iterator/deref.hpp> #include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/distance.hpp>
namespace boost { namespace fusion { namespace detail namespace boost { namespace fusion {
struct random_access_traversal_tag;
namespace detail
{ {
template <typename First, typename Last, typename F> template <typename First, typename Last, typename F>
inline bool inline bool
any(First const&, Last const&, F const&, mpl::true_) linear_any(First const&, Last const&, F const&, mpl::true_)
{ {
return false; return false;
} }
template <typename First, typename Last, typename F> template <typename First, typename Last, typename F>
inline bool inline bool
any(First const& first, Last const& last, F& f, mpl::false_) linear_any(First const& first, Last const& last, F& f, mpl::false_)
{ {
typename result_of::deref<First>::type x = *first; typename result_of::deref<First>::type x = *first;
return f(x) || return f(x) ||
detail::any( detail::linear_any(
fusion::next(first) fusion::next(first)
, last , last
, f , f
, result_of::equal_to<typename result_of::next<First>::type, Last>()); , result_of::equal_to<typename result_of::next<First>::type, Last>());
} }
template <typename Sequence, typename F, typename Tag>
inline bool
any(Sequence const& seq, F f, Tag)
{
return detail::linear_any(
fusion::begin(seq)
, fusion::end(seq)
, f
, result_of::equal_to<
typename result_of::begin<Sequence>::type
, typename result_of::end<Sequence>::type>());
}
template<int N>
struct unrolled_any
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return
f(*it) ||
f(*fusion::advance_c<1>(it))||
f(*fusion::advance_c<2>(it)) ||
f(*fusion::advance_c<3>(it)) ||
detail::unrolled_any<N-4>::call(fusion::advance_c<4>(it), f);
}
};
template<>
struct unrolled_any<3>
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return
f(*it) ||
f(*fusion::advance_c<1>(it)) ||
f(*fusion::advance_c<2>(it));
}
};
template<>
struct unrolled_any<2>
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return
f(*it) ||
f(*fusion::advance_c<1>(it));
}
};
template<>
struct unrolled_any<1>
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return f(*it);
}
};
template<>
struct unrolled_any<0>
{
template <typename It, typename F>
static bool call(It const& it, F f)
{
return false;
}
};
template <typename Sequence, typename F>
inline bool
any(Sequence const& seq, F f, random_access_traversal_tag)
{
typedef typename result_of::begin<Sequence>::type begin;
typedef typename result_of::end<Sequence>::type end;
return detail::unrolled_any<result_of::distance<begin, end>::value>::call(
fusion::begin(seq), f);
}
}}} }}}
#endif #endif

View File

@ -1,16 +1,14 @@
/*============================================================================= /*=============================================================================
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)
==============================================================================*/ ==============================================================================*/
#if !defined(FUSION_NONE_07062005_1128) #if !defined(BOOST_FUSION_NONE_07062005_1128)
#define FUSION_NONE_07062005_1128 #define BOOST_FUSION_NONE_07062005_1128
#include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/algorithm/query/any.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/algorithm/query/detail/none.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion
{ {
@ -27,13 +25,7 @@ namespace boost { namespace fusion
inline bool inline bool
none(Sequence const& seq, F f) none(Sequence const& seq, F f)
{ {
return detail::none( return !fusion::any(seq, f);
fusion::begin(seq)
, fusion::end(seq)
, f
, result_of::equal_to<
typename result_of::begin<Sequence>::type
, typename result_of::end<Sequence>::type>());
} }
}} }}