/* * Copyright 2008-2021 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 #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) # pragma GCC system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG) # pragma clang system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC) # pragma system_header #endif // no system header #include #include THRUST_NAMESPACE_BEGIN template _CCCL_HOST_DEVICE pointer::pointer() : super_t(static_cast(nullptr)) {} // end pointer::pointer template _CCCL_HOST_DEVICE pointer::pointer(std::nullptr_t) : super_t(static_cast(nullptr)) {} // end pointer::pointer template template _CCCL_HOST_DEVICE pointer::pointer(OtherElement* other) : super_t(other) {} // end pointer::pointer template template _CCCL_HOST_DEVICE pointer::pointer( const OtherPointer& other, typename thrust::detail::enable_if_pointer_is_convertible>::type*) : super_t(thrust::detail::pointer_traits::get(other)) {} // end pointer::pointer template template _CCCL_HOST_DEVICE pointer::pointer( const OtherPointer& other, typename thrust::detail:: enable_if_void_pointer_is_system_convertible>::type*) : super_t(static_cast(thrust::detail::pointer_traits::get(other))) {} // end pointer::pointer template _CCCL_HOST_DEVICE typename pointer::derived_type& pointer::operator=(decltype(nullptr)) { super_t::base_reference() = nullptr; return static_cast(*this); } // end pointer::operator= template template _CCCL_HOST_DEVICE typename thrust::detail::enable_if_pointer_is_convertible< OtherPointer, pointer, typename pointer::derived_type&>::type pointer::operator=(const OtherPointer& other) { super_t::base_reference() = thrust::detail::pointer_traits::get(other); return static_cast(*this); } // end pointer::operator= namespace detail { // Implementation for dereference() when Reference is Element&, // e.g. cuda's managed_memory_pointer template _CCCL_HOST_DEVICE Reference pointer_dereference_impl(const Derived& ptr, thrust::detail::true_type /* is_cpp_ref */) { return *ptr.get(); } // Implementation for pointers with proxy references: template _CCCL_HOST_DEVICE Reference pointer_dereference_impl(const Derived& ptr, thrust::detail::false_type /* is_cpp_ref */) { return Reference(ptr); } } // namespace detail template _CCCL_HOST_DEVICE typename pointer::super_t::reference pointer::dereference() const { // Need to handle cpp refs and fancy refs differently: using RefT = typename super_t::reference; using IsCppRef = typename ::cuda::std::is_reference::type; const derived_type& derivedPtr = static_cast(*this); return detail::pointer_dereference_impl(derivedPtr, IsCppRef()); } // end pointer::dereference template _CCCL_HOST_DEVICE Element* pointer::get() const { return super_t::base(); } // end pointer::get template _CCCL_HOST_DEVICE Element* pointer::operator->() const { return super_t::base(); } // end pointer::operator-> template _CCCL_HOST_DEVICE pointer::operator bool() const { return bool(get()); } // end pointer::operator bool template _CCCL_HOST std::basic_ostream& operator<<(std::basic_ostream& os, const pointer& p) { return os << p.get(); } // NOTE: These are needed so that Thrust smart pointers work with // `std::unique_ptr`. template _CCCL_HOST_DEVICE bool operator==(std::nullptr_t, pointer p) { return nullptr == p.get(); } template _CCCL_HOST_DEVICE bool operator==(pointer p, std::nullptr_t) { return nullptr == p.get(); } template _CCCL_HOST_DEVICE bool operator!=(std::nullptr_t, pointer p) { return !(nullptr == p); } template _CCCL_HOST_DEVICE bool operator!=(pointer p, std::nullptr_t) { return !(nullptr == p); } THRUST_NAMESPACE_END