17 #ifndef INC_KY_Kernel_Alg_H
18 #define INC_KY_Kernel_Alg_H
23 namespace Kaim {
namespace Alg {
28 template <
typename T> KY_INLINE
void Swap(T &a, T &b)
29 { T temp(a); a = b; b = temp; }
32 template <
typename T1,
typename T2> KY_INLINE
void Swap(Pair<T1, T2>& l, Pair<T1, T2>& r)
33 { Swap(l.First, r.First); Swap(l.Second, r.Second); }
37 template <
typename T> KY_INLINE
const T Min(
const T a,
const T b)
38 {
return (a < b) ? a : b; }
40 template <
typename T> KY_INLINE
const T Max(
const T a,
const T b)
41 {
return (b < a) ? a : b; }
43 template <
typename T> KY_INLINE
const T Clamp(
const T v,
const T minVal,
const T maxVal)
44 {
return Max<T>(minVal, Min<T>(v, maxVal)); }
46 template <
typename T> KY_INLINE
int Chop(T f)
49 template <
typename T> KY_INLINE T Lerp(T a, T b, T f)
50 {
return (b - a) * f + a; }
52 template <
typename T> KY_INLINE
int IRound(
const T a)
53 {
return (a > 0.0) ? (int)(a + 0.5) : (int)(a - 0.5); }
55 template <
typename T> KY_INLINE
unsigned URound(
const T a)
56 {
return (
unsigned)(a + 0.5); }
63 template <
typename T> KY_INLINE
const T PMin(
const T a,
const T b)
65 KY_COMPILER_ASSERT(
sizeof(T) ==
sizeof(UPInt));
66 return (a < b) ? a : b;
68 template <
typename T> KY_INLINE
const T PMax(
const T a,
const T b)
70 KY_COMPILER_ASSERT(
sizeof(T) ==
sizeof(UPInt));
71 return (b < a) ? a : b;
75 inline bool IsMax(UPInt v) {
return v == KY_MAX_UPINT; }
76 #ifdef KY_64BIT_POINTERS
77 inline bool IsMax(
unsigned v) {
return v == KY_MAX_UINT; }
82 template <
typename T> KY_INLINE
const T Abs(
const T v)
83 {
return (v>=0) ? v : -v; }
89 template<
class T>
struct OperatorLess
91 static bool Compare(
const T& a,
const T& b)
109 template<
class Array,
class Less>
110 void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less)
117 if(end - start < 2)
return;
121 SPInt base = (SPInt)start;
122 SPInt limit = (SPInt)end;
126 SPInt len = limit - base;
132 pivot = base + len / 2;
133 Swap(arr[base], arr[pivot]);
139 if(less(arr[j], arr[i])) Swap(arr[j], arr[i]);
140 if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
141 if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
145 do i++;
while( less(arr[i], arr[base]) );
146 do j--;
while( less(arr[base], arr[j]) );
153 Swap(arr[i], arr[j]);
156 Swap(arr[base], arr[j]);
159 if(j - base > limit - i)
179 for(; i < limit; j = i, i++)
181 for(; less(arr[j + 1], arr[j]); j--)
183 Swap(arr[j + 1], arr[j]);
210 template<
class Array>
211 void QuickSortSliced(Array& arr, UPInt start, UPInt end)
213 typedef typename Array::ValueType ValueType;
214 QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
219 template<
class Array,
class Less>
220 bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end, Less less)
227 if(end - start < 2)
return true;
231 SPInt base = (SPInt)start;
232 SPInt limit = (SPInt)end;
236 SPInt len = limit - base;
242 pivot = base + len / 2;
243 Swap(arr[base], arr[pivot]);
249 if(less(arr[j], arr[i])) Swap(arr[j], arr[i]);
250 if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
251 if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
260 }
while( less(arr[i], arr[base]) );
266 }
while( less(arr[base], arr[j]) );
273 Swap(arr[i], arr[j]);
276 Swap(arr[base], arr[j]);
279 if(j - base > limit - i)
299 for(; i < limit; j = i, i++)
301 for(; less(arr[j + 1], arr[j]); j--)
303 Swap(arr[j + 1], arr[j]);
325 template<
class Array>
326 bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end)
328 typedef typename Array::ValueType ValueType;
329 return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare);
339 template<
class Array,
class Less>
340 void QuickSort(Array& arr, Less less)
342 QuickSortSliced(arr, 0, arr.GetSize(), less);
346 template<
class Array,
class Less>
347 bool QuickSortSafe(Array& arr, Less less)
349 return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less);
359 template<
class Array>
360 void QuickSort(Array& arr)
362 typedef typename Array::ValueType ValueType;
363 QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
366 template<
class Array>
367 bool QuickSortSafe(Array& arr)
369 typedef typename Array::ValueType ValueType;
370 return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
384 template<
class Array,
class Less>
385 void InsertionSortSliced(Array& arr, UPInt start, UPInt end, Less less)
391 for(; i < limit; j = i, i++)
393 for(; less(arr[j + 1], arr[j]); j--)
395 Swap(arr[j + 1], arr[j]);
413 template<
class Array>
414 void InsertionSortSliced(Array& arr, UPInt start, UPInt end)
416 typedef typename Array::ValueType ValueType;
417 InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
427 template<
class Array,
class Less>
428 void InsertionSort(Array& arr, Less less)
430 InsertionSortSliced(arr, 0, arr.GetSize(), less);
440 template<
class Array>
441 void InsertionSort(Array& arr)
443 typedef typename Array::ValueType ValueType;
444 InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
453 template<
class Array,
class Value,
class Less>
454 UPInt LowerBoundSliced(
const Array& arr, UPInt start, UPInt end,
const Value& val, Less less)
456 SPInt first = (SPInt)start;
457 SPInt len = (SPInt)(end - start);
464 middle = first + half;
465 if(less(arr[middle], val))
468 len = len - half - 1;
482 template<
class Array,
class Value>
483 UPInt LowerBoundSliced(
const Array& arr, UPInt start, UPInt end,
const Value& val)
485 return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
492 template<
class Array,
class Value>
493 UPInt LowerBoundSized(
const Array& arr, UPInt size,
const Value& val)
495 return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
502 template<
class Array,
class Value,
class Less>
503 UPInt LowerBound(
const Array& arr,
const Value& val, Less less)
505 return LowerBoundSliced(arr, 0, arr.GetSize(), val, less);
512 template<
class Array,
class Value>
513 UPInt LowerBound(
const Array& arr,
const Value& val)
515 return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
524 template<
class Array,
class Value,
class Less>
525 UPInt UpperBoundSliced(
const Array& arr, UPInt start, UPInt end,
const Value& val, Less less)
527 SPInt first = (SPInt)start;
528 SPInt len = (SPInt)(end - start);
535 middle = first + half;
536 if(less(val, arr[middle]))
543 len = len - half - 1;
553 template<
class Array,
class Value>
554 UPInt UpperBoundSliced(
const Array& arr, UPInt start, UPInt end,
const Value& val)
556 return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
563 template<
class Array,
class Value>
564 UPInt UpperBoundSized(
const Array& arr, UPInt size,
const Value& val)
566 return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
573 template<
class Array,
class Value,
class Less>
574 UPInt UpperBound(
const Array& arr,
const Value& val, Less less)
576 return UpperBoundSliced(arr, 0, arr.GetSize(), val, less);
583 template<
class Array,
class Value>
584 UPInt UpperBound(
const Array& arr,
const Value& val)
586 return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
593 template<
class Array>
void ReverseArray(Array& arr)
596 SPInt to = arr.GetSize() - 1;
599 Swap(arr[from], arr[to]);
609 template<
class CDst,
class CSrc>
610 void AppendArray(CDst& dst,
const CSrc& src)
613 for(i = 0; i < src.GetSize(); i++)
614 dst.PushBack(src[i]);
623 template<
class T>
class ArrayAdaptor
627 ArrayAdaptor() : Data(0), Size(0) {}
628 ArrayAdaptor(T* ptr, UPInt size) : Data(ptr), Size(size) {}
629 UPInt GetSize()
const {
return Size; }
630 const T& operator [] (UPInt i)
const {
return Data[i]; }
631 T& operator [] (UPInt i) {
return Data[i]; }
643 template<
class T>
class ConstArrayAdaptor
647 ConstArrayAdaptor() : Data(0), Size(0) {}
648 ConstArrayAdaptor(
const T* ptr, UPInt size) : Data(ptr), Size(size) {}
649 UPInt GetSize()
const {
return Size; }
650 const T& operator [] (UPInt i)
const {
return Data[i]; }
659 extern const UByte UpperBitTable[256];
660 extern const UByte LowerBitTable[256];
665 inline UByte UpperBit(UPInt val)
667 #ifndef KY_64BIT_POINTERS
669 if (val & 0xFFFF0000)
671 return (val & 0xFF000000) ?
672 UpperBitTable[(val >> 24) ] + 24:
673 UpperBitTable[(val >> 16) & 0xFF] + 16;
675 return (val & 0xFF00) ?
676 UpperBitTable[(val >> 8) & 0xFF] + 8:
677 UpperBitTable[(val ) & 0xFF];
681 if (val & 0xFFFFFFFF00000000)
683 if (val & 0xFFFF000000000000)
685 return (val & 0xFF00000000000000) ?
686 UpperBitTable[(val >> 56) ] + 56:
687 UpperBitTable[(val >> 48) & 0xFF] + 48;
689 return (val & 0xFF0000000000) ?
690 UpperBitTable[(val >> 40) & 0xFF] + 40:
691 UpperBitTable[(val >> 32) & 0xFF] + 32;
695 if (val & 0xFFFF0000)
697 return (val & 0xFF000000) ?
698 UpperBitTable[(val >> 24) ] + 24:
699 UpperBitTable[(val >> 16) & 0xFF] + 16;
701 return (val & 0xFF00) ?
702 UpperBitTable[(val >> 8) & 0xFF] + 8:
703 UpperBitTable[(val ) & 0xFF];
710 inline UByte LowerBit(UPInt val)
712 #ifndef KY_64BIT_POINTERS
716 return (val & 0xFF) ?
717 LowerBitTable[ val & 0xFF]:
718 LowerBitTable[(val >> 8) & 0xFF] + 8;
720 return (val & 0xFF0000) ?
721 LowerBitTable[(val >> 16) & 0xFF] + 16:
722 LowerBitTable[(val >> 24) & 0xFF] + 24;
726 if (val & 0xFFFFFFFF)
730 return (val & 0xFF) ?
731 LowerBitTable[ val & 0xFF]:
732 LowerBitTable[(val >> 8) & 0xFF] + 8;
734 return (val & 0xFF0000) ?
735 LowerBitTable[(val >> 16) & 0xFF] + 16:
736 LowerBitTable[(val >> 24) & 0xFF] + 24;
740 if (val & 0xFFFF00000000)
742 return (val & 0xFF00000000) ?
743 LowerBitTable[(val >> 32) & 0xFF] + 32:
744 LowerBitTable[(val >> 40) & 0xFF] + 40;
746 return (val & 0xFF000000000000) ?
747 LowerBitTable[(val >> 48) & 0xFF] + 48:
748 LowerBitTable[(val >> 56) & 0xFF] + 56;
763 static void* Copy (
void* pdest,
const void* psrc, UPInt byteCount) {
return memcpy(pdest, psrc, byteCount); }
764 static void* Copy16(
void* pdest,
const void* psrc, UPInt int16Count) {
return memcpy(pdest, psrc, int16Count*2); }
765 static void* Copy32(
void* pdest,
const void* psrc, UPInt int32Count) {
return memcpy(pdest, psrc, int32Count*4); }
766 static void* Copy64(
void* pdest,
const void* psrc, UPInt int64Count) {
return memcpy(pdest, psrc, int64Count*8); }
769 static void* Move (
void* pdest,
const void* psrc, UPInt byteCount) {
return memmove(pdest, psrc, byteCount); }
770 static void* Move16(
void* pdest,
const void* psrc, UPInt int16Count) {
return memmove(pdest, psrc, int16Count*2); }
771 static void* Move32(
void* pdest,
const void* psrc, UPInt int32Count) {
return memmove(pdest, psrc, int32Count*4); }
772 static void* Move64(
void* pdest,
const void* psrc, UPInt int64Count) {
return memmove(pdest, psrc, int64Count*8); }
775 static int Cmp (
const void* p1,
const void* p2, UPInt byteCount) {
return memcmp(p1, p2, byteCount); }
776 static int Cmp16(
const void* p1,
const void* p2, UPInt int16Count);
777 static int Cmp32(
const void* p1,
const void* p2, UPInt int32Count);
778 static int Cmp64(
const void* p1,
const void* p2, UPInt int64Count);
781 static void Set (
void* pdest,
int value, UPInt byteCount) { memset(pdest, value, byteCount); }
786 inline int MemUtil::Cmp16(
const void* p1,
const void* p2, UPInt int16Count)
793 while (pa[ic] == pb[ic])
794 if (++ic==int16Count)
796 return pa[ic] > pb[ic] ? 1 : -1;
799 inline int MemUtil::Cmp32(
const void* p1,
const void* p2, UPInt int32Count)
806 while (pa[ic] == pb[ic])
807 if (++ic==int32Count)
809 return pa[ic] > pb[ic] ? 1 : -1;
811 inline int MemUtil::Cmp64(
const void* p1,
const void* p2, UPInt int64Count)
818 while (pa[ic] == pb[ic])
819 if (++ic==int64Count)
821 return pa[ic] > pb[ic] ? 1 : -1;
834 inline void SwapOrder(
void* pv,
int size)
838 for (
int i = 0; i < size>>1; i++)
841 pb[size-1-i] = pb[i];
851 inline UInt32 SwapOrder(
UInt32 v) {
return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); }
856 ((v&KY_UINT64(0x00FF000000000000))>>40) |
857 ((v&KY_UINT64(0x0000FF0000000000))>>24) |
858 ((v&KY_UINT64(0x000000FF00000000))>>8) |
859 ((v&KY_UINT64(0x00000000FF000000))<<8) |
860 ((v&KY_UINT64(0x0000000000FF0000))<<24) |
861 ((v&KY_UINT64(0x000000000000FF00))<<40) |
865 inline float SwapOrder(
float p)
872 u.v = SwapOrder(u.v);
876 inline double SwapOrder(
double p)
883 u.v = SwapOrder(u.v);
889 #if (KY_BYTE_ORDER == KY_LITTLE_ENDIAN)
891 inline UInt8 LEToSystem(
UInt8 v) {
return v; }
892 inline SInt8 LEToSystem(
SInt8 v) {
return v; }
899 inline float LEToSystem(
float v) {
return v; }
900 inline double LEToSystem(
double v) {
return v; }
902 inline UInt8 BEToSystem(
UInt8 v) {
return SwapOrder(v); }
903 inline SInt8 BEToSystem(
SInt8 v) {
return SwapOrder(v); }
904 inline UInt16 BEToSystem(
UInt16 v) {
return SwapOrder(v); }
905 inline SInt16 BEToSystem(
SInt16 v) {
return SwapOrder(v); }
906 inline UInt32 BEToSystem(
UInt32 v) {
return SwapOrder(v); }
907 inline SInt32 BEToSystem(
SInt32 v) {
return SwapOrder(v); }
908 inline UInt64 BEToSystem(
UInt64 v) {
return SwapOrder(v); }
909 inline SInt64 BEToSystem(
SInt64 v) {
return SwapOrder(v); }
910 inline float BEToSystem(
float v) {
return SwapOrder(v); }
911 inline double BEToSystem(
double v) {
return SwapOrder(v); }
913 inline UInt8 SystemToLE(
UInt8 v) {
return v; }
914 inline SInt8 SystemToLE(
SInt8 v) {
return v; }
921 inline float SystemToLE(
float v) {
return v; }
922 inline double SystemToLE(
double v) {
return v; }
924 inline UInt8 SystemToBE(
UInt8 v) {
return SwapOrder(v); }
925 inline SInt8 SystemToBE(
SInt8 v) {
return SwapOrder(v); }
926 inline UInt16 SystemToBE(
UInt16 v) {
return SwapOrder(v); }
927 inline SInt16 SystemToBE(
SInt16 v) {
return SwapOrder(v); }
928 inline UInt32 SystemToBE(
UInt32 v) {
return SwapOrder(v); }
929 inline SInt32 SystemToBE(
SInt32 v) {
return SwapOrder(v); }
930 inline UInt64 SystemToBE(
UInt64 v) {
return SwapOrder(v); }
931 inline SInt64 SystemToBE(
SInt64 v) {
return SwapOrder(v); }
932 inline float SystemToBE(
float v) {
return SwapOrder(v); }
933 inline double SystemToBE(
double v) {
return SwapOrder(v); }
935 #elif (KY_BYTE_ORDER == KY_BIG_ENDIAN)
937 inline UInt8 LEToSystem(
UInt8 v) {
return SwapOrder(v); }
938 inline SInt8 LEToSystem(
SInt8 v) {
return SwapOrder(v); }
939 inline UInt16 LEToSystem(
UInt16 v) {
return SwapOrder(v); }
940 inline SInt16 LEToSystem(
SInt16 v) {
return SwapOrder(v); }
941 inline UInt32 LEToSystem(
UInt32 v) {
return SwapOrder(v); }
942 inline SInt32 LEToSystem(
SInt32 v) {
return SwapOrder(v); }
943 inline UInt64 LEToSystem(
UInt64 v) {
return SwapOrder(v); }
944 inline SInt64 LEToSystem(
SInt64 v) {
return SwapOrder(v); }
945 inline float LEToSystem(
float v) {
return SwapOrder(v); }
946 inline double LEToSystem(
double v) {
return SwapOrder(v); }
948 inline UInt8 BEToSystem(
UInt8 v) {
return v; }
949 inline SInt8 BEToSystem(
SInt8 v) {
return v; }
956 inline float BEToSystem(
float v) {
return v; }
957 inline double BEToSystem(
double v) {
return v; }
959 inline UInt8 SystemToLE(
UInt8 v) {
return SwapOrder(v); }
960 inline SInt8 SystemToLE(
SInt8 v) {
return SwapOrder(v); }
961 inline UInt16 SystemToLE(
UInt16 v) {
return SwapOrder(v); }
962 inline SInt16 SystemToLE(
SInt16 v) {
return SwapOrder(v); }
963 inline UInt32 SystemToLE(
UInt32 v) {
return SwapOrder(v); }
964 inline SInt32 SystemToLE(
SInt32 v) {
return SwapOrder(v); }
965 inline UInt64 SystemToLE(
UInt64 v) {
return SwapOrder(v); }
966 inline SInt64 SystemToLE(
SInt64 v) {
return SwapOrder(v); }
967 inline float SystemToLE(
float v) {
return SwapOrder(v); }
968 inline double SystemToLE(
double v) {
return SwapOrder(v); }
970 inline UInt8 SystemToBE(
UInt8 v) {
return v; }
971 inline SInt8 SystemToBE(
SInt8 v) {
return v; }
978 inline float SystemToBE(
float v) {
return v; }
979 inline double SystemToBE(
double v) {
return v; }
982 #error "! KY_BYTE_ORDER must be defined to KY_LITTLE_ENDIAN or KY_BIG_ENDIAN !"
989 inline UInt8 Cardinality(T v)
991 const T MASK_01010101 = (((T)(-1))/3);
992 const T MASK_00110011 = (((T)(-1))/5);
993 const T MASK_00001111 = (((T)(-1))/17);
995 v = (v & MASK_01010101) + ((v >> 1) & MASK_01010101) ;
996 v = (v & MASK_00110011) + ((v >> 2) & MASK_00110011) ;
997 v = (v & MASK_00001111) + ((v >> 4) & MASK_00001111) ;
998 return (
UInt8)(v % 255);
1006 ((value < 1UL<<15) ?
1009 ((value < 1UL<<1) ? ((value < 1UL<<0) ? 0 : 1) : ((value < 1UL<<2) ? 2 : 3)) :
1010 ((value < 1UL<<5) ? ((value < 1UL<<4) ? 4 : 5) : ((value < 1UL<<6) ? 6 : 7))) :
1011 ((value < 1UL<<11) ?
1012 ((value < 1UL<<9) ? ((value < 1UL<<8) ? 8 : 9) : ((value < 1UL<<10) ? 10 : 11)) :
1013 ((value < 1UL<<13) ? ((value < 1UL<<12) ? 12 : 13) : ((value < 1UL<<14) ? 14 : 15)))) :
1014 ((value < 1UL<<23) ?
1015 ((value < 1UL<<19) ?
1016 ((value < 1UL<<17) ? ((value < 1UL<<16) ? 16 : 17) : ((value < 1UL<<18) ? 18 : 19)) :
1017 ((value < 1UL<<21) ? ((value < 1UL<<20) ? 20 : 21) : ((value < 1UL<<22) ? 22 : 23))) :
1018 ((value < 1UL<<27) ?
1019 ((value < 1UL<<25) ? ((value < 1UL<<24) ? 24 : 25) : ((value < 1UL<<26) ? 26 : 27)) :
1020 ((value < 1UL<<29) ? ((value < 1UL<<28) ? 28 : 29) : ((value < 1UL<<30) ? 30 :
1021 ((value < 1UL<<31) ? 31 : 32))))));
std::int64_t SInt64
int64_t
Definition: SF_Types.h:132
std::uint16_t UInt16
uint16_t
Definition: SF_Types.h:136
std::uint8_t UByte
uint8_t
Definition: SF_Types.h:134
std::int32_t SInt32
int32_t
Definition: SF_Types.h:131
std::uint32_t UInt32
uint32_t
Definition: SF_Types.h:137
std::int8_t SInt8
int8_t
Definition: SF_Types.h:129
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
std::uint8_t UInt8
uint8_t
Definition: SF_Types.h:135
std::uint64_t UInt64
uint64_t
Definition: SF_Types.h:138
std::int16_t SInt16
int16_t
Definition: SF_Types.h:130