rocPRIM
zip_iterator.hpp
1 // Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
21 #ifndef ROCPRIM_ITERATOR_ZIP_ITERATOR_HPP_
22 #define ROCPRIM_ITERATOR_ZIP_ITERATOR_HPP_
23 
24 #include <iterator>
25 #include <cstddef>
26 #include <type_traits>
27 
28 #include "../config.hpp"
29 #include "../detail/various.hpp"
30 #include "../types/tuple.hpp"
31 
34 
35 BEGIN_ROCPRIM_NAMESPACE
36 
37 namespace detail
38 {
39 
40 template<class T>
42 
43 template<class... Types>
44 struct tuple_of_references<::rocprim::tuple<Types...>>
45 {
46  using type = ::rocprim::tuple<typename std::iterator_traits<Types>::reference...>;
47 };
48 
49 template<class T>
51 
52 template<class... Types>
53 struct tuple_of_values<::rocprim::tuple<Types...>>
54 {
55  using type = ::rocprim::tuple<typename std::iterator_traits<Types>::value_type...>;
56 };
57 
59 {
60  template<class Iterator>
61  ROCPRIM_HOST_DEVICE inline
62  void operator()(Iterator& it)
63  {
64  ++it;
65  }
66 };
67 
69 {
70  template<class Iterator>
71  ROCPRIM_HOST_DEVICE inline
72  void operator()(Iterator& it)
73  {
74  --it;
75  }
76 };
77 
78 template<class Difference>
80 {
81  ROCPRIM_HOST_DEVICE inline
82  advance_iterator(Difference distance)
83  : distance_(distance)
84  {
85  }
86 
87  template<class Iterator>
88  ROCPRIM_HOST_DEVICE inline
89  void operator()(Iterator& it)
90  {
91  using it_distance_type = typename std::iterator_traits<Iterator>::difference_type;
92  it += static_cast<it_distance_type>(distance_);
93  }
94 
95 private:
96  Difference distance_;
97 };
98 
99 template<class ReferenceTuple, class... Types, size_t... Indices>
100 ROCPRIM_HOST_DEVICE inline
101 ReferenceTuple dereference_iterator_tuple_impl(const ::rocprim::tuple<Types...>& t,
102  ::rocprim::index_sequence<Indices...>)
103 {
104  ReferenceTuple rt { *::rocprim::get<Indices>(t)... };
105  return rt;
106 }
107 
108 template<class ReferenceTuple, class... Types>
109 ROCPRIM_HOST_DEVICE inline
110 ReferenceTuple dereference_iterator_tuple(const ::rocprim::tuple<Types...>& t)
111 {
112  return dereference_iterator_tuple_impl<ReferenceTuple>(
113  t, ::rocprim::index_sequence_for<Types...>()
114  );
115 }
116 
117 } // end detail namespace
118 
126 template<class IteratorTuple>
128 {
129 public:
138  using pointer = value_type*;
143  using difference_type = typename std::iterator_traits<
144  typename ::rocprim::tuple_element<0, IteratorTuple>::type
147  using iterator_category = std::random_access_iterator_tag;
148 
149  ROCPRIM_HOST_DEVICE inline
150  ~zip_iterator() = default;
151 
155  ROCPRIM_HOST_DEVICE inline
156  zip_iterator(IteratorTuple iterator_tuple)
157  : iterator_tuple_(iterator_tuple)
158  {
159  }
160 
161  #ifndef DOXYGEN_SHOULD_SKIP_THIS
162  ROCPRIM_HOST_DEVICE inline
163  zip_iterator& operator++()
164  {
165  detail::for_each_in_tuple(iterator_tuple_, detail::increment_iterator());
166  return *this;
167  }
168 
169  ROCPRIM_HOST_DEVICE inline
170  zip_iterator operator++(int)
171  {
172  zip_iterator old = *this;
173  ++(*this);
174  return old;
175  }
176 
177  ROCPRIM_HOST_DEVICE inline
178  zip_iterator& operator--()
179  {
180  detail::for_each_in_tuple(iterator_tuple_, detail::decrement_iterator());
181  return *this;
182  }
183 
184  ROCPRIM_HOST_DEVICE inline
185  zip_iterator operator--(int)
186  {
187  zip_iterator old = *this;
188  --(*this);
189  return old;
190  }
191 
192  ROCPRIM_HOST_DEVICE inline
193  reference operator*() const
194  {
195  return detail::dereference_iterator_tuple<reference>(iterator_tuple_);
196  }
197 
198  ROCPRIM_HOST_DEVICE inline
199  pointer operator->() const
200  {
201  return &(*(*this));
202  }
203 
204  ROCPRIM_HOST_DEVICE inline
205  reference operator[](difference_type distance) const
206  {
207  zip_iterator i = (*this) + distance;
208  return *i;
209  }
210 
211  ROCPRIM_HOST_DEVICE inline
212  zip_iterator operator+(difference_type distance) const
213  {
214  zip_iterator copy = *this;
215  copy += distance;
216  return copy;
217  }
218 
219  ROCPRIM_HOST_DEVICE inline
220  zip_iterator& operator+=(difference_type distance)
221  {
222  detail::for_each_in_tuple(
223  iterator_tuple_,
225  );
226  return *this;
227  }
228 
229  ROCPRIM_HOST_DEVICE inline
230  zip_iterator operator-(difference_type distance) const
231  {
232  auto copy = *this;
233  copy -= distance;
234  return copy;
235  }
236 
237  ROCPRIM_HOST_DEVICE inline
238  zip_iterator& operator-=(difference_type distance)
239  {
240  *this += -distance;
241  return *this;
242  }
243 
244  ROCPRIM_HOST_DEVICE inline
245  difference_type operator-(zip_iterator other) const
246  {
247  return ::rocprim::get<0>(iterator_tuple_) - ::rocprim::get<0>(other.iterator_tuple_);
248  }
249 
250  ROCPRIM_HOST_DEVICE inline
251  bool operator==(zip_iterator other) const
252  {
253  return iterator_tuple_ == other.iterator_tuple_;
254  }
255 
256  ROCPRIM_HOST_DEVICE inline
257  bool operator!=(zip_iterator other) const
258  {
259  return !(*this == other);
260  }
261 
262  ROCPRIM_HOST_DEVICE inline
263  bool operator<(zip_iterator other) const
264  {
265  return ::rocprim::get<0>(iterator_tuple_) < ::rocprim::get<0>(other.iterator_tuple_);
266  }
267 
268  ROCPRIM_HOST_DEVICE inline
269  bool operator<=(zip_iterator other) const
270  {
271  return !(other < *this);
272  }
273 
274  ROCPRIM_HOST_DEVICE inline
275  bool operator>(zip_iterator other) const
276  {
277  return other < *this;
278  }
279 
280  ROCPRIM_HOST_DEVICE inline
281  bool operator>=(zip_iterator other) const
282  {
283  return !(*this < other);
284  }
285 
286  friend std::ostream& operator<<(std::ostream& os, const zip_iterator& /* iter */)
287  {
288  return os;
289  }
290  #endif // DOXYGEN_SHOULD_SKIP_THIS
291 
292 private:
293  IteratorTuple iterator_tuple_;
294 };
295 
296 #ifndef DOXYGEN_SHOULD_SKIP_THIS
297 template<class IteratorTuple>
298 ROCPRIM_HOST_DEVICE inline
300 operator+(typename zip_iterator<IteratorTuple>::difference_type distance,
301  const zip_iterator<IteratorTuple>& iterator)
302 {
303  return iterator + distance;
304 }
305 #endif // DOXYGEN_SHOULD_SKIP_THIS
306 
314 template<class IteratorTuple>
315 ROCPRIM_HOST_DEVICE inline
317 make_zip_iterator(IteratorTuple iterator_tuple)
318 {
319  return zip_iterator<IteratorTuple>(iterator_tuple);
320 }
321 
322 END_ROCPRIM_NAMESPACE
323 
325 // end of group iteratormodule
326 
327 #endif // ROCPRIM_ITERATOR_ZIP_ITERATOR_HPP_
std::random_access_iterator_tag iterator_category
The category of the iterator.
Definition: zip_iterator.hpp:147
Definition: zip_iterator.hpp:50
typename detail::tuple_of_references< IteratorTuple >::type reference
A reference type of the type iterated over.
Definition: zip_iterator.hpp:134
ROCPRIM_HOST_DEVICE bool operator>=(const tuple< TTypes... > &lhs, const tuple< UTypes... > &rhs)
Greater than or equal to operator for tuples.
Definition: tuple.hpp:915
ROCPRIM_HOST_DEVICE bool operator<(const tuple< TTypes... > &lhs, const tuple< UTypes... > &rhs)
Less than operator for tuples.
Definition: tuple.hpp:864
Definition: zip_iterator.hpp:68
Definition: zip_iterator.hpp:58
ROCPRIM_HOST_DEVICE bool operator!=(const tuple< TTypes... > &lhs, const tuple< UTypes... > &rhs)
Not equal to operator for tuples.
Definition: tuple.hpp:838
typename detail::tuple_of_values< IteratorTuple >::type value_type
The type of the value that can be obtained by dereferencing the iterator.
Definition: zip_iterator.hpp:136
Deprecated: Configuration of device-level scan primitives.
Definition: block_histogram.hpp:62
Definition: zip_iterator.hpp:41
typename std::iterator_traits< typename ::rocprim::tuple_element< 0, IteratorTuple >::type >::difference_type difference_type
A type used for identify distance between iterators.
Definition: zip_iterator.hpp:145
ROCPRIM_HOST_DEVICE zip_iterator(IteratorTuple iterator_tuple)
Creates a new zip_iterator.
Definition: zip_iterator.hpp:156
ROCPRIM_HOST_DEVICE bool operator<=(const tuple< TTypes... > &lhs, const tuple< UTypes... > &rhs)
Less than or equal to operator for tuples.
Definition: tuple.hpp:898
ROCPRIM_HOST_DEVICE zip_iterator< IteratorTuple > make_zip_iterator(IteratorTuple iterator_tuple)
make_zip_iterator creates a zip_iterator using iterator_tuple as the underlying tuple of iterator...
Definition: zip_iterator.hpp:317
Definition: zip_iterator.hpp:79
ROCPRIM_HOST_DEVICE bool operator>(const tuple< TTypes... > &lhs, const tuple< UTypes... > &rhs)
Greater than operator for tuples.
Definition: tuple.hpp:881
ROCPRIM_HOST_DEVICE bool operator==(const tuple< TTypes... > &lhs, const tuple< UTypes... > &rhs)
Equal to operator for tuples.
Definition: tuple.hpp:819
value_type * pointer
A pointer type of the type iterated over (value_type).
Definition: zip_iterator.hpp:138
TBD.
Definition: zip_iterator.hpp:127