diff options
Diffstat (limited to 'boost/compute/iterator/permutation_iterator.hpp')
-rw-r--r-- | boost/compute/iterator/permutation_iterator.hpp | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/boost/compute/iterator/permutation_iterator.hpp b/boost/compute/iterator/permutation_iterator.hpp new file mode 100644 index 0000000000..8a7f97a402 --- /dev/null +++ b/boost/compute/iterator/permutation_iterator.hpp @@ -0,0 +1,192 @@ +//---------------------------------------------------------------------------// +// 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_ITERATOR_PERMUTATION_ITERATOR_HPP +#define BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP + +#include <string> +#include <cstddef> +#include <iterator> + +#include <boost/config.hpp> +#include <boost/iterator/iterator_adaptor.hpp> + +#include <boost/compute/functional.hpp> +#include <boost/compute/detail/meta_kernel.hpp> +#include <boost/compute/detail/is_buffer_iterator.hpp> +#include <boost/compute/detail/read_write_single_value.hpp> +#include <boost/compute/iterator/detail/get_base_iterator_buffer.hpp> +#include <boost/compute/type_traits/is_device_iterator.hpp> + +namespace boost { +namespace compute { + +// forward declaration for transform_iterator +template<class ElementIterator, class IndexIterator> +class permutation_iterator; + +namespace detail { + +// helper class which defines the iterator_adaptor super-class +// type for permutation_iterator +template<class ElementIterator, class IndexIterator> +class permutation_iterator_base +{ +public: + typedef ::boost::iterator_adaptor< + ::boost::compute::permutation_iterator<ElementIterator, IndexIterator>, + ElementIterator + > type; +}; + +template<class ElementIterator, class IndexIterator, class IndexExpr> +struct permutation_iterator_access_expr +{ + typedef typename std::iterator_traits<ElementIterator>::value_type result_type; + + permutation_iterator_access_expr(const ElementIterator &e, + const IndexIterator &i, + const IndexExpr &expr) + : m_element_iter(e), + m_index_iter(i), + m_expr(expr) + { + } + + ElementIterator m_element_iter; + IndexIterator m_index_iter; + IndexExpr m_expr; +}; + +template<class ElementIterator, class IndexIterator, class IndexExpr> +inline meta_kernel& operator<<(meta_kernel &kernel, + const permutation_iterator_access_expr<ElementIterator, + IndexIterator, + IndexExpr> &expr) +{ + return kernel << expr.m_element_iter[expr.m_index_iter[expr.m_expr]]; +} + +} // end detail namespace + +/// \class permutation_iterator +/// \brief The permutation_iterator class provides a permuation iterator +/// +/// A permutation iterator iterates over a value range and an index range. When +/// dereferenced, it returns the value from the value range using the current +/// index from the index range. +/// +/// For example, to reverse a range using the copy() algorithm and a permutation +/// sequence: +/// +/// \snippet test/test_permutation_iterator.cpp reverse_range +/// +/// \see make_permutation_iterator() +template<class ElementIterator, class IndexIterator> +class permutation_iterator + : public detail::permutation_iterator_base<ElementIterator, + IndexIterator>::type +{ +public: + typedef typename + detail::permutation_iterator_base<ElementIterator, + IndexIterator>::type super_type; + typedef typename super_type::value_type value_type; + typedef typename super_type::reference reference; + typedef typename super_type::base_type base_type; + typedef typename super_type::difference_type difference_type; + typedef IndexIterator index_iterator; + + permutation_iterator(ElementIterator e, IndexIterator i) + : super_type(e), + m_map(i) + { + } + + permutation_iterator(const permutation_iterator<ElementIterator, + IndexIterator> &other) + : super_type(other), + m_map(other.m_map) + { + } + + permutation_iterator<ElementIterator, IndexIterator>& + operator=(const permutation_iterator<ElementIterator, + IndexIterator> &other) + { + if(this != &other){ + super_type::operator=(other); + m_map = other.m_map; + } + + return *this; + } + + ~permutation_iterator() + { + } + + size_t get_index() const + { + return super_type::base().get_index(); + } + + const buffer& get_buffer() const + { + return detail::get_base_iterator_buffer(*this); + } + + template<class IndexExpr> + detail::permutation_iterator_access_expr<ElementIterator, + IndexIterator, + IndexExpr> + operator[](const IndexExpr &expr) const + { + return detail::permutation_iterator_access_expr<ElementIterator, + IndexIterator, + IndexExpr>(super_type::base(), + m_map, + expr); + } + +private: + friend class ::boost::iterator_core_access; + + reference dereference() const + { + return reference(); + } + +private: + IndexIterator m_map; +}; + +/// Returns a permutation_iterator for \p e using indices from \p i. +/// +/// \param e the element range iterator +/// \param i the index range iterator +/// +/// \return a \c permutation_iterator for \p e using \p i +template<class ElementIterator, class IndexIterator> +inline permutation_iterator<ElementIterator, IndexIterator> +make_permutation_iterator(ElementIterator e, IndexIterator i) +{ + return permutation_iterator<ElementIterator, IndexIterator>(e, i); +} + +/// \internal_ (is_device_iterator specialization for permutation_iterator) +template<class ElementIterator, class IndexIterator> +struct is_device_iterator< + permutation_iterator<ElementIterator, IndexIterator> > : boost::true_type {}; + +} // end compute namespace +} // end boost namespace + +#endif // BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP |