1616#ifndef STDGPU_DEQUE_DETAIL_H
1717#define STDGPU_DEQUE_DETAIL_H
1818
19+ #include < type_traits>
20+
1921#include < stdgpu/contract.h>
2022#include < stdgpu/iterator.h>
2123#include < stdgpu/memory.h>
@@ -42,19 +44,21 @@ deque<T, Allocator>::createDeviceObject(ExecutionPolicy&& policy, const index_t&
4244
4345 deque<T, Allocator> result (
4446 mutex_array<mutex_default_type, mutex_array_allocator_type>::createDeviceObject (
45- std::forward <ExecutionPolicy>( policy) ,
47+ std::decay_t <ExecutionPolicy>{ policy } ,
4648 capacity,
4749 mutex_array_allocator_type (allocator)),
4850 bitset<bitset_default_type, bitset_allocator_type>::createDeviceObject (
49- std::forward <ExecutionPolicy>( policy) ,
51+ std::decay_t <ExecutionPolicy>{ policy } ,
5052 capacity,
5153 bitset_allocator_type (allocator)),
52- atomic<int , atomic_int_allocator_type>::createDeviceObject (std::forward <ExecutionPolicy>( policy) ,
54+ atomic<int , atomic_int_allocator_type>::createDeviceObject (std::decay_t <ExecutionPolicy>{ policy } ,
5355 atomic_int_allocator_type (allocator)),
54- atomic<unsigned int , atomic_uint_allocator_type>::createDeviceObject (std::forward<ExecutionPolicy>(policy),
55- atomic_uint_allocator_type (allocator)),
56- atomic<unsigned int , atomic_uint_allocator_type>::createDeviceObject (std::forward<ExecutionPolicy>(policy),
57- atomic_uint_allocator_type (allocator)),
56+ atomic<unsigned int , atomic_uint_allocator_type>::createDeviceObject (
57+ std::decay_t <ExecutionPolicy>{ policy },
58+ atomic_uint_allocator_type (allocator)),
59+ atomic<unsigned int , atomic_uint_allocator_type>::createDeviceObject (
60+ std::decay_t <ExecutionPolicy>{ policy },
61+ atomic_uint_allocator_type (allocator)),
5862 allocator);
5963 result._data = allocator_traits<allocator_type>::allocate (result._allocator , capacity);
6064 result._range_indices = allocator_traits<index_allocator_type>::allocate (result._index_allocator , capacity);
@@ -77,7 +81,7 @@ deque<T, Allocator>::destroyDeviceObject(ExecutionPolicy&& policy, deque<T, Allo
7781{
7882 if (!detail::is_destroy_optimizable<value_type>())
7983 {
80- device_object.clear (std::forward <ExecutionPolicy>( policy) );
84+ device_object.clear (std::decay_t <ExecutionPolicy>{ policy } );
8185 }
8286
8387 allocator_traits<allocator_type>::deallocate (device_object._allocator ,
@@ -89,13 +93,13 @@ deque<T, Allocator>::destroyDeviceObject(ExecutionPolicy&& policy, deque<T, Allo
8993 device_object._data = nullptr ;
9094 device_object._range_indices = nullptr ;
9195 mutex_array<mutex_default_type, mutex_array_allocator_type>::destroyDeviceObject (
92- std::forward <ExecutionPolicy>( policy) ,
96+ std::decay_t <ExecutionPolicy>{ policy } ,
9397 device_object._locks );
94- bitset<bitset_default_type, bitset_allocator_type>::destroyDeviceObject (std::forward <ExecutionPolicy>( policy) ,
98+ bitset<bitset_default_type, bitset_allocator_type>::destroyDeviceObject (std::decay_t <ExecutionPolicy>{ policy } ,
9599 device_object._occupied );
96- atomic<int , atomic_int_allocator_type>::destroyDeviceObject (std::forward <ExecutionPolicy>( policy) ,
100+ atomic<int , atomic_int_allocator_type>::destroyDeviceObject (std::decay_t <ExecutionPolicy>{ policy } ,
97101 device_object._size );
98- atomic<unsigned int , atomic_uint_allocator_type>::destroyDeviceObject (std::forward <ExecutionPolicy>( policy) ,
102+ atomic<unsigned int , atomic_uint_allocator_type>::destroyDeviceObject (std::decay_t <ExecutionPolicy>{ policy } ,
99103 device_object._begin );
100104 atomic<unsigned int , atomic_uint_allocator_type>::destroyDeviceObject (std::forward<ExecutionPolicy>(policy),
101105 device_object._end );
@@ -550,48 +554,50 @@ template <typename ExecutionPolicy,
550554inline void
551555deque<T, Allocator>::clear(ExecutionPolicy&& policy)
552556{
553- if (empty (std::forward <ExecutionPolicy>( policy) ))
557+ if (empty (std::decay_t <ExecutionPolicy>{ policy } ))
554558 {
555559 return ;
556560 }
557561
558562 if (!detail::is_destroy_optimizable<value_type>())
559563 {
560- const index_t begin = static_cast <index_t >(_begin.load (std::forward <ExecutionPolicy>( policy) ));
561- const index_t end = static_cast <index_t >(_end.load (std::forward <ExecutionPolicy>( policy) ));
564+ const index_t begin = static_cast <index_t >(_begin.load (std::decay_t <ExecutionPolicy>{ policy } ));
565+ const index_t end = static_cast <index_t >(_end.load (std::decay_t <ExecutionPolicy>{ policy } ));
562566
563567 // Full, i.e. one large block and begin == end
564- if (full (std::forward <ExecutionPolicy>( policy) ))
568+ if (full (std::decay_t <ExecutionPolicy>{ policy } ))
565569 {
566- detail::unoptimized_destroy (std::forward<ExecutionPolicy>(policy), device_begin (_data), device_end (_data));
570+ detail::unoptimized_destroy (std::decay_t <ExecutionPolicy>{ policy },
571+ device_begin (_data),
572+ device_end (_data));
567573 }
568574 // One large block
569575 else if (begin <= end)
570576 {
571- detail::unoptimized_destroy (std::forward <ExecutionPolicy>( policy) ,
577+ detail::unoptimized_destroy (std::decay_t <ExecutionPolicy>{ policy } ,
572578 make_device (_data + begin),
573579 make_device (_data + end));
574580 }
575581 // Two disconnected blocks
576582 else
577583 {
578- detail::unoptimized_destroy (std::forward <ExecutionPolicy>( policy) ,
584+ detail::unoptimized_destroy (std::decay_t <ExecutionPolicy>{ policy } ,
579585 device_begin (_data),
580586 make_device (_data + end));
581- detail::unoptimized_destroy (std::forward <ExecutionPolicy>( policy) ,
587+ detail::unoptimized_destroy (std::decay_t <ExecutionPolicy>{ policy } ,
582588 make_device (_data + begin),
583589 device_end (_data));
584590 }
585591 }
586592
587- _occupied.reset (std::forward <ExecutionPolicy>( policy) );
593+ _occupied.reset (std::decay_t <ExecutionPolicy>{ policy } );
588594
589- _size.store (std::forward <ExecutionPolicy>( policy) , 0 );
595+ _size.store (std::decay_t <ExecutionPolicy>{ policy } , 0 );
590596
591- _begin.store (std::forward <ExecutionPolicy>( policy) , 0 );
592- _end.store (std::forward <ExecutionPolicy>( policy) , 0 );
597+ _begin.store (std::decay_t <ExecutionPolicy>{ policy } , 0 );
598+ _end.store (std::decay_t <ExecutionPolicy>{ policy } , 0 );
593599
594- STDGPU_ENSURES (empty (std::forward <ExecutionPolicy>( policy) ));
600+ STDGPU_ENSURES (empty (std::decay_t <ExecutionPolicy>{ policy } ));
595601 STDGPU_ENSURES (valid (std::forward<ExecutionPolicy>(policy)));
596602}
597603
@@ -614,9 +620,9 @@ deque<T, Allocator>::valid(ExecutionPolicy&& policy) const
614620 return true ;
615621 }
616622
617- return (size_valid (std::forward <ExecutionPolicy>( policy) ) &&
618- occupied_count_valid (std::forward <ExecutionPolicy>( policy) ) &&
619- _locks.valid (std::forward <ExecutionPolicy>( policy) ));
623+ return (size_valid (std::decay_t <ExecutionPolicy>{ policy } ) &&
624+ occupied_count_valid (std::decay_t <ExecutionPolicy>{ policy } ) &&
625+ _locks.valid (std::decay_t <ExecutionPolicy>{ policy } ));
620626}
621627
622628template <typename T, typename Allocator>
@@ -632,30 +638,30 @@ template <typename ExecutionPolicy,
632638stdgpu::device_indexed_range<T>
633639deque<T, Allocator>::device_range(ExecutionPolicy&& policy)
634640{
635- const index_t begin = static_cast <index_t >(_begin.load (std::forward <ExecutionPolicy>( policy) ));
636- const index_t end = static_cast <index_t >(_end.load (std::forward <ExecutionPolicy>( policy) ));
641+ const index_t begin = static_cast <index_t >(_begin.load (std::decay_t <ExecutionPolicy>{ policy } ));
642+ const index_t end = static_cast <index_t >(_end.load (std::decay_t <ExecutionPolicy>{ policy } ));
637643
638644 // Full, i.e. one large block and begin == end
639- if (full (std::forward <ExecutionPolicy>( policy) ))
645+ if (full (std::decay_t <ExecutionPolicy>{ policy } ))
640646 {
641- iota (std::forward <ExecutionPolicy>( policy) , device_begin (_range_indices), device_end (_range_indices), 0 );
647+ iota (std::decay_t <ExecutionPolicy>{ policy } , device_begin (_range_indices), device_end (_range_indices), 0 );
642648 }
643649 // One large block, including empty block
644650 else if (begin <= end)
645651 {
646- iota (std::forward <ExecutionPolicy>( policy) ,
652+ iota (std::decay_t <ExecutionPolicy>{ policy } ,
647653 device_begin (_range_indices),
648654 device_begin (_range_indices) + (end - begin),
649655 begin);
650656 }
651657 // Two disconnected blocks
652658 else
653659 {
654- iota (std::forward <ExecutionPolicy>( policy) ,
660+ iota (std::decay_t <ExecutionPolicy>{ policy } ,
655661 device_begin (_range_indices),
656662 device_begin (_range_indices) + end,
657663 0 );
658- iota (std::forward <ExecutionPolicy>( policy) ,
664+ iota (std::decay_t <ExecutionPolicy>{ policy } ,
659665 device_begin (_range_indices) + end,
660666 device_begin (_range_indices) + (end + capacity () - begin),
661667 begin);
@@ -679,30 +685,30 @@ template <typename ExecutionPolicy,
679685stdgpu::device_indexed_range<const T>
680686deque<T, Allocator>::device_range(ExecutionPolicy&& policy) const
681687{
682- const index_t begin = static_cast <index_t >(_begin.load (std::forward <ExecutionPolicy>( policy) ));
683- const index_t end = static_cast <index_t >(_end.load (std::forward <ExecutionPolicy>( policy) ));
688+ const index_t begin = static_cast <index_t >(_begin.load (std::decay_t <ExecutionPolicy>{ policy } ));
689+ const index_t end = static_cast <index_t >(_end.load (std::decay_t <ExecutionPolicy>{ policy } ));
684690
685691 // Full, i.e. one large block and begin == end
686- if (full (std::forward <ExecutionPolicy>( policy) ))
692+ if (full (std::decay_t <ExecutionPolicy>{ policy } ))
687693 {
688- iota (std::forward <ExecutionPolicy>( policy) , device_begin (_range_indices), device_end (_range_indices), 0 );
694+ iota (std::decay_t <ExecutionPolicy>{ policy } , device_begin (_range_indices), device_end (_range_indices), 0 );
689695 }
690696 // One large block, including empty block
691697 else if (begin <= end)
692698 {
693- iota (std::forward <ExecutionPolicy>( policy) ,
699+ iota (std::decay_t <ExecutionPolicy>{ policy } ,
694700 device_begin (_range_indices),
695701 device_begin (_range_indices) + (end - begin),
696702 begin);
697703 }
698704 // Two disconnected blocks
699705 else
700706 {
701- iota (std::forward <ExecutionPolicy>( policy) ,
707+ iota (std::decay_t <ExecutionPolicy>{ policy } ,
702708 device_begin (_range_indices),
703709 device_begin (_range_indices) + end,
704710 0 );
705- iota (std::forward <ExecutionPolicy>( policy) ,
711+ iota (std::decay_t <ExecutionPolicy>{ policy } ,
706712 device_begin (_range_indices) + end,
707713 device_begin (_range_indices) + (end + capacity () - begin),
708714 begin);
@@ -726,7 +732,7 @@ template <typename ExecutionPolicy,
726732bool
727733deque<T, Allocator>::occupied_count_valid(ExecutionPolicy&& policy) const
728734{
729- index_t size_count = size (std::forward <ExecutionPolicy>( policy) );
735+ index_t size_count = size (std::decay_t <ExecutionPolicy>{ policy } );
730736 index_t size_sum = _occupied.count (std::forward<ExecutionPolicy>(policy));
731737
732738 return (size_count == size_sum);
0 commit comments