8 #include <thrust/detail/config.h> 9 #include <thrust/detail/cpp11_required.h> 11 #if THRUST_CPP_DIALECT >= 2011 13 #include <thrust/detail/raw_pointer_cast.h> 14 #include <thrust/detail/type_deduction.h> 15 #include <thrust/detail/memory_algorithms.h> 16 #include <thrust/detail/allocator/allocator_traits.h> 30 template <
typename Allocator,
typename Po
inter>
31 void allocator_delete_impl(
32 Allocator
const& alloc, Pointer p, std::false_type
35 using traits =
typename detail::allocator_traits<
36 typename std::remove_cv<
37 typename std::remove_reference<Allocator>::type
41 typename traits::allocator_type alloc_T(alloc);
46 traits::deallocate(alloc_T, p, 1);
50 template <
typename Allocator,
typename Po
inter>
51 void allocator_delete_impl(
52 Allocator
const& alloc, Pointer p, std::true_type
55 using traits =
typename detail::allocator_traits<
56 typename std::remove_cv<
57 typename std::remove_reference<Allocator>::type
61 typename traits::allocator_type alloc_T(alloc);
65 traits::deallocate(alloc_T, p, 1);
71 template <
typename T,
typename Allocator,
bool Uninitialized = false>
72 struct allocator_delete final
75 =
typename std::remove_cv<
76 typename std::remove_reference<Allocator>::type
77 >::type::template rebind<T>::other;
78 using pointer =
typename detail::allocator_traits<allocator_type>::pointer;
80 template <
typename UAllocator>
81 allocator_delete(UAllocator&& other) noexcept
82 : alloc_(THRUST_FWD(other))
85 template <
typename U,
typename UAllocator>
87 allocator_delete<U, UAllocator>
const& other
89 : alloc_(other.get_allocator())
91 template <
typename U,
typename UAllocator>
93 allocator_delete<U, UAllocator>&& other
95 : alloc_(std::move(other.get_allocator()))
98 template <
typename U,
typename UAllocator>
99 allocator_delete& operator=(
100 allocator_delete<U, UAllocator>
const& other
103 alloc_ = other.get_allocator();
106 template <
typename U,
typename UAllocator>
107 allocator_delete& operator=(
108 allocator_delete<U, UAllocator>&& other
111 alloc_ = std::move(other.get_allocator());
115 void operator()(pointer p)
117 std::integral_constant<bool, Uninitialized> ic;
119 detail::allocator_delete_impl(get_allocator(), p, ic);
122 allocator_type& get_allocator() noexcept {
return alloc_; }
123 allocator_type
const& get_allocator() const noexcept {
return alloc_; }
125 void swap(allocator_delete& other) noexcept
128 swap(alloc_, other.alloc_);
132 allocator_type alloc_;
135 template <
typename T,
typename Allocator>
136 using uninitialized_allocator_delete = allocator_delete<T, Allocator, true>;
140 template <
typename Allocator,
typename Po
inter,
typename Size>
141 void array_allocator_delete_impl(
142 Allocator
const& alloc, Pointer p, Size
count, std::false_type
145 using traits =
typename detail::allocator_traits<
146 typename std::remove_cv<
147 typename std::remove_reference<Allocator>::type
151 typename traits::allocator_type alloc_T(alloc);
155 destroy_n(alloc_T, p, count);
156 traits::deallocate(alloc_T, p, count);
160 template <
typename Allocator,
typename Po
inter,
typename Size>
161 void array_allocator_delete_impl(
162 Allocator
const& alloc, Pointer p, Size count, std::true_type
165 using traits =
typename detail::allocator_traits<
166 typename std::remove_cv<
167 typename std::remove_reference<Allocator>::type
171 typename traits::allocator_type alloc_T(alloc);
175 traits::deallocate(alloc_T, p, count);
181 template <
typename T,
typename Allocator,
bool Uninitialized = false>
182 struct array_allocator_delete final
185 =
typename std::remove_cv<
186 typename std::remove_reference<Allocator>::type
187 >::type::template rebind<T>::other;
188 using pointer =
typename detail::allocator_traits<allocator_type>::pointer;
190 template <
typename UAllocator>
191 array_allocator_delete(UAllocator&& other, std::size_t n) noexcept
192 : alloc_(THRUST_FWD(other)), count_(n)
195 template <
typename U,
typename UAllocator>
196 array_allocator_delete(
197 array_allocator_delete<U, UAllocator>
const& other
199 : alloc_(other.get_allocator()), count_(other.count_)
201 template <
typename U,
typename UAllocator>
202 array_allocator_delete(
203 array_allocator_delete<U, UAllocator>&& other
205 : alloc_(std::move(other.get_allocator())), count_(other.count_)
208 template <
typename U,
typename UAllocator>
209 array_allocator_delete& operator=(
210 array_allocator_delete<U, UAllocator>
const& other
213 alloc_ = other.get_allocator();
214 count_ = other.count_;
217 template <
typename U,
typename UAllocator>
218 array_allocator_delete& operator=(
219 array_allocator_delete<U, UAllocator>&& other
222 alloc_ = std::move(other.get_allocator());
223 count_ = other.count_;
227 void operator()(pointer p)
229 std::integral_constant<bool, Uninitialized> ic;
231 detail::array_allocator_delete_impl(get_allocator(), p, count_, ic);
234 allocator_type& get_allocator() noexcept {
return alloc_; }
235 allocator_type
const& get_allocator() const noexcept {
return alloc_; }
237 void swap(array_allocator_delete& other) noexcept
240 swap(alloc_, other.alloc_);
241 swap(count_, other.count_);
245 allocator_type alloc_;
249 template <
typename T,
typename Allocator>
250 using uninitialized_array_allocator_delete
251 = array_allocator_delete<T, Allocator, true>;
255 template <
typename Po
inter,
typename Lambda>
256 struct tagged_deleter : Lambda
259 tagged_deleter(Lambda&& l) : Lambda(THRUST_FWD(l)) {}
261 using pointer = Pointer;
264 template <
typename Po
inter,
typename Lambda>
266 tagged_deleter<Pointer, Lambda>
267 make_tagged_deleter(Lambda&& l)
269 return tagged_deleter<Pointer, Lambda>(THRUST_FWD(l));
274 template <
typename T,
typename Allocator,
typename... Args>
280 ,
typename detail::allocator_traits<
281 typename std::remove_cv<
282 typename std::remove_reference<Allocator>::type
284 >::template rebind_traits<T>::allocator_type
288 Allocator
const& alloc, Args&&... args
291 using traits =
typename detail::allocator_traits<
292 typename std::remove_cv<
293 typename std::remove_reference<Allocator>::type
295 >::template rebind_traits<T>;
297 typename traits::allocator_type alloc_T(alloc);
299 auto hold_deleter = make_tagged_deleter<typename traits::pointer>(
300 [&alloc_T] (
typename traits::pointer p) {
301 traits::deallocate(alloc_T, p, 1);
304 using hold_t = std::unique_ptr<T, decltype(hold_deleter)>;
305 auto hold = hold_t(traits::allocate(alloc_T, 1), hold_deleter);
310 auto deleter = allocator_delete<T, typename traits::allocator_type>(alloc);
311 return std::unique_ptr<T, decltype(deleter)>
312 (hold.release(), std::move(deleter));
315 template <
typename T,
typename Allocator>
319 uninitialized_allocator_delete<
321 ,
typename detail::allocator_traits<
322 typename std::remove_cv<
323 typename std::remove_reference<Allocator>::type
325 >::template rebind_traits<T>::allocator_type
328 uninitialized_allocate_unique(
329 Allocator
const& alloc
332 using traits =
typename detail::allocator_traits<
333 typename std::remove_cv<
334 typename std::remove_reference<Allocator>::type
336 >::template rebind_traits<T>;
338 typename traits::allocator_type alloc_T(alloc);
340 auto hold_deleter = make_tagged_deleter<typename traits::pointer>(
341 [&alloc_T] (
typename traits::pointer p) {
342 traits::deallocate(alloc_T, p, 1);
345 using hold_t = std::unique_ptr<T, decltype(hold_deleter)>;
346 auto hold = hold_t(traits::allocate(alloc_T, 1), hold_deleter);
348 auto deleter = uninitialized_allocator_delete<
349 T,
typename traits::allocator_type
351 return std::unique_ptr<T, decltype(deleter)>
352 (hold.release(), std::move(deleter));
355 template <
typename T,
typename Allocator,
typename Size,
typename... Args>
359 array_allocator_delete<
361 ,
typename detail::allocator_traits<
362 typename std::remove_cv<
363 typename std::remove_reference<Allocator>::type
365 >::template rebind_traits<T>::allocator_type
369 Allocator
const& alloc, Size n, Args&&... args
372 using traits =
typename detail::allocator_traits<
373 typename std::remove_cv<
374 typename std::remove_reference<Allocator>::type
376 >::template rebind_traits<T>;
378 typename traits::allocator_type alloc_T(alloc);
380 auto hold_deleter = make_tagged_deleter<typename traits::pointer>(
381 [n, &alloc_T] (
typename traits::pointer p) {
382 traits::deallocate(alloc_T, p, n);
385 using hold_t = std::unique_ptr<T[], decltype(hold_deleter)>;
386 auto hold = hold_t(traits::allocate(alloc_T, n), hold_deleter);
388 uninitialized_construct_n_with_allocator(
389 alloc_T, hold.get(), n, THRUST_FWD(args)...
391 auto deleter = array_allocator_delete<
392 T,
typename traits::allocator_type
394 return std::unique_ptr<T[], decltype(deleter)>
395 (hold.release(), std::move(deleter));
398 template <
typename T,
typename Allocator,
typename Size>
402 uninitialized_array_allocator_delete<
404 ,
typename detail::allocator_traits<
405 typename std::remove_cv<
406 typename std::remove_reference<Allocator>::type
408 >::template rebind_traits<T>::allocator_type
411 uninitialized_allocate_unique_n(
412 Allocator
const& alloc, Size n
415 using traits =
typename detail::allocator_traits<
416 typename std::remove_cv<
417 typename std::remove_reference<Allocator>::type
419 >::template rebind_traits<T>;
421 typename traits::allocator_type alloc_T(alloc);
423 auto hold_deleter = make_tagged_deleter<typename traits::pointer>(
424 [n, &alloc_T] (
typename traits::pointer p) {
425 traits::deallocate(alloc_T, p, n);
428 using hold_t = std::unique_ptr<T[], decltype(hold_deleter)>;
429 auto hold = hold_t(traits::allocate(alloc_T, n), hold_deleter);
431 auto deleter = uninitialized_array_allocator_delete<
432 T,
typename traits::allocator_type
434 return std::unique_ptr<T[], decltype(deleter)>
435 (hold.release(), std::move(deleter));
442 #endif // THRUST_CPP_DIALECT >= 2011 __host__ __device__ access_traits< typename tuple_element< N, detail::cons< HT, TT > >::type >::non_const_type get(detail::cons< HT, TT > &t)
__host__ __device__ thrust::iterator_traits< InputIterator >::difference_type count(const thrust::detail::execution_policy_base< DerivedPolicy > &exec, InputIterator first, InputIterator last, const EqualityComparable &value)
__host__ __device__ thrust::detail::pointer_traits< Pointer >::raw_pointer raw_pointer_cast(Pointer ptr)
__host__ __device__ void swap(device_reference< T > x, device_reference< T > y)