// Copyright (c) 2018 NVIDIA Corporation // Author: Bryce Adelstein Lelbach // // Distributed under the Boost Software License v1.0 (boost.org/LICENSE_1_0.txt) // TODO: These need to be turned into proper Thrust algorithms (dispatch layer, // backends, etc). #pragma once #include #include #include #include #include #include #include #include THRUST_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////////// template __host__ __device__ void destroy_at(T* location) { location->~T(); } template __host__ __device__ void destroy_at(Allocator const& alloc, T* location) { typedef typename detail::allocator_traits< typename detail::remove_cv< typename detail::remove_reference::type >::type >::template rebind_traits::other traits; typename traits::allocator_type alloc_T(alloc); traits::destroy(alloc_T, location); } template __host__ __device__ ForwardIt destroy(ForwardIt first, ForwardIt last) { for (; first != last; ++first) destroy_at(addressof(*first)); return first; } template __host__ __device__ ForwardIt destroy(Allocator const& alloc, ForwardIt first, ForwardIt last) { typedef typename iterator_traits::value_type T; typedef typename detail::allocator_traits< typename detail::remove_cv< typename detail::remove_reference::type >::type >::template rebind_traits::other traits; typename traits::allocator_type alloc_T(alloc); for (; first != last; ++first) destroy_at(alloc_T, addressof(*first)); return first; } template __host__ __device__ ForwardIt destroy_n(ForwardIt first, Size n) { for (; n > 0; (void) ++first, --n) destroy_at(addressof(*first)); return first; } template __host__ __device__ ForwardIt destroy_n(Allocator const& alloc, ForwardIt first, Size n) { typedef typename iterator_traits::value_type T; typedef typename detail::allocator_traits< typename detail::remove_cv< typename detail::remove_reference::type >::type >::template rebind_traits::other traits; typename traits::allocator_type alloc_T(alloc); for (; n > 0; (void) ++first, --n) destroy_at(alloc_T, addressof(*first)); return first; } #if THRUST_CPP_DIALECT >= 2011 template __host__ __device__ void uninitialized_construct( ForwardIt first, ForwardIt last, Args const&... args ) { using T = typename iterator_traits::value_type; ForwardIt current = first; #if !__CUDA_ARCH__ // No exceptions in CUDA. try { #endif for (; current != last; ++current) ::new (static_cast(addressof(*current))) T(args...); #if !__CUDA_ARCH__ // No exceptions in CUDA. } catch (...) { destroy(first, current); throw; } #endif } template void uninitialized_construct_with_allocator( Allocator const& alloc, ForwardIt first, ForwardIt last, Args const&... args ) { using T = typename iterator_traits::value_type; using traits = typename detail::allocator_traits< typename std::remove_cv< typename std::remove_reference::type >::type >::template rebind_traits; typename traits::allocator_type alloc_T(alloc); ForwardIt current = first; #if !__CUDA_ARCH__ // No exceptions in CUDA. try { #endif for (; current != last; ++current) traits::construct(alloc_T, addressof(*current), args...); #if !__CUDA_ARCH__ // No exceptions in CUDA. } catch (...) { destroy(alloc_T, first, current); throw; } #endif } template void uninitialized_construct_n( ForwardIt first, Size n, Args const&... args ) { using T = typename iterator_traits::value_type; ForwardIt current = first; #if !__CUDA_ARCH__ // No exceptions in CUDA. try { #endif for (; n > 0; (void) ++current, --n) ::new (static_cast(addressof(*current))) T(args...); #if !__CUDA_ARCH__ // No exceptions in CUDA. } catch (...) { destroy(first, current); throw; } #endif } template void uninitialized_construct_n_with_allocator( Allocator const& alloc, ForwardIt first, Size n, Args const&... args ) { using T = typename iterator_traits::value_type; using traits = typename detail::allocator_traits< typename std::remove_cv< typename std::remove_reference::type >::type >::template rebind_traits; typename traits::allocator_type alloc_T(alloc); ForwardIt current = first; #if !__CUDA_ARCH__ // No exceptions in CUDA. try { #endif for (; n > 0; (void) ++current, --n) traits::construct(alloc_T, addressof(*current), args...); #if !__CUDA_ARCH__ // No exceptions in CUDA. } catch (...) { destroy(alloc_T, first, current); throw; } #endif } #endif /////////////////////////////////////////////////////////////////////////////// THRUST_NAMESPACE_END