CUB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups
cache_modified_output_iterator.cuh
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (c) 2011, Duane Merrill. All rights reserved.
3  * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the NVIDIA CORPORATION nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  ******************************************************************************/
28 
34 #pragma once
35 
36 #include <iterator>
37 #include <iostream>
38 
39 #include "../thread/thread_load.cuh"
40 #include "../thread/thread_store.cuh"
41 #include "../util_device.cuh"
42 #include "../util_namespace.cuh"
43 
44 #if (THRUST_VERSION >= 100700)
45  // This iterator is compatible with Thrust API 1.7 and newer
46  #include <thrust/iterator/iterator_facade.h>
47  #include <thrust/iterator/iterator_traits.h>
48 #endif // THRUST_VERSION
49 
50 
52 CUB_NS_PREFIX
53 
55 namespace cub {
56 
57 
105 template <
106  CacheStoreModifier MODIFIER,
107  typename ValueType,
108  typename Offset = ptrdiff_t>
110 {
111 private:
112 
113  // Proxy object
114  struct Reference
115  {
116  ValueType* ptr;
117 
119  __host__ __device__ __forceinline__ Reference(ValueType* ptr) : ptr(ptr) {}
120 
122  __host__ __device__ __forceinline__ ValueType operator =(ValueType val)
123  {
124  ThreadStore<MODIFIER>(ptr, val);
125  return val;
126  }
127  };
128 
129 public:
130 
131  // Required iterator traits
133  typedef Offset difference_type;
134  typedef ValueType value_type;
135  typedef ValueType* pointer;
136  typedef Reference reference;
137 
138 #if (THRUST_VERSION >= 100700)
139  // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods
140  typedef typename thrust::detail::iterator_facade_category<
141  thrust::device_system_tag,
142  thrust::random_access_traversal_tag,
143  value_type,
144  reference
145  >::type iterator_category;
146 #else
147  typedef std::random_access_iterator_tag iterator_category;
148 #endif // THRUST_VERSION
149 
150 private:
151 
152  ValueType* ptr;
153 
154 public:
155 
157  __host__ __device__ __forceinline__ CacheModifiedOutputIterator(
158  ValueType* ptr)
159  :
160  ptr(ptr)
161  {}
162 
164  __host__ __device__ __forceinline__ self_type operator++(int)
165  {
166  self_type retval = *this;
167  ptr++;
168  return retval;
169  }
170 
171 
173  __host__ __device__ __forceinline__ self_type operator++()
174  {
175  ptr++;
176  return *this;
177  }
178 
180  __host__ __device__ __forceinline__ reference operator*() const
181  {
182  return Reference(ptr);
183  }
184 
186  template <typename Distance>
187  __host__ __device__ __forceinline__ self_type operator+(Distance n) const
188  {
189  self_type retval(ptr + n);
190  return retval;
191  }
192 
194  template <typename Distance>
195  __host__ __device__ __forceinline__ self_type& operator+=(Distance n)
196  {
197  ptr += n;
198  return *this;
199  }
200 
202  template <typename Distance>
203  __host__ __device__ __forceinline__ self_type operator-(Distance n) const
204  {
205  self_type retval(ptr - n);
206  return retval;
207  }
208 
210  template <typename Distance>
211  __host__ __device__ __forceinline__ self_type& operator-=(Distance n)
212  {
213  ptr -= n;
214  return *this;
215  }
216 
218  __host__ __device__ __forceinline__ difference_type operator-(self_type other) const
219  {
220  return ptr - other.ptr;
221  }
222 
224  template <typename Distance>
225  __host__ __device__ __forceinline__ reference operator[](Distance n) const
226  {
227  return Reference(ptr + n);
228  }
229 
231  __host__ __device__ __forceinline__ bool operator==(const self_type& rhs)
232  {
233  return (ptr == rhs.ptr);
234  }
235 
237  __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs)
238  {
239  return (ptr != rhs.ptr);
240  }
241 
243  friend std::ostream& operator<<(std::ostream& os, const self_type& itr)
244  {
245  return os;
246  }
247 };
248 
249  // end group UtilIterator
251 
252 } // CUB namespace
253 CUB_NS_POSTFIX // Optional outer namespace(s)