rocPRIM
arg_index_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_ARG_INDEX_ITERATOR_HPP_
22 #define ROCPRIM_ITERATOR_ARG_INDEX_ITERATOR_HPP_
23 
24 #include <iterator>
25 #include <iostream>
26 #include <cstddef>
27 #include <type_traits>
28 
29 #include "../config.hpp"
30 #include "../types/key_value_pair.hpp"
31 
34 
35 BEGIN_ROCPRIM_NAMESPACE
36 
51 template<
52  class InputIterator,
53  class Difference = std::ptrdiff_t,
54  class InputValueType = typename std::iterator_traits<InputIterator>::value_type
55 >
57 {
58 private:
59  using input_category = typename std::iterator_traits<InputIterator>::iterator_category;
60 
61 public:
63  using value_type = ::rocprim::key_value_pair<Difference, InputValueType>;
66  using reference = const value_type&;
69  using pointer = const value_type*;
71  using difference_type = Difference;
73  using iterator_category = std::random_access_iterator_tag;
74 
75 #ifndef DOXYGEN_SHOULD_SKIP_THIS
77 #endif
78 
79  static_assert(
80  std::is_same<input_category, iterator_category>::value,
81  "InputIterator must be a random-access iterator"
82  );
83 
84  ROCPRIM_HOST_DEVICE inline
85  ~arg_index_iterator() = default;
86 
91  ROCPRIM_HOST_DEVICE inline
92  arg_index_iterator(InputIterator iterator, difference_type offset = 0)
93  : iterator_(iterator), offset_(offset)
94  {
95  }
96 
97  #ifndef DOXYGEN_SHOULD_SKIP_THIS
98  ROCPRIM_HOST_DEVICE inline
99  arg_index_iterator& operator++()
100  {
101  iterator_++;
102  offset_++;
103  return *this;
104  }
105 
106  ROCPRIM_HOST_DEVICE inline
107  arg_index_iterator operator++(int)
108  {
109  arg_index_iterator old_ai = *this;
110  iterator_++;
111  offset_++;
112  return old_ai;
113  }
114 
115  ROCPRIM_HOST_DEVICE inline
116  value_type operator*() const
117  {
118  value_type ret(offset_, *iterator_);
119  return ret;
120  }
121 
122  ROCPRIM_HOST_DEVICE inline
123  pointer operator->() const
124  {
125  return &(*(*this));
126  }
127 
128  ROCPRIM_HOST_DEVICE inline
129  arg_index_iterator operator+(difference_type distance) const
130  {
131  return arg_index_iterator(iterator_ + distance, offset_ + distance);
132  }
133 
134  ROCPRIM_HOST_DEVICE inline
135  arg_index_iterator& operator+=(difference_type distance)
136  {
137  iterator_ += distance;
138  offset_ += distance;
139  return *this;
140  }
141 
142  ROCPRIM_HOST_DEVICE inline
143  arg_index_iterator operator-(difference_type distance) const
144  {
145  return arg_index_iterator(iterator_ - distance, offset_ - distance);
146  }
147 
148  ROCPRIM_HOST_DEVICE inline
149  arg_index_iterator& operator-=(difference_type distance)
150  {
151  iterator_ -= distance;
152  offset_ -= distance;
153  return *this;
154  }
155 
156  ROCPRIM_HOST_DEVICE inline
157  difference_type operator-(arg_index_iterator other) const
158  {
159  return iterator_ - other.iterator_;
160  }
161 
162  ROCPRIM_HOST_DEVICE inline
163  value_type operator[](difference_type distance) const
164  {
165  arg_index_iterator i = (*this) + distance;
166  return *i;
167  }
168 
169  ROCPRIM_HOST_DEVICE inline
170  bool operator==(arg_index_iterator other) const
171  {
172  return (iterator_ == other.iterator_) && (offset_ == other.offset_);
173  }
174 
175  ROCPRIM_HOST_DEVICE inline
176  bool operator!=(arg_index_iterator other) const
177  {
178  return (iterator_ != other.iterator_) || (offset_ != other.offset_);
179  }
180 
181  ROCPRIM_HOST_DEVICE inline
182  bool operator<(arg_index_iterator other) const
183  {
184  return (iterator_ - other.iterator_) > 0;
185  }
186 
187  ROCPRIM_HOST_DEVICE inline
188  bool operator<=(arg_index_iterator other) const
189  {
190  return (iterator_ - other.iterator_) >= 0;
191  }
192 
193  ROCPRIM_HOST_DEVICE inline
194  bool operator>(arg_index_iterator other) const
195  {
196  return (iterator_ - other.iterator_) < 0;
197  }
198 
199  ROCPRIM_HOST_DEVICE inline
200  bool operator>=(arg_index_iterator other) const
201  {
202  return (iterator_ - other.iterator_) <= 0;
203  }
204 
205  ROCPRIM_HOST_DEVICE inline
206  void normalize()
207  {
208  offset_ = 0;
209  }
210 
211  friend std::ostream& operator<<(std::ostream& os, const arg_index_iterator& /* iter */)
212  {
213  return os;
214  }
215  #endif // DOXYGEN_SHOULD_SKIP_THIS
216 
217 private:
218  InputIterator iterator_;
219  difference_type offset_;
220 };
221 
222 #ifndef DOXYGEN_SHOULD_SKIP_THIS
223 template<
224  class InputIterator,
225  class Difference,
226  class InputValueType
227 >
228 ROCPRIM_HOST_DEVICE inline
232 {
233  return iterator + distance;
234 }
235 #endif // DOXYGEN_SHOULD_SKIP_THIS
236 
250 template<
251  class InputIterator,
252  class Difference = std::ptrdiff_t,
253  class InputValueType = typename std::iterator_traits<InputIterator>::value_type
254 >
255 ROCPRIM_HOST_DEVICE inline
257 make_arg_index_iterator(InputIterator iterator, Difference offset = 0)
258 {
260 }
261 
262 END_ROCPRIM_NAMESPACE
263 
265 // end of group iteratormodule
266 
267 #endif // ROCPRIM_ITERATOR_ARG_INDEX_ITERATOR_HPP_
const value_type & reference
A reference type of the type iterated over (value_type).
Definition: arg_index_iterator.hpp:66
ROCPRIM_HOST_DEVICE arg_index_iterator(InputIterator iterator, difference_type offset=0)
Creates a new arg_index_iterator.
Definition: arg_index_iterator.hpp:92
std::random_access_iterator_tag iterator_category
The category of the iterator.
Definition: arg_index_iterator.hpp:73
ROCPRIM_HOST_DEVICE arg_index_iterator< InputIterator, Difference, InputValueType > make_arg_index_iterator(InputIterator iterator, Difference offset=0)
make_arg_index_iterator creates a arg_index_iterator using iterator as the underlying iterator and of...
Definition: arg_index_iterator.hpp:257
::rocprim::key_value_pair< Difference, InputValueType > value_type
The type of the value that can be obtained by dereferencing the iterator.
Definition: arg_index_iterator.hpp:63
const value_type * pointer
A pointer type of the type iterated over (value_type).
Definition: arg_index_iterator.hpp:69
A random-access input (read-only) iterator adaptor for pairing dereferenced values with their indices...
Definition: arg_index_iterator.hpp:56
Difference difference_type
A type used for identify distance between iterators.
Definition: arg_index_iterator.hpp:71