193 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			6.3 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_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
 | 
