Thrust
transform_iterator.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2013 NVIDIA Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
22 /*
23  * (C) Copyright David Abrahams 2002.
24  * (C) Copyright Jeremy Siek 2002.
25  * (C) Copyright Thomas Witt 2002.
26  *
27  * Distributed under the Boost Software License, Version 1.0.
28  * (See accompanying NOTICE file for the complete license)
29  *
30  * For more information, see http://www.boost.org
31  */
32 
33 #pragma once
34 
35 #include <thrust/detail/config.h>
36 
37 // #include the details first
38 #include <thrust/iterator/detail/transform_iterator.inl>
41 #include <thrust/detail/type_traits.h>
42 
43 THRUST_NAMESPACE_BEGIN
44 
188 template <class AdaptableUnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
190  : public detail::transform_iterator_base<AdaptableUnaryFunction, Iterator, Reference, Value>::type
191 {
194  public:
195  typedef typename
196  detail::transform_iterator_base<AdaptableUnaryFunction, Iterator, Reference, Value>::type
197  super_t;
198 
199  friend class thrust::iterator_core_access;
203  public:
206  __host__ __device__
208 
209 #if THRUST_CPP_DIALECT >= 2011
210  transform_iterator(transform_iterator const&) = default;
211 #endif
212 
219  __host__ __device__
220  transform_iterator(Iterator const& x, AdaptableUnaryFunction f)
221  : super_t(x), m_f(f) {
222  }
223 
229  __host__ __device__
230  explicit transform_iterator(Iterator const& x)
231  : super_t(x) { }
232 
238  template<typename OtherAdaptableUnaryFunction,
239  typename OtherIterator,
240  typename OtherReference,
241  typename OtherValue>
242  __host__ __device__
244  typename thrust::detail::enable_if_convertible<OtherIterator, Iterator>::type* = 0,
245  typename thrust::detail::enable_if_convertible<OtherAdaptableUnaryFunction, AdaptableUnaryFunction>::type* = 0)
246  : super_t(other.base()), m_f(other.functor()) {}
247 
258  __host__ __device__
260  {
261  return do_assign(other,
262  // XXX gcc 4.2.1 crashes on is_copy_assignable; just assume the functor is assignable as a WAR
263 #if (THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC) && (THRUST_GCC_VERSION <= 40201)
264  thrust::detail::true_type()
265 #else
266  typename thrust::detail::is_copy_assignable<AdaptableUnaryFunction>::type()
267 #endif // THRUST_HOST_COMPILER
268  );
269  }
270 
274  __host__ __device__
275  AdaptableUnaryFunction functor() const
276  { return m_f; }
277 
280  private:
281  __host__ __device__
282  transform_iterator &do_assign(const transform_iterator &other, thrust::detail::true_type)
283  {
284  super_t::operator=(other);
285 
286  // do assign to m_f
287  m_f = other.functor();
288 
289  return *this;
290  }
291 
292  __host__ __device__
293  transform_iterator &do_assign(const transform_iterator &other, thrust::detail::false_type)
294  {
295  super_t::operator=(other);
296 
297  // don't assign to m_f
298 
299  return *this;
300  }
301 
302  // MSVC 2013 and 2015 incorrectly warning about returning a reference to
303  // a local/temporary here.
304  // See goo.gl/LELTNp
305  THRUST_DISABLE_MSVC_WARNING_BEGIN(4172)
306 
307  __thrust_exec_check_disable__
308  __host__ __device__
309  typename super_t::reference dereference() const
310  {
311  // Create a temporary to allow iterators with wrapped references to
312  // convert to their value type before calling m_f. Note that this
313  // disallows non-constant operations through m_f.
314  typename thrust::iterator_value<Iterator>::type const& x = *this->base();
315  return m_f(x);
316  }
317 
318  THRUST_DISABLE_MSVC_WARNING_END(4172)
319 
320  // tag this as mutable per Dave Abrahams in this thread:
321  // http://lists.boost.org/Archives/boost/2004/05/65332.php
322  mutable AdaptableUnaryFunction m_f;
323 
326 }; // end transform_iterator
327 
328 
340 template <class AdaptableUnaryFunction, class Iterator>
341 inline __host__ __device__
343 make_transform_iterator(Iterator it, AdaptableUnaryFunction fun)
344 {
346 } // end make_transform_iterator
347 
354 THRUST_NAMESPACE_END
355 
__host__ __device__ AdaptableUnaryFunction functor() const
Definition: transform_iterator.h:275
Definition: transform_iterator.h:189
thrust::reference< T, thrust::system::cpp::tag > reference
Definition: pointer.h:98
Definition: iterator_facade.h:60
__host__ __device__ transform_iterator()
Definition: transform_iterator.h:207
__host__ __device__ transform_iterator< AdaptableUnaryFunction, Iterator > make_transform_iterator(Iterator it, AdaptableUnaryFunction fun)
Definition: transform_iterator.h:343
__host__ __device__ transform_iterator(Iterator const &x)
Definition: transform_iterator.h:230
__host__ __device__ transform_iterator(Iterator const &x, AdaptableUnaryFunction f)
Definition: transform_iterator.h:220
Traits and metafunctions for reasoning about the traits of iterators.
__host__ __device__ transform_iterator & operator=(const transform_iterator &other)
Definition: transform_iterator.h:259
A class which exposes a public interface for iterators.
__host__ __device__ transform_iterator(const transform_iterator< OtherAdaptableUnaryFunction, OtherIterator, OtherReference, OtherValue > &other, typename thrust::detail::enable_if_convertible< OtherIterator, Iterator >::type *=0, typename thrust::detail::enable_if_convertible< OtherAdaptableUnaryFunction, AdaptableUnaryFunction >::type *=0)
Definition: transform_iterator.h:243