diff options
Diffstat (limited to 'boost/compute/algorithm/detail/count_if_with_reduce.hpp')
-rw-r--r-- | boost/compute/algorithm/detail/count_if_with_reduce.hpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/boost/compute/algorithm/detail/count_if_with_reduce.hpp b/boost/compute/algorithm/detail/count_if_with_reduce.hpp new file mode 100644 index 0000000000..f9449f4a41 --- /dev/null +++ b/boost/compute/algorithm/detail/count_if_with_reduce.hpp @@ -0,0 +1,87 @@ +//---------------------------------------------------------------------------// +// 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 |