1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
11 #ifndef BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP
12 #define BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP
18 #include <boost/config.hpp>
19 #include <boost/iterator/iterator_adaptor.hpp>
21 #include <boost/compute/functional.hpp>
22 #include <boost/compute/detail/meta_kernel.hpp>
23 #include <boost/compute/detail/is_buffer_iterator.hpp>
24 #include <boost/compute/detail/read_write_single_value.hpp>
25 #include <boost/compute/iterator/detail/get_base_iterator_buffer.hpp>
26 #include <boost/compute/type_traits/is_device_iterator.hpp>
31 // forward declaration for transform_iterator
32 template<class ElementIterator, class IndexIterator>
33 class permutation_iterator;
37 // helper class which defines the iterator_adaptor super-class
38 // type for permutation_iterator
39 template<class ElementIterator, class IndexIterator>
40 class permutation_iterator_base
43 typedef ::boost::iterator_adaptor<
44 ::boost::compute::permutation_iterator<ElementIterator, IndexIterator>,
49 template<class ElementIterator, class IndexIterator, class IndexExpr>
50 struct permutation_iterator_access_expr
52 typedef typename std::iterator_traits<ElementIterator>::value_type result_type;
54 permutation_iterator_access_expr(const ElementIterator &e,
55 const IndexIterator &i,
56 const IndexExpr &expr)
63 ElementIterator m_element_iter;
64 IndexIterator m_index_iter;
68 template<class ElementIterator, class IndexIterator, class IndexExpr>
69 inline meta_kernel& operator<<(meta_kernel &kernel,
70 const permutation_iterator_access_expr<ElementIterator,
74 return kernel << expr.m_element_iter[expr.m_index_iter[expr.m_expr]];
77 } // end detail namespace
79 /// \class permutation_iterator
80 /// \brief The permutation_iterator class provides a permuation iterator
82 /// A permutation iterator iterates over a value range and an index range. When
83 /// dereferenced, it returns the value from the value range using the current
84 /// index from the index range.
86 /// For example, to reverse a range using the copy() algorithm and a permutation
89 /// \snippet test/test_permutation_iterator.cpp reverse_range
91 /// \see make_permutation_iterator()
92 template<class ElementIterator, class IndexIterator>
93 class permutation_iterator
94 : public detail::permutation_iterator_base<ElementIterator,
99 detail::permutation_iterator_base<ElementIterator,
100 IndexIterator>::type super_type;
101 typedef typename super_type::value_type value_type;
102 typedef typename super_type::reference reference;
103 typedef typename super_type::base_type base_type;
104 typedef typename super_type::difference_type difference_type;
105 typedef IndexIterator index_iterator;
107 permutation_iterator(ElementIterator e, IndexIterator i)
113 permutation_iterator(const permutation_iterator<ElementIterator,
114 IndexIterator> &other)
120 permutation_iterator<ElementIterator, IndexIterator>&
121 operator=(const permutation_iterator<ElementIterator,
122 IndexIterator> &other)
125 super_type::operator=(other);
132 ~permutation_iterator()
136 size_t get_index() const
138 return super_type::base().get_index();
141 const buffer& get_buffer() const
143 return detail::get_base_iterator_buffer(*this);
146 template<class IndexExpr>
147 detail::permutation_iterator_access_expr<ElementIterator,
150 operator[](const IndexExpr &expr) const
152 return detail::permutation_iterator_access_expr<ElementIterator,
154 IndexExpr>(super_type::base(),
160 friend class ::boost::iterator_core_access;
162 reference dereference() const
171 /// Returns a permutation_iterator for \p e using indices from \p i.
173 /// \param e the element range iterator
174 /// \param i the index range iterator
176 /// \return a \c permutation_iterator for \p e using \p i
177 template<class ElementIterator, class IndexIterator>
178 inline permutation_iterator<ElementIterator, IndexIterator>
179 make_permutation_iterator(ElementIterator e, IndexIterator i)
181 return permutation_iterator<ElementIterator, IndexIterator>(e, i);
184 /// \internal_ (is_device_iterator specialization for permutation_iterator)
185 template<class ElementIterator, class IndexIterator>
186 struct is_device_iterator<
187 permutation_iterator<ElementIterator, IndexIterator> > : boost::true_type {};
189 } // end compute namespace
190 } // end boost namespace
192 #endif // BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP