From a4268d3cf9173faf2e32b643d90fce21e0663171 Mon Sep 17 00:00:00 2001 From: Dan Marsden Date: Wed, 30 May 2007 06:56:32 +0000 Subject: [PATCH] loop unrolling for compile time perf in any, all and none [SVN r37820] --- include/boost/fusion/algorithm/query/all.hpp | 17 +--- include/boost/fusion/algorithm/query/any.hpp | 13 +-- .../algorithm/query/detail/Attic/none.hpp | 39 -------- .../fusion/algorithm/query/detail/all.hpp | 94 +++++++++++++++++- .../fusion/algorithm/query/detail/any.hpp | 98 ++++++++++++++++++- include/boost/fusion/algorithm/query/none.hpp | 18 +--- 6 files changed, 198 insertions(+), 81 deletions(-) delete mode 100644 include/boost/fusion/algorithm/query/detail/Attic/none.hpp diff --git a/include/boost/fusion/algorithm/query/all.hpp b/include/boost/fusion/algorithm/query/all.hpp index 67452d5a..9d78867c 100644 --- a/include/boost/fusion/algorithm/query/all.hpp +++ b/include/boost/fusion/algorithm/query/all.hpp @@ -1,15 +1,14 @@ /*============================================================================= Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden 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_ALL_05052005_1238) -#define FUSION_ALL_05052005_1238 +#if !defined(BOOST_FUSION_ALL_05052005_1238) +#define BOOST_FUSION_ALL_05052005_1238 -#include -#include -#include +#include #include namespace boost { namespace fusion @@ -27,13 +26,7 @@ namespace boost { namespace fusion inline bool all(Sequence const& seq, F f) { - return detail::all( - fusion::begin(seq) - , fusion::end(seq) - , f - , result_of::equal_to< - typename result_of::begin::type - , typename result_of::end::type>()); + return detail::all(seq, f, typename traits::category_of::type()); } }} diff --git a/include/boost/fusion/algorithm/query/any.hpp b/include/boost/fusion/algorithm/query/any.hpp index 39590dfe..be4ef099 100644 --- a/include/boost/fusion/algorithm/query/any.hpp +++ b/include/boost/fusion/algorithm/query/any.hpp @@ -1,6 +1,7 @@ /*============================================================================= Copyright (c) 2001-2006 Joel de Guzman Copyright (c) 2005 Eric Niebler + Copyright (c) 2007 Dan Marsden 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) @@ -8,9 +9,7 @@ #if !defined(FUSION_ANY_05052005_1230) #define FUSION_ANY_05052005_1230 -#include -#include -#include +#include #include namespace boost { namespace fusion @@ -28,13 +27,7 @@ namespace boost { namespace fusion inline bool any(Sequence const& seq, F f) { - return detail::any( - fusion::begin(seq) - , fusion::end(seq) - , f - , result_of::equal_to< - typename result_of::begin::type - , typename result_of::end::type>()); + return detail::any(seq, f, typename traits::category_of::type()); } }} diff --git a/include/boost/fusion/algorithm/query/detail/Attic/none.hpp b/include/boost/fusion/algorithm/query/detail/Attic/none.hpp deleted file mode 100644 index 1a633fca..00000000 --- a/include/boost/fusion/algorithm/query/detail/Attic/none.hpp +++ /dev/null @@ -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 -#include -#include -#include - -namespace boost { namespace fusion { namespace detail -{ - template - inline bool - none(First const&, Last const&, F const&, mpl::true_) - { - return true; - } - - template - inline bool - none(First const& first, Last const& last, F& f, mpl::false_) - { - typename result_of::deref::type x = *first; - return !f(x) && - detail::none( - fusion::next(first) - , last - , f - , result_of::equal_to::type, Last>()); - } -}}} - -#endif - diff --git a/include/boost/fusion/algorithm/query/detail/all.hpp b/include/boost/fusion/algorithm/query/detail/all.hpp index ae3e64c6..9f4828ce 100644 --- a/include/boost/fusion/algorithm/query/detail/all.hpp +++ b/include/boost/fusion/algorithm/query/detail/all.hpp @@ -1,5 +1,6 @@ /*============================================================================= Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden 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) @@ -8,31 +9,118 @@ #define FUSION_ALL_05052005_1237 #include +#include +#include +#include #include #include #include +#include namespace boost { namespace fusion { namespace detail { template inline bool - all(First const&, Last const&, F const&, mpl::true_) + linear_all(First const&, Last const&, F const&, mpl::true_) { return true; } template 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::type x = *first; return f(x) && - detail::all( + detail::linear_all( fusion::next(first) , last , f , result_of::equal_to::type, Last>()); } + + template + 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::type + , typename result_of::end::type>()); + } + + template + struct unrolled_all + { + template + 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::call(fusion::advance_c<4>(it), f); + } + }; + + template<> + struct unrolled_all<3> + { + template + 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 + static bool call(It const& it, F f) + { + return + f(*it) && + f(*fusion::advance_c<1>(it)); + } + }; + + template<> + struct unrolled_all<1> + { + template + static bool call(It const& it, F f) + { + return f(*it); + } + }; + + template<> + struct unrolled_all<0> + { + template + static bool call(It const& it, F f) + { + return false; + } + }; + + template + inline bool + all(Sequence const& seq, F f, random_access_traversal_tag) + { + typedef typename result_of::begin::type begin; + typedef typename result_of::end::type end; + return detail::unrolled_all::value>::call( + fusion::begin(seq), f); + } }}} #endif diff --git a/include/boost/fusion/algorithm/query/detail/any.hpp b/include/boost/fusion/algorithm/query/detail/any.hpp index 5e5e569f..8cb2ea21 100644 --- a/include/boost/fusion/algorithm/query/detail/any.hpp +++ b/include/boost/fusion/algorithm/query/detail/any.hpp @@ -1,6 +1,7 @@ /*============================================================================= Copyright (c) 2001-2006 Joel de Guzman Copyright (c) 2005 Eric Niebler + Copyright (c) 2007 Dan Marsden 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) @@ -9,31 +10,120 @@ #define FUSION_ANY_05052005_1229 #include +#include +#include +#include #include #include #include +#include -namespace boost { namespace fusion { namespace detail +namespace boost { namespace fusion { + struct random_access_traversal_tag; +namespace detail { template inline bool - any(First const&, Last const&, F const&, mpl::true_) + linear_any(First const&, Last const&, F const&, mpl::true_) { return false; } template 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::type x = *first; return f(x) || - detail::any( + detail::linear_any( fusion::next(first) , last , f , result_of::equal_to::type, Last>()); } + + template + 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::type + , typename result_of::end::type>()); + } + + template + struct unrolled_any + { + template + 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::call(fusion::advance_c<4>(it), f); + } + }; + + template<> + struct unrolled_any<3> + { + template + 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 + static bool call(It const& it, F f) + { + return + f(*it) || + f(*fusion::advance_c<1>(it)); + } + }; + + template<> + struct unrolled_any<1> + { + template + static bool call(It const& it, F f) + { + return f(*it); + } + }; + + template<> + struct unrolled_any<0> + { + template + static bool call(It const& it, F f) + { + return false; + } + }; + + template + inline bool + any(Sequence const& seq, F f, random_access_traversal_tag) + { + typedef typename result_of::begin::type begin; + typedef typename result_of::end::type end; + return detail::unrolled_any::value>::call( + fusion::begin(seq), f); + } }}} #endif diff --git a/include/boost/fusion/algorithm/query/none.hpp b/include/boost/fusion/algorithm/query/none.hpp index e182d811..f31f4c9c 100644 --- a/include/boost/fusion/algorithm/query/none.hpp +++ b/include/boost/fusion/algorithm/query/none.hpp @@ -1,16 +1,14 @@ /*============================================================================= Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden 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_1128) -#define FUSION_NONE_07062005_1128 +#if !defined(BOOST_FUSION_NONE_07062005_1128) +#define BOOST_FUSION_NONE_07062005_1128 -#include -#include -#include -#include +#include namespace boost { namespace fusion { @@ -27,13 +25,7 @@ namespace boost { namespace fusion inline bool none(Sequence const& seq, F f) { - return detail::none( - fusion::begin(seq) - , fusion::end(seq) - , f - , result_of::equal_to< - typename result_of::begin::type - , typename result_of::end::type>()); + return !fusion::any(seq, f); } }}