UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
IntroSort.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
7#include "Templates/IdentityFunctor.h"
8#include "Templates/Invoke.h" // for older _MSC_FULL_VER only - see usage below
10#include "Templates/Less.h"
11#include "Templates/UnrealTemplate.h" // For GetData, GetNum
12
13
14namespace AlgoImpl
15{
26 template <typename T, typename IndexType, typename ProjectionType, typename PredicateType>
28 {
29 struct FStack
30 {
31 T* Min;
32 T* Max;
33 uint32 MaxDepth;
34 };
35
36 if( Num < 2 )
37 {
38 return;
39 }
40
41 FStack RecursionStack[32]={{First, First+Num-1, (uint32)(FMath::Loge((float)Num) * 2.f)}}, Current, Inner;
42 for( FStack* StackTop=RecursionStack; StackTop>=RecursionStack; --StackTop ) //-V625
43 {
45
46 Loop:
47 IndexType Count = (IndexType)(Current.Max - Current.Min + 1);
48
49 if ( Current.MaxDepth == 0 )
50 {
51 // We're too deep into quick sort, switch to heap sort
52 HeapSortInternal( Current.Min, Count, Proj, Predicate );
53 continue;
54 }
55
56 if( Count <= 8 )
57 {
58 // Use simple bubble-sort.
59 while( Current.Max > Current.Min )
60 {
61 T *Max, *Item;
62 for( Max=Current.Min, Item=Current.Min+1; Item<=Current.Max; Item++ )
63 {
64// Workaround for a codegen bug that was discovered related to member function pointer projections that are virtual
65#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 194134123
66 if( Invoke( Predicate, Invoke( Proj, *Max ), Invoke( Proj, *Item ) ) )
67#else
68 if( Predicate( Proj( *Max ), Proj( *Item ) ) )
69#endif
70 {
71 Max = Item;
72 }
73 }
74 Swap( *Max, *Current.Max-- );
75 }
76 }
77 else
78 {
79 // Grab middle element so sort doesn't exhibit worst-cast behavior with presorted lists.
80 Swap( Current.Min[Count/2], Current.Min[0] );
81
82 // Divide list into two halves, one with items <=Current.Min, the other with items >Current.Max.
83 Inner.Min = Current.Min;
84 Inner.Max = Current.Max+1;
85 for( ; ; )
86 {
87// Workaround for a codegen bug that was discovered related to member function pointer projections that are virtual
88#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 194134123
89 while( ++Inner.Min<=Current.Max && !Invoke( Predicate, Invoke( Proj, *Current.Min ), Invoke( Proj, *Inner.Min ) ) );
90 while( --Inner.Max> Current.Min && !Invoke( Predicate, Invoke( Proj, *Inner.Max ), Invoke( Proj, *Current.Min ) ) );
91#else
92 while( ++Inner.Min<=Current.Max && !Predicate( Proj( *Current.Min ), Proj( *Inner.Min ) ) );
93 while( --Inner.Max> Current.Min && !Predicate( Proj( *Inner.Max ), Proj( *Current.Min ) ) );
94#endif
95 if( Inner.Min>Inner.Max )
96 {
97 break;
98 }
99 Swap( *Inner.Min, *Inner.Max );
100 }
101 Swap( *Current.Min, *Inner.Max );
102
103 --Current.MaxDepth;
104
105 // Save big half and recurse with small half.
106 if( Inner.Max-1-Current.Min >= Current.Max-Inner.Min )
107 {
108 if( Current.Min+1 < Inner.Max )
109 {
110 StackTop->Min = Current.Min;
111 StackTop->Max = Inner.Max - 1;
112 StackTop->MaxDepth = Current.MaxDepth;
113 StackTop++;
114 }
115 if( Current.Max>Inner.Min )
116 {
117 Current.Min = Inner.Min;
118 goto Loop;
119 }
120 }
121 else
122 {
123 if( Current.Max>Inner.Min )
124 {
125 StackTop->Min = Inner .Min;
126 StackTop->Max = Current.Max;
127 StackTop->MaxDepth = Current.MaxDepth;
128 StackTop++;
129 }
130 if( Current.Min+1<Inner.Max )
131 {
132 Current.Max = Inner.Max - 1;
133 goto Loop;
134 }
135 }
136 }
137 }
138 }
139}
140
141namespace Algo
142{
148 template <typename RangeType>
149 UE_REWRITE void IntroSort(RangeType&& Range)
150 {
152 }
153
160 template <typename RangeType, typename PredicateType>
161 UE_REWRITE void IntroSort(RangeType&& Range, PredicateType Predicate)
162 {
164 }
165
172 template <typename RangeType, typename ProjectionType>
173 UE_REWRITE void IntroSortBy(RangeType&& Range, ProjectionType Proj)
174 {
175// Workaround for a codegen bug that was discovered related to member function pointer projections that are virtual
176#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 194134123
178#else
180#endif
181 }
182
190 template <typename RangeType, typename ProjectionType, typename PredicateType>
191 UE_REWRITE void IntroSortBy(RangeType&& Range, ProjectionType Proj, PredicateType Predicate)
192 {
193// Workaround for a codegen bug that was discovered related to member function pointer projections that are virtual
194#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 194134123
195 AlgoImpl::IntroSortInternal(GetData(Range), GetNum(Range), MoveTemp(Proj), MoveTemp(Predicate));
196#else
198#endif
199 }
200}
201
202#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_6
203#include "Templates/Invoke.h"
204#endif
#define UE_REWRITE
Definition Platform.h:747
AUTORTFM_INFER UE_FORCEINLINE_HINT constexpr auto Invoke(FuncType &&Func, ArgTypes &&... Args) -> decltype(((FuncType &&) Func)((ArgTypes &&) Args...))
Definition Invoke.h:44
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
@ Num
Definition MetalRHIPrivate.h:234
AUTORTFM_INFER constexpr auto Projection(Invocable0Type &&Invocable0, InvocableTypes &&... Invocables)
Definition Projection.h:108
auto GetNum(const TStringConversion< Converter, DefaultConversionSize > &Conversion) -> decltype(Conversion.Length())
Definition StringConv.h:808
auto GetData(const TStringConversion< Converter, DefaultConversionSize > &Conversion) -> decltype(Conversion.Get())
Definition StringConv.h:802
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition BinarySearch.h:10
void HeapSortInternal(RangeValueType *First, IndexType Num, ProjectionType Proj, PredicateType Predicate)
Definition BinaryHeap.h:181
void IntroSortInternal(T *First, IndexType Num, ProjectionType Proj, PredicateType Predicate)
Definition IntroSort.h:27
Definition ParallelSort.h:13
UE_REWRITE void IntroSort(RangeType &&Range)
Definition IntroSort.h:149
UE_REWRITE void IntroSortBy(RangeType &&Range, ProjectionType Proj)
Definition IntroSort.h:173
Definition IdentityFunctor.h:11
Definition Less.h:19