• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
3 //
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
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10 
11 #ifndef BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP
12 #define BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP
13 
14 #include <string>
15 #include <cstddef>
16 #include <iterator>
17 
18 #include <boost/config.hpp>
19 #include <boost/iterator/iterator_adaptor.hpp>
20 
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>
27 
28 namespace boost {
29 namespace compute {
30 
31 // forward declaration for transform_iterator
32 template<class ElementIterator, class IndexIterator>
33 class permutation_iterator;
34 
35 namespace detail {
36 
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
41 {
42 public:
43     typedef ::boost::iterator_adaptor<
44         ::boost::compute::permutation_iterator<ElementIterator, IndexIterator>,
45         ElementIterator
46     > type;
47 };
48 
49 template<class ElementIterator, class IndexIterator, class IndexExpr>
50 struct permutation_iterator_access_expr
51 {
52     typedef typename std::iterator_traits<ElementIterator>::value_type result_type;
53 
permutation_iterator_access_exprboost::compute::detail::permutation_iterator_access_expr54     permutation_iterator_access_expr(const ElementIterator &e,
55                                      const IndexIterator &i,
56                                      const IndexExpr &expr)
57         : m_element_iter(e),
58           m_index_iter(i),
59           m_expr(expr)
60     {
61     }
62 
63     const ElementIterator m_element_iter;
64     const IndexIterator m_index_iter;
65     const IndexExpr m_expr;
66 };
67 
68 template<class ElementIterator, class IndexIterator, class IndexExpr>
operator <<(meta_kernel & kernel,const permutation_iterator_access_expr<ElementIterator,IndexIterator,IndexExpr> & expr)69 inline meta_kernel& operator<<(meta_kernel &kernel,
70                                const permutation_iterator_access_expr<ElementIterator,
71                                                                       IndexIterator,
72                                                                       IndexExpr> &expr)
73 {
74     return kernel << expr.m_element_iter[expr.m_index_iter[expr.m_expr]];
75 }
76 
77 } // end detail namespace
78 
79 /// \class permutation_iterator
80 /// \brief The permutation_iterator class provides a permuation iterator
81 ///
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.
85 ///
86 /// For example, to reverse a range using the copy() algorithm and a permutation
87 /// sequence:
88 ///
89 /// \snippet test/test_permutation_iterator.cpp reverse_range
90 ///
91 /// \see make_permutation_iterator()
92 template<class ElementIterator, class IndexIterator>
93 class permutation_iterator
94     : public detail::permutation_iterator_base<ElementIterator,
95                                                IndexIterator>::type
96 {
97 public:
98     typedef typename
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;
106 
permutation_iterator(ElementIterator e,IndexIterator i)107     permutation_iterator(ElementIterator e, IndexIterator i)
108         : super_type(e),
109           m_map(i)
110     {
111     }
112 
permutation_iterator(const permutation_iterator<ElementIterator,IndexIterator> & other)113     permutation_iterator(const permutation_iterator<ElementIterator,
114                                                     IndexIterator> &other)
115         : super_type(other),
116           m_map(other.m_map)
117     {
118     }
119 
120     permutation_iterator<ElementIterator, IndexIterator>&
operator =(const permutation_iterator<ElementIterator,IndexIterator> & other)121     operator=(const permutation_iterator<ElementIterator,
122                                          IndexIterator> &other)
123     {
124         if(this != &other){
125             super_type::operator=(other);
126             m_map = other.m_map;
127         }
128 
129         return *this;
130     }
131 
~permutation_iterator()132     ~permutation_iterator()
133     {
134     }
135 
get_index() const136     size_t get_index() const
137     {
138         return super_type::base().get_index();
139     }
140 
get_buffer() const141     const buffer& get_buffer() const
142     {
143         return detail::get_base_iterator_buffer(*this);
144     }
145 
146     template<class IndexExpr>
147     detail::permutation_iterator_access_expr<ElementIterator,
148                                              IndexIterator,
149                                              IndexExpr>
operator [](const IndexExpr & expr) const150     operator[](const IndexExpr &expr) const
151     {
152         return detail::permutation_iterator_access_expr<ElementIterator,
153                                                         IndexIterator,
154                                                         IndexExpr>(super_type::base(),
155                                                                    m_map,
156                                                                    expr);
157     }
158 
159 private:
160     friend class ::boost::iterator_core_access;
161 
dereference() const162     reference dereference() const
163     {
164         return reference();
165     }
166 
167 private:
168     IndexIterator m_map;
169 };
170 
171 /// Returns a permutation_iterator for \p e using indices from \p i.
172 ///
173 /// \param e the element range iterator
174 /// \param i the index range iterator
175 ///
176 /// \return a \c permutation_iterator for \p e using \p i
177 template<class ElementIterator, class IndexIterator>
178 inline permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator(ElementIterator e,IndexIterator i)179 make_permutation_iterator(ElementIterator e, IndexIterator i)
180 {
181     return permutation_iterator<ElementIterator, IndexIterator>(e, i);
182 }
183 
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 {};
188 
189 } // end compute namespace
190 } // end boost namespace
191 
192 #endif // BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP
193