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); }
789 inline int MemUtil::Cmp16(
const void* p1,
const void* p2, UPInt int16Count)
791 SInt16* pa = (SInt16*)p1;
792 SInt16* pb = (SInt16*)p2;
796 while (pa[ic] == pb[ic])
797 if (++ic==int16Count)
799 return pa[ic] > pb[ic] ? 1 : -1;
801 inline int MemUtil::Cmp32(
const void* p1,
const void* p2, UPInt int32Count)
803 SInt32* pa = (SInt32*)p1;
804 SInt32* pb = (SInt32*)p2;
808 while (pa[ic] == pb[ic])
809 if (++ic==int32Count)
811 return pa[ic] > pb[ic] ? 1 : -1;
813 inline int MemUtil::Cmp64(
const void* p1,
const void* p2, UPInt int64Count)
815 SInt64* pa = (SInt64*)p1;
816 SInt64* pb = (SInt64*)p2;
820 while (pa[ic] == pb[ic])
821 if (++ic==int64Count)
823 return pa[ic] > pb[ic] ? 1 : -1;
836 inline void SwapOrder(
void* pv,
int size)
838 UByte* pb = (UByte*)pv;
840 for (
int i = 0; i < size>>1; i++)
843 pb[size-1-i] = pb[i];
849 inline UInt8 SwapOrder(UInt8 v) {
return v; }
850 inline SInt8 SwapOrder(SInt8 v) {
return v; }
851 inline UInt16 SwapOrder(UInt16 v) {
return UInt16(v>>8)|UInt16(v<<8); }
852 inline SInt16 SwapOrder(SInt16 v) {
return SInt16((UInt16(v)>>8)|(v<<8)); }
853 inline UInt32 SwapOrder(UInt32 v) {
return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); }
854 inline SInt32 SwapOrder(SInt32 p) {
return (SInt32)SwapOrder(UInt32(p)); }
855 inline UInt64 SwapOrder(UInt64 v)
858 ((v&KY_UINT64(0x00FF000000000000))>>40) |
859 ((v&KY_UINT64(0x0000FF0000000000))>>24) |
860 ((v&KY_UINT64(0x000000FF00000000))>>8) |
861 ((v&KY_UINT64(0x00000000FF000000))<<8) |
862 ((v&KY_UINT64(0x0000000000FF0000))<<24) |
863 ((v&KY_UINT64(0x000000000000FF00))<<40) |
866 inline SInt64 SwapOrder(SInt64 v) {
return (SInt64)SwapOrder(UInt64(v)); }
867 inline float SwapOrder(
float p)
874 u.v = SwapOrder(u.v);
879 inline Double SwapOrder(Double p)
886 u.v = SwapOrder(u.v);
893 #if (KY_BYTE_ORDER == KY_LITTLE_ENDIAN)
895 inline UInt8 LEToSystem(UInt8 v) {
return v; }
896 inline SInt8 LEToSystem(SInt8 v) {
return v; }
897 inline UInt16 LEToSystem(UInt16 v) {
return v; }
898 inline SInt16 LEToSystem(SInt16 v) {
return v; }
899 inline UInt32 LEToSystem(UInt32 v) {
return v; }
900 inline SInt32 LEToSystem(SInt32 v) {
return v; }
901 inline UInt64 LEToSystem(UInt64 v) {
return v; }
902 inline SInt64 LEToSystem(SInt64 v) {
return v; }
903 inline float LEToSystem(
float v) {
return v; }
905 inline Double LEToSystem(Double v) {
return v; }
908 inline UInt8 BEToSystem(UInt8 v) {
return SwapOrder(v); }
909 inline SInt8 BEToSystem(SInt8 v) {
return SwapOrder(v); }
910 inline UInt16 BEToSystem(UInt16 v) {
return SwapOrder(v); }
911 inline SInt16 BEToSystem(SInt16 v) {
return SwapOrder(v); }
912 inline UInt32 BEToSystem(UInt32 v) {
return SwapOrder(v); }
913 inline SInt32 BEToSystem(SInt32 v) {
return SwapOrder(v); }
914 inline UInt64 BEToSystem(UInt64 v) {
return SwapOrder(v); }
915 inline SInt64 BEToSystem(SInt64 v) {
return SwapOrder(v); }
916 inline float BEToSystem(
float v) {
return SwapOrder(v); }
918 inline Double BEToSystem(Double v) {
return SwapOrder(v); }
921 inline UInt8 SystemToLE(UInt8 v) {
return v; }
922 inline SInt8 SystemToLE(SInt8 v) {
return v; }
923 inline UInt16 SystemToLE(UInt16 v) {
return v; }
924 inline SInt16 SystemToLE(SInt16 v) {
return v; }
925 inline UInt32 SystemToLE(UInt32 v) {
return v; }
926 inline SInt32 SystemToLE(SInt32 v) {
return v; }
927 inline UInt64 SystemToLE(UInt64 v) {
return v; }
928 inline SInt64 SystemToLE(SInt64 v) {
return v; }
929 inline float SystemToLE(
float v) {
return v; }
931 inline Double SystemToLE(Double v) {
return v; }
934 inline UInt8 SystemToBE(UInt8 v) {
return SwapOrder(v); }
935 inline SInt8 SystemToBE(SInt8 v) {
return SwapOrder(v); }
936 inline UInt16 SystemToBE(UInt16 v) {
return SwapOrder(v); }
937 inline SInt16 SystemToBE(SInt16 v) {
return SwapOrder(v); }
938 inline UInt32 SystemToBE(UInt32 v) {
return SwapOrder(v); }
939 inline SInt32 SystemToBE(SInt32 v) {
return SwapOrder(v); }
940 inline UInt64 SystemToBE(UInt64 v) {
return SwapOrder(v); }
941 inline SInt64 SystemToBE(SInt64 v) {
return SwapOrder(v); }
942 inline float SystemToBE(
float v) {
return SwapOrder(v); }
944 inline Double SystemToBE(Double v) {
return SwapOrder(v); }
947 #elif (KY_BYTE_ORDER == KY_BIG_ENDIAN)
949 inline UInt8 LEToSystem(UInt8 v) {
return SwapOrder(v); }
950 inline SInt8 LEToSystem(SInt8 v) {
return SwapOrder(v); }
951 inline UInt16 LEToSystem(UInt16 v) {
return SwapOrder(v); }
952 inline SInt16 LEToSystem(SInt16 v) {
return SwapOrder(v); }
953 inline UInt32 LEToSystem(UInt32 v) {
return SwapOrder(v); }
954 inline SInt32 LEToSystem(SInt32 v) {
return SwapOrder(v); }
955 inline UInt64 LEToSystem(UInt64 v) {
return SwapOrder(v); }
956 inline SInt64 LEToSystem(SInt64 v) {
return SwapOrder(v); }
957 inline float LEToSystem(
float v) {
return SwapOrder(v); }
959 inline Double LEToSystem(Double v) {
return SwapOrder(v); }
962 inline UInt8 BEToSystem(UInt8 v) {
return v; }
963 inline SInt8 BEToSystem(SInt8 v) {
return v; }
964 inline UInt16 BEToSystem(UInt16 v) {
return v; }
965 inline SInt16 BEToSystem(SInt16 v) {
return v; }
966 inline UInt32 BEToSystem(UInt32 v) {
return v; }
967 inline SInt32 BEToSystem(SInt32 v) {
return v; }
968 inline UInt64 BEToSystem(UInt64 v) {
return v; }
969 inline SInt64 BEToSystem(SInt64 v) {
return v; }
970 inline float BEToSystem(
float v) {
return v; }
972 inline Double BEToSystem(Double v) {
return v; }
975 inline UInt8 SystemToLE(UInt8 v) {
return SwapOrder(v); }
976 inline SInt8 SystemToLE(SInt8 v) {
return SwapOrder(v); }
977 inline UInt16 SystemToLE(UInt16 v) {
return SwapOrder(v); }
978 inline SInt16 SystemToLE(SInt16 v) {
return SwapOrder(v); }
979 inline UInt32 SystemToLE(UInt32 v) {
return SwapOrder(v); }
980 inline SInt32 SystemToLE(SInt32 v) {
return SwapOrder(v); }
981 inline UInt64 SystemToLE(UInt64 v) {
return SwapOrder(v); }
982 inline SInt64 SystemToLE(SInt64 v) {
return SwapOrder(v); }
983 inline float SystemToLE(
float v) {
return SwapOrder(v); }
985 inline Double SystemToLE(Double v) {
return SwapOrder(v); }
988 inline UInt8 SystemToBE(UInt8 v) {
return v; }
989 inline SInt8 SystemToBE(SInt8 v) {
return v; }
990 inline UInt16 SystemToBE(UInt16 v) {
return v; }
991 inline SInt16 SystemToBE(SInt16 v) {
return v; }
992 inline UInt32 SystemToBE(UInt32 v) {
return v; }
993 inline SInt32 SystemToBE(SInt32 v) {
return v; }
994 inline UInt64 SystemToBE(UInt64 v) {
return v; }
995 inline SInt64 SystemToBE(SInt64 v) {
return v; }
996 inline float SystemToBE(
float v) {
return v; }
998 inline Double SystemToBE(Double v) {
return v; }
1002 #error "! KY_BYTE_ORDER must be defined to KY_LITTLE_ENDIAN or KY_BIG_ENDIAN !"
1009 inline UInt8 Cardinality(T v)
1011 const T MASK_01010101 = (((T)(-1))/3);
1012 const T MASK_00110011 = (((T)(-1))/5);
1013 const T MASK_00001111 = (((T)(-1))/17);
1015 v = (v & MASK_01010101) + ((v >> 1) & MASK_01010101) ;
1016 v = (v & MASK_00110011) + ((v >> 2) & MASK_00110011) ;
1017 v = (v & MASK_00001111) + ((v >> 4) & MASK_00001111) ;
1018 return (UInt8)(v % 255);
1022 inline UInt8 BitCount32(UInt32 value)
1026 ((value < 1UL<<15) ?
1029 ((value < 1UL<<1) ? ((value < 1UL<<0) ? 0 : 1) : ((value < 1UL<<2) ? 2 : 3)) :
1030 ((value < 1UL<<5) ? ((value < 1UL<<4) ? 4 : 5) : ((value < 1UL<<6) ? 6 : 7))) :
1031 ((value < 1UL<<11) ?
1032 ((value < 1UL<<9) ? ((value < 1UL<<8) ? 8 : 9) : ((value < 1UL<<10) ? 10 : 11)) :
1033 ((value < 1UL<<13) ? ((value < 1UL<<12) ? 12 : 13) : ((value < 1UL<<14) ? 14 : 15)))) :
1034 ((value < 1UL<<23) ?
1035 ((value < 1UL<<19) ?
1036 ((value < 1UL<<17) ? ((value < 1UL<<16) ? 16 : 17) : ((value < 1UL<<18) ? 18 : 19)) :
1037 ((value < 1UL<<21) ? ((value < 1UL<<20) ? 20 : 21) : ((value < 1UL<<22) ? 22 : 23))) :
1038 ((value < 1UL<<27) ?
1039 ((value < 1UL<<25) ? ((value < 1UL<<24) ? 24 : 25) : ((value < 1UL<<26) ? 26 : 27)) :
1040 ((value < 1UL<<29) ? ((value < 1UL<<28) ? 28 : 29) : ((value < 1UL<<30) ? 30 :
1041 ((value < 1UL<<31) ? 31 : 32))))));
T Min(const T &a, const T &b)
Returns the lesser of the two specified values.
Definition: fastmath.h:113
T Max(const T &a, const T &b)
Returns the greater of the two specified values.
Definition: fastmath.h:121
Definition: gamekitcrowddispersion.h:20