17 #include "LvArrayConfig.hpp" 24 namespace sortedArrayManipulation
30 constexpr
int INTROSORT_THRESHOLD = 64;
39 template<
class A,
class B >
40 struct DualIteratorAccessor
51 inline Temporary() =
delete;
56 inline Temporary( Temporary
const & ) =
delete;
64 m_a(
std::move( src.m_a )),
65 m_b(
std::move( src.m_b ))
74 m_a(
std::move( src.m_a )),
75 m_b(
std::move( src.m_b ))
82 inline ~Temporary() =
default;
88 inline Temporary & operator=( Temporary
const & ) =
delete;
94 inline Temporary & operator=( Temporary && ) =
delete;
106 DualIteratorAccessor() =
delete;
122 DualIteratorAccessor( DualIteratorAccessor
const & ) =
delete;
128 inline DualIteratorAccessor( DualIteratorAccessor && ) =
default;
134 DualIteratorAccessor & operator=( DualIteratorAccessor
const & ) =
delete;
144 m_a = std::move( src.m_a );
145 m_b = std::move( src.m_b );
157 m_a = std::move( src.m_a );
158 m_b = std::move( src.m_b );
177 template<
typename A,
typename B,
typename Compare >
178 struct DualIteratorComparator
197 DualIteratorAccessor< A, B >
const & rhs )
const 198 {
return m_compare( lhs.m_a, rhs.m_a ); }
207 LVARRAY_HOST_DEVICE inline bool operator()(
typename DualIteratorAccessor< A, B >::Temporary
const & lhs,
208 DualIteratorAccessor< A, B >
const & rhs )
const 209 {
return m_compare( lhs.m_a, rhs.m_a ); }
222 template<
class RandomAccessIteratorA,
class RandomAccessIteratorB >
227 using A =
typename std::remove_reference< decltype( *std::declval< RandomAccessIteratorA >() ) >::type;
230 using B =
typename std::remove_reference< decltype( *std::declval< RandomAccessIteratorB >() ) >::type;
236 inline DualIterator() =
default;
244 LVARRAY_HOST_DEVICE inline DualIterator( RandomAccessIteratorA
const itA, RandomAccessIteratorB
const itB ):
254 inline DualIterator( DualIterator
const & src ) =
default;
261 inline DualIterator( DualIterator && src ) =
default;
269 inline DualIterator & operator=( DualIterator
const & src ) =
default;
277 inline DualIterator & operator=( DualIterator && src ) =
default;
286 {
return DualIterator( m_itA + offset, m_itB + offset ); }
321 std::ptrdiff_t
const distance = m_itA - rhs.m_itA;
333 {
return *
this + (-offset); }
342 {
return *
this += (-offset); }
363 {
return m_itA != rhs.m_itA; }
372 {
return m_itA < rhs.m_itA; }
380 {
return DualIteratorAccessor< A, B >( *m_itA, *m_itB ); }
389 template<
class Compare >
390 LVARRAY_HOST_DEVICE inline DualIteratorComparator< A, B, Compare > createComparator( Compare && comp )
const 391 {
return DualIteratorComparator< A, B, Compare >( std::forward< Compare >( comp ) ); }
395 RandomAccessIteratorA m_itA;
398 RandomAccessIteratorB m_itB;
412 return std::move( a );
423 template<
class A,
class B >
424 inline LVARRAY_HOST_DEVICE typename DualIteratorAccessor< A, B >::Temporary createTemporary( DualIteratorAccessor< A, B > && it )
425 {
return typename DualIteratorAccessor< A, B >::Temporary( std::move( it )); }
434 template<
class Iterator >
437 auto temp = createTemporary( *a );
438 *a = std::move( *b );
439 *b = std::move( temp );
454 template<
class B
idirIt1,
class B
idirIt2 >
455 LVARRAY_HOST_DEVICE inline void moveBackward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last )
457 while( first != last )
459 *(--d_last) = std::move( *(--last));
477 template<
typename Iterator,
typename Compare >
478 LVARRAY_HOST_DEVICE inline void computeMedian( Iterator result, Iterator a, Iterator b, Iterator c, Compare && comp )
484 exchange( result, b );
486 else if( comp( *a, *c ))
488 exchange( result, c );
492 exchange( result, a );
495 else if( comp( *a, *c ))
497 exchange( result, a );
499 else if( comp( *b, *c ))
501 exchange( result, c );
505 exchange( result, b );
522 template<
typename RandomAccessIterator,
typename Compare >
523 LVARRAY_HOST_DEVICE inline RandomAccessIterator unguardedPartition( RandomAccessIterator first, RandomAccessIterator last,
524 RandomAccessIterator pivot, Compare && comp )
528 while( comp( *first, *pivot ))
534 while( comp( *pivot, *last ))
544 exchange( first, last );
561 template<
typename RandomAccessIterator,
typename Compare >
562 LVARRAY_HOST_DEVICE inline RandomAccessIterator unguardedPartitionPivot( RandomAccessIterator first, RandomAccessIterator last, Compare && comp )
564 RandomAccessIterator mid = first + (last - first) / 2;
565 computeMedian( first, first + 1, mid, last - 1, comp );
566 return unguardedPartition( first + 1, last, first, comp );
579 template<
typename RandomAccessIterator,
typename Compare >
580 LVARRAY_HOST_DEVICE inline void unguardedLinearInsert( RandomAccessIterator last, Compare comp )
582 auto val = createTemporary( *last );
583 RandomAccessIterator next = last - 1;
584 while( comp( val, *next ))
586 *last = std::move( *next );
590 *last = std::move( val );
605 template<
class RandomAccessIterator,
class Compare >
606 LVARRAY_HOST_DEVICE inline void insertionSort( RandomAccessIterator first, std::ptrdiff_t
const n, Compare comp )
608 for( std::ptrdiff_t i = 1; i < n; ++i )
610 if( comp( *(first + i), *first ))
612 auto val = createTemporary( *(first + i));
613 moveBackward( first, first + i, first + i + 1 );
614 *first = std::move( val );
618 unguardedLinearInsert( first + i, comp );
640 template<
typename RandomAccessIterator,
typename Compare >
641 LVARRAY_HOST_DEVICE inline void introsortLoop( RandomAccessIterator first, RandomAccessIterator last, Compare && comp )
643 constexpr
int MAX_RANGES = 31;
644 RandomAccessIterator ranges[MAX_RANGES + 1];
649 while( nRanges != 0 )
651 RandomAccessIterator
const m_first = ranges[nRanges - 1];
653 if( ranges[nRanges] - m_first > INTROSORT_THRESHOLD )
656 ranges[nRanges + 1] = ranges[nRanges];
657 ranges[nRanges] = unguardedPartitionPivot( m_first, ranges[nRanges], comp );
#define LVARRAY_ASSERT(EXP)
Assert EXP is true with no message.
bool operator!=(InputFlags const left, InputFlags const right)
Comparison operator for InputFlags enumeration.
bool operator<(InputFlags const left, InputFlags const right)
Comparison operator for InputFlags enumeration.
Contains a bunch of macro definitions.
#define DISABLE_HD_WARNING
Disable host device warnings.
#define LVARRAY_ASSERT_EQ(lhs, rhs)
Assert that two values compare equal in debug builds.
#define LVARRAY_HOST_DEVICE
Mark a function for both host and device usage.