/* * Copyright 2008-2012 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include namespace thrust { // declare pointer with default values of template parameters template class pointer; } // end thrust // specialize std::iterator_traits to avoid problems with the name of // pointer's constructor shadowing its nested pointer type // do this before pointer is defined so the specialization is correctly // used inside the definition namespace std { template struct iterator_traits > { private: typedef thrust::pointer ptr; public: typedef typename ptr::iterator_category iterator_category; typedef typename ptr::value_type value_type; typedef typename ptr::difference_type difference_type; // XXX implement this type (the result of operator->) later typedef void pointer; typedef typename ptr::reference reference; }; // end iterator_traits } // end std namespace thrust { namespace detail { // this metafunction computes the type of iterator_adaptor thrust::pointer should inherit from template struct pointer_base { // void pointers should have no element type // note that we remove_cv from the Element type to get the value_type typedef typename thrust::detail::eval_if< thrust::detail::is_void::type>::value, thrust::detail::identity_, thrust::detail::remove_cv >::type value_type; // if no Derived type is given, just use pointer typedef typename thrust::detail::eval_if< thrust::detail::is_same::value, thrust::detail::identity_ >, thrust::detail::identity_ >::type derived_type; // void pointers should have no reference type // if no Reference type is given, just use reference typedef typename thrust::detail::eval_if< thrust::detail::is_void::type>::value, thrust::detail::identity_, thrust::detail::eval_if< thrust::detail::is_same::value, thrust::detail::identity_ >, thrust::detail::identity_ > >::type reference_arg; typedef thrust::iterator_adaptor< derived_type, // pass along the type of our Derived class to iterator_adaptor Element *, // we adapt a raw pointer value_type, // the value type Tag, // system tag thrust::random_access_traversal_tag, // pointers have random access traversal reference_arg, // pass along our Reference type std::ptrdiff_t > type; }; // end pointer_base } // end detail // the base type for all of thrust's tagged pointers. // for reasonable pointer-like semantics, derived types should reimplement the following: // 1. no-argument constructor // 2. constructor from OtherElement * // 3. constructor from OtherPointer related by convertibility // 4. assignment from OtherPointer related by convertibility // These should just call the corresponding members of pointer. template class pointer : public thrust::detail::pointer_base::type { private: typedef typename thrust::detail::pointer_base::type super_t; typedef typename thrust::detail::pointer_base::derived_type derived_type; // friend iterator_core_access to give it access to dereference friend class thrust::iterator_core_access; __host__ __device__ typename super_t::reference dereference() const; // don't provide access to this part of super_t's interface using super_t::base; using typename super_t::base_type; public: typedef typename super_t::base_type raw_pointer; // constructors __host__ __device__ pointer(); // OtherValue shall be convertible to Value // XXX consider making the pointer implementation a template parameter which defaults to Element * template __host__ __device__ explicit pointer(OtherElement *ptr); // OtherPointer's element_type shall be convertible to Element // OtherPointer's system shall be convertible to Tag template __host__ __device__ pointer(const OtherPointer &other, typename thrust::detail::enable_if_pointer_is_convertible< OtherPointer, pointer >::type * = 0); // assignment // OtherPointer's element_type shall be convertible to Element // OtherPointer's system shall be convertible to Tag template __host__ __device__ typename thrust::detail::enable_if_pointer_is_convertible< OtherPointer, pointer, derived_type & >::type operator=(const OtherPointer &other); // observers __host__ __device__ Element *get() const; }; // end pointer } // end thrust #include