Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:31:09

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c) 2007 Dan Marsden
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying 
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 ==============================================================================*/
0008 #if !defined(BOOST_FUSION_COUNT_IF_09162005_0141)
0009 #define BOOST_FUSION_COUNT_IF_09162005_0141
0010 
0011 #include <boost/fusion/support/config.hpp>
0012 #include <boost/mpl/bool.hpp>
0013 #include <boost/fusion/sequence/intrinsic/begin.hpp>
0014 #include <boost/fusion/sequence/intrinsic/end.hpp>
0015 #include <boost/fusion/iterator/equal_to.hpp>
0016 #include <boost/fusion/iterator/next.hpp>
0017 #include <boost/fusion/iterator/deref.hpp>
0018 #include <boost/fusion/iterator/equal_to.hpp>
0019 #include <boost/fusion/iterator/distance.hpp>
0020 #include <boost/fusion/iterator/advance.hpp>
0021 
0022 namespace boost { namespace fusion { 
0023     struct random_access_traversal_tag;
0024 namespace detail
0025 {
0026     template <typename First, typename Last, typename F>
0027     BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0028     inline int
0029     linear_count_if(First const&, Last const&, F const&, mpl::true_)
0030     {
0031         return 0;
0032     }
0033 
0034     template <typename First, typename Last, typename F>
0035     BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0036     inline int
0037     linear_count_if(First const& first, Last const& last, F& f, mpl::false_)
0038     {
0039         int n =
0040             detail::linear_count_if(
0041                 fusion::next(first)
0042               , last
0043               , f
0044               , result_of::equal_to<typename result_of::next<First>::type, Last>());
0045         if (f(*first))
0046             ++n;
0047         return n;
0048     }
0049 
0050     template <typename Sequence, typename F, typename Tag>
0051     BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0052     inline int
0053     count_if(Sequence const& seq, F f, Tag)
0054     {
0055         return detail::linear_count_if(
0056                 fusion::begin(seq)
0057               , fusion::end(seq)
0058               , f
0059               , result_of::equal_to<
0060                     typename result_of::begin<Sequence>::type
0061                   , typename result_of::end<Sequence>::type>());
0062     }
0063 
0064     template<int n>
0065     struct unrolled_count_if
0066     {
0067         template<typename I0, typename F>
0068         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0069         static int call(I0 const& i0, F f)
0070         {
0071             int ct = unrolled_count_if<n-4>::
0072                 call(fusion::advance_c<4>(i0), f);
0073             if(f(*i0))
0074                 ++ct;
0075 
0076             typedef typename result_of::next<I0>::type I1;
0077             I1 i1(fusion::next(i0));
0078             if(f(*i1))
0079                 ++ct;
0080 
0081             typedef typename result_of::next<I1>::type I2;
0082             I2 i2(fusion::next(i1));
0083             if(f(*i2))
0084                 ++ct;
0085 
0086             typedef typename result_of::next<I2>::type I3;
0087             I3 i3(fusion::next(i2));
0088             if(f(*i3))
0089                 ++ct;
0090 
0091             return ct;
0092         }
0093     };
0094 
0095     template<>
0096     struct unrolled_count_if<3>
0097     {
0098         template<typename I0, typename F>
0099         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0100         static int call(I0 const& i0, F f)
0101         {
0102             int ct = 0;
0103             if(f(*i0))
0104                 ++ct;
0105 
0106             typedef typename result_of::next<I0>::type I1;
0107             I1 i1(fusion::next(i0));
0108             if(f(*i1))
0109                 ++ct;
0110 
0111             typedef typename result_of::next<I1>::type I2;
0112             I2 i2(fusion::next(i1));
0113             if(f(*i2))
0114                 ++ct;
0115 
0116             return ct;
0117         }
0118     };
0119 
0120     template<>
0121     struct unrolled_count_if<2>
0122     {
0123         template<typename I0, typename F>
0124         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0125         static int call(I0 const& i0, F f)
0126         {
0127             int ct = 0;
0128 
0129             if(f(*i0))
0130                 ++ct;
0131 
0132             typedef typename result_of::next<I0>::type I1;
0133             I1 i1(fusion::next(i0));
0134             if(f(*i1))
0135                 ++ct;
0136 
0137             return ct;
0138         }
0139     };
0140 
0141     template<>
0142     struct unrolled_count_if<1>
0143     {
0144         template<typename I0, typename F>
0145         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0146         static int call(I0 const& i0, F f)
0147         {
0148             int ct = 0;
0149             if(f(*i0))
0150                 ++ct;
0151             return ct;
0152         }
0153     };
0154 
0155 
0156     template<>
0157     struct unrolled_count_if<0>
0158     {
0159         template<typename I0, typename F>
0160         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0161         static int call(I0 const&, F)
0162         {
0163             return 0;
0164         }
0165     };
0166 
0167     template <typename Sequence, typename F>
0168     BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0169     inline int
0170     count_if(Sequence const& seq, F f, random_access_traversal_tag)
0171     {
0172         typedef typename result_of::begin<Sequence>::type begin;
0173         typedef typename result_of::end<Sequence>::type end;
0174         return detail::unrolled_count_if<result_of::distance<begin, end>::type::value>::
0175             call(fusion::begin(seq), f);
0176     }
0177 }}}
0178 
0179 #endif
0180