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) 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 <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/algorithm/query/detail/all.hpp>
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<Sequence>::type
, typename result_of::end<Sequence>::type>());
return detail::all(seq, f, typename traits::category_of<Sequence>::type());
}
}}

View File

@ -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 <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/algorithm/query/detail/any.hpp>
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<Sequence>::type
, typename result_of::end<Sequence>::type>());
return detail::any(seq, f, typename traits::category_of<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) 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 <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/next.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/distance.hpp>
namespace boost { namespace fusion { namespace detail
{
template <typename First, typename Last, typename F>
inline bool
all(First const&, Last const&, F const&, mpl::true_)
linear_all(First const&, Last const&, F const&, mpl::true_)
{
return true;
}
template <typename First, typename Last, typename F>
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;
return f(x) &&
detail::all(
detail::linear_all(
fusion::next(first)
, last
, f
, 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

View File

@ -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 <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/next.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>
inline bool
any(First const&, Last const&, F const&, mpl::true_)
linear_any(First const&, Last const&, F const&, mpl::true_)
{
return false;
}
template <typename First, typename Last, typename F>
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;
return f(x) ||
detail::any(
detail::linear_any(
fusion::next(first)
, last
, f
, 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

View File

@ -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 <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/algorithm/query/detail/none.hpp>
#include <boost/fusion/algorithm/query/any.hpp>
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<Sequence>::type
, typename result_of::end<Sequence>::type>());
return !fusion::any(seq, f);
}
}}