88 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
//---------------------------------------------------------------------------//
 | 
						|
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
 | 
						|
//
 | 
						|
// 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
 | 
						|
//
 | 
						|
// See http://boostorg.github.com/compute for more information.
 | 
						|
//---------------------------------------------------------------------------//
 | 
						|
 | 
						|
#ifndef BOOST_COMPUTE_ALGORITHM_DETAIL_COUNT_IF_WITH_REDUCE_HPP
 | 
						|
#define BOOST_COMPUTE_ALGORITHM_DETAIL_COUNT_IF_WITH_REDUCE_HPP
 | 
						|
 | 
						|
#include <boost/compute/algorithm/reduce.hpp>
 | 
						|
#include <boost/compute/iterator/transform_iterator.hpp>
 | 
						|
#include <boost/compute/types/fundamental.hpp>
 | 
						|
 | 
						|
namespace boost {
 | 
						|
namespace compute {
 | 
						|
namespace detail {
 | 
						|
 | 
						|
template<class Predicate, class Arg>
 | 
						|
struct invoked_countable_predicate
 | 
						|
{
 | 
						|
    invoked_countable_predicate(Predicate p, Arg a)
 | 
						|
        : predicate(p), arg(a)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    Predicate predicate;
 | 
						|
    Arg arg;
 | 
						|
};
 | 
						|
 | 
						|
template<class Predicate, class Arg>
 | 
						|
inline meta_kernel& operator<<(meta_kernel &kernel,
 | 
						|
                               const invoked_countable_predicate<Predicate, Arg> &expr)
 | 
						|
{
 | 
						|
    return kernel << "(" << expr.predicate(expr.arg) << " ? 1 : 0)";
 | 
						|
}
 | 
						|
 | 
						|
// the countable_predicate wraps Predicate and converts its result from
 | 
						|
// bool to ulong so that it can be used with reduce()
 | 
						|
template<class Predicate>
 | 
						|
struct countable_predicate
 | 
						|
{
 | 
						|
    typedef ulong_ result_type;
 | 
						|
 | 
						|
    countable_predicate(Predicate predicate)
 | 
						|
        : m_predicate(predicate)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    template<class Arg>
 | 
						|
    invoked_countable_predicate<Predicate, Arg> operator()(const Arg &arg) const
 | 
						|
    {
 | 
						|
        return invoked_countable_predicate<Predicate, Arg>(m_predicate, arg);
 | 
						|
    }
 | 
						|
 | 
						|
    Predicate m_predicate;
 | 
						|
};
 | 
						|
 | 
						|
// counts the number of elements matching predicate using reduce()
 | 
						|
template<class InputIterator, class Predicate>
 | 
						|
inline size_t count_if_with_reduce(InputIterator first,
 | 
						|
                                   InputIterator last,
 | 
						|
                                   Predicate predicate,
 | 
						|
                                   command_queue &queue)
 | 
						|
{
 | 
						|
    countable_predicate<Predicate> reduce_predicate(predicate);
 | 
						|
 | 
						|
    ulong_ count = 0;
 | 
						|
    ::boost::compute::reduce(
 | 
						|
        ::boost::compute::make_transform_iterator(first, reduce_predicate),
 | 
						|
        ::boost::compute::make_transform_iterator(last, reduce_predicate),
 | 
						|
        &count,
 | 
						|
        ::boost::compute::plus<ulong_>(),
 | 
						|
        queue
 | 
						|
    );
 | 
						|
 | 
						|
    return static_cast<size_t>(count);
 | 
						|
}
 | 
						|
 | 
						|
} // end detail namespace
 | 
						|
} // end compute namespace
 | 
						|
} // end boost namespace
 | 
						|
 | 
						|
#endif // BOOST_COMPUTE_ALGORITHM_DETAIL_COUNT_IF_WITH_REDUCE_HPP
 |