rocPRIM
replace_first_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_REPLACE_FIRST_ITERATOR_HPP_
22 #define ROCPRIM_ITERATOR_REPLACE_FIRST_ITERATOR_HPP_
23 
24 #include <iterator>
25 #include <cstddef>
26 #include <type_traits>
27 
28 #include "../../config.hpp"
29 
30 BEGIN_ROCPRIM_NAMESPACE
31 
32 namespace detail
33 {
34 
35 // Replaces first value of given range with given value. Used in exclusive scan-by-key
36 // and exclusive segmented scan to avoid allocating additional memory and/or running
37 // additional kernels.
38 //
39 // Important: it does not dereference the first item in given range, so it does not matter
40 // if it's an invalid pointer.
41 //
42 // Usage:
43 // * input - start of your input range
44 // * value - value that should be used as first element of new range.
45 //
46 // replace_first_iterator<InputIterator>(input - 1, value);
47 //
48 // (input - 1) will never be dereferenced.
49 template<class InputIterator>
51 {
52 private:
53  using input_category = typename std::iterator_traits<InputIterator>::iterator_category;
54  static_assert(
55  std::is_same<input_category, std::random_access_iterator_tag>::value,
56  "InputIterator must be a random-access iterator"
57  );
58 
59 public:
60  using value_type = typename std::iterator_traits<InputIterator>::value_type;
61  using reference = value_type;
62  using pointer = const value_type*;
63  using difference_type = typename std::iterator_traits<InputIterator>::difference_type;
64  using iterator_category = std::random_access_iterator_tag;
65 
66  ROCPRIM_HOST_DEVICE inline
67  ~replace_first_iterator() = default;
68 
69  ROCPRIM_HOST_DEVICE inline
70  replace_first_iterator(InputIterator iterator, value_type value, size_t index = 0)
71  : iterator_(iterator), value_(value), index_(index)
72  {
73  }
74 
75  ROCPRIM_HOST_DEVICE inline
76  replace_first_iterator& operator++()
77  {
78  iterator_++;
79  index_++;
80  return *this;
81  }
82 
83  ROCPRIM_HOST_DEVICE inline
84  replace_first_iterator operator++(int)
85  {
86  replace_first_iterator old = *this;
87  iterator_++;
88  index_++;
89  return old;
90  }
91 
92  ROCPRIM_HOST_DEVICE inline
93  value_type operator*() const
94  {
95  if(index_ == 0)
96  {
97  return value_;
98  }
99  return *iterator_;
100  }
101 
102  ROCPRIM_HOST_DEVICE inline
103  value_type operator[](difference_type distance) const
104  {
105  replace_first_iterator i = (*this) + distance;
106  return *i;
107  }
108 
109  ROCPRIM_HOST_DEVICE inline
110  replace_first_iterator operator+(difference_type distance) const
111  {
112  return replace_first_iterator(iterator_ + distance, value_, index_ + distance);
113  }
114 
115  ROCPRIM_HOST_DEVICE inline
116  replace_first_iterator& operator+=(difference_type distance)
117  {
118  iterator_ += distance;
119  index_ += distance;
120  return *this;
121  }
122 
123 private:
124  InputIterator iterator_;
125  value_type value_;
126  size_t index_;
127 };
128 
129 } // end of detail namespace
130 
131 END_ROCPRIM_NAMESPACE
132 
133 #endif // ROCPRIM_ITERATOR_REPLACE_FIRST_ITERATOR_HPP_
Deprecated: Configuration of device-level scan primitives.
Definition: block_histogram.hpp:62
Definition: replace_first_iterator.hpp:50