oculus1
diff libovr/Src/Kernel/OVR_Alg.h @ 3:b069a5c27388
added a couple more stuff, fixed all the LibOVR line endings
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 15 Sep 2013 04:10:05 +0300 |
parents | e2f9e4603129 |
children |
line diff
1.1 --- a/libovr/Src/Kernel/OVR_Alg.h Sat Sep 14 17:51:03 2013 +0300 1.2 +++ b/libovr/Src/Kernel/OVR_Alg.h Sun Sep 15 04:10:05 2013 +0300 1.3 @@ -1,1 +1,953 @@ 1.4 -/************************************************************************************ 1.5 1.6 PublicHeader: OVR.h 1.7 Filename : OVR_Alg.h 1.8 Content : Simple general purpose algorithms: Sort, Binary Search, etc. 1.9 Created : September 19, 2012 1.10 Notes : 1.11 1.12 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. 1.13 1.14 Use of this software is subject to the terms of the Oculus license 1.15 agreement provided at the time of installation or download, or which 1.16 otherwise accompanies this software in either electronic or hard copy form. 1.17 1.18 ************************************************************************************/ 1.19 1.20 #ifndef OVR_Alg_h 1.21 #define OVR_Alg_h 1.22 1.23 #include "OVR_Types.h" 1.24 #include <string.h> 1.25 1.26 namespace OVR { namespace Alg { 1.27 1.28 1.29 //----------------------------------------------------------------------------------- 1.30 // ***** Operator extensions 1.31 1.32 template <typename T> OVR_FORCE_INLINE void Swap(T &a, T &b) 1.33 { T temp(a); a = b; b = temp; } 1.34 1.35 1.36 // ***** min/max are not implemented in Visual Studio 6 standard STL 1.37 1.38 template <typename T> OVR_FORCE_INLINE const T Min(const T a, const T b) 1.39 { return (a < b) ? a : b; } 1.40 1.41 template <typename T> OVR_FORCE_INLINE const T Max(const T a, const T b) 1.42 { return (b < a) ? a : b; } 1.43 1.44 template <typename T> OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal) 1.45 { return Max<T>(minVal, Min<T>(v, maxVal)); } 1.46 1.47 template <typename T> OVR_FORCE_INLINE int Chop(T f) 1.48 { return (int)f; } 1.49 1.50 template <typename T> OVR_FORCE_INLINE T Lerp(T a, T b, T f) 1.51 { return (b - a) * f + a; } 1.52 1.53 1.54 // These functions stand to fix a stupid VC++ warning (with /Wp64 on): 1.55 // "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data" 1.56 // Use these functions instead of gmin/gmax if the argument has size 1.57 // of the pointer to avoid the warning. Though, functionally they are 1.58 // absolutelly the same as regular gmin/gmax. 1.59 template <typename T> OVR_FORCE_INLINE const T PMin(const T a, const T b) 1.60 { 1.61 OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt)); 1.62 return (a < b) ? a : b; 1.63 } 1.64 template <typename T> OVR_FORCE_INLINE const T PMax(const T a, const T b) 1.65 { 1.66 OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt)); 1.67 return (b < a) ? a : b; 1.68 } 1.69 1.70 1.71 template <typename T> OVR_FORCE_INLINE const T Abs(const T v) 1.72 { return (v>=0) ? v : -v; } 1.73 1.74 1.75 //----------------------------------------------------------------------------------- 1.76 // ***** OperatorLess 1.77 // 1.78 template<class T> struct OperatorLess 1.79 { 1.80 static bool Compare(const T& a, const T& b) 1.81 { 1.82 return a < b; 1.83 } 1.84 }; 1.85 1.86 1.87 //----------------------------------------------------------------------------------- 1.88 // ***** QuickSortSliced 1.89 // 1.90 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. 1.91 // The range is specified with start, end, where "end" is exclusive! 1.92 // The comparison predicate must be specified. 1.93 template<class Array, class Less> 1.94 void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less) 1.95 { 1.96 enum 1.97 { 1.98 Threshold = 9 1.99 }; 1.100 1.101 if(end - start < 2) return; 1.102 1.103 SPInt stack[80]; 1.104 SPInt* top = stack; 1.105 SPInt base = (SPInt)start; 1.106 SPInt limit = (SPInt)end; 1.107 1.108 for(;;) 1.109 { 1.110 SPInt len = limit - base; 1.111 SPInt i, j, pivot; 1.112 1.113 if(len > Threshold) 1.114 { 1.115 // we use base + len/2 as the pivot 1.116 pivot = base + len / 2; 1.117 Swap(arr[base], arr[pivot]); 1.118 1.119 i = base + 1; 1.120 j = limit - 1; 1.121 1.122 // now ensure that *i <= *base <= *j 1.123 if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); 1.124 if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); 1.125 if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); 1.126 1.127 for(;;) 1.128 { 1.129 do i++; while( less(arr[i], arr[base]) ); 1.130 do j--; while( less(arr[base], arr[j]) ); 1.131 1.132 if( i > j ) 1.133 { 1.134 break; 1.135 } 1.136 1.137 Swap(arr[i], arr[j]); 1.138 } 1.139 1.140 Swap(arr[base], arr[j]); 1.141 1.142 // now, push the largest sub-array 1.143 if(j - base > limit - i) 1.144 { 1.145 top[0] = base; 1.146 top[1] = j; 1.147 base = i; 1.148 } 1.149 else 1.150 { 1.151 top[0] = i; 1.152 top[1] = limit; 1.153 limit = j; 1.154 } 1.155 top += 2; 1.156 } 1.157 else 1.158 { 1.159 // the sub-array is small, perform insertion sort 1.160 j = base; 1.161 i = j + 1; 1.162 1.163 for(; i < limit; j = i, i++) 1.164 { 1.165 for(; less(arr[j + 1], arr[j]); j--) 1.166 { 1.167 Swap(arr[j + 1], arr[j]); 1.168 if(j == base) 1.169 { 1.170 break; 1.171 } 1.172 } 1.173 } 1.174 if(top > stack) 1.175 { 1.176 top -= 2; 1.177 base = top[0]; 1.178 limit = top[1]; 1.179 } 1.180 else 1.181 { 1.182 break; 1.183 } 1.184 } 1.185 } 1.186 } 1.187 1.188 1.189 //----------------------------------------------------------------------------------- 1.190 // ***** QuickSortSliced 1.191 // 1.192 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. 1.193 // The range is specified with start, end, where "end" is exclusive! 1.194 // The data type must have a defined "<" operator. 1.195 template<class Array> 1.196 void QuickSortSliced(Array& arr, UPInt start, UPInt end) 1.197 { 1.198 typedef typename Array::ValueType ValueType; 1.199 QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare); 1.200 } 1.201 1.202 // Same as corresponding G_QuickSortSliced but with checking array limits to avoid 1.203 // crash in the case of wrong comparator functor. 1.204 template<class Array, class Less> 1.205 bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end, Less less) 1.206 { 1.207 enum 1.208 { 1.209 Threshold = 9 1.210 }; 1.211 1.212 if(end - start < 2) return true; 1.213 1.214 SPInt stack[80]; 1.215 SPInt* top = stack; 1.216 SPInt base = (SPInt)start; 1.217 SPInt limit = (SPInt)end; 1.218 1.219 for(;;) 1.220 { 1.221 SPInt len = limit - base; 1.222 SPInt i, j, pivot; 1.223 1.224 if(len > Threshold) 1.225 { 1.226 // we use base + len/2 as the pivot 1.227 pivot = base + len / 2; 1.228 Swap(arr[base], arr[pivot]); 1.229 1.230 i = base + 1; 1.231 j = limit - 1; 1.232 1.233 // now ensure that *i <= *base <= *j 1.234 if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); 1.235 if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); 1.236 if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); 1.237 1.238 for(;;) 1.239 { 1.240 do 1.241 { 1.242 i++; 1.243 if (i >= limit) 1.244 return false; 1.245 } while( less(arr[i], arr[base]) ); 1.246 do 1.247 { 1.248 j--; 1.249 if (j < 0) 1.250 return false; 1.251 } while( less(arr[base], arr[j]) ); 1.252 1.253 if( i > j ) 1.254 { 1.255 break; 1.256 } 1.257 1.258 Swap(arr[i], arr[j]); 1.259 } 1.260 1.261 Swap(arr[base], arr[j]); 1.262 1.263 // now, push the largest sub-array 1.264 if(j - base > limit - i) 1.265 { 1.266 top[0] = base; 1.267 top[1] = j; 1.268 base = i; 1.269 } 1.270 else 1.271 { 1.272 top[0] = i; 1.273 top[1] = limit; 1.274 limit = j; 1.275 } 1.276 top += 2; 1.277 } 1.278 else 1.279 { 1.280 // the sub-array is small, perform insertion sort 1.281 j = base; 1.282 i = j + 1; 1.283 1.284 for(; i < limit; j = i, i++) 1.285 { 1.286 for(; less(arr[j + 1], arr[j]); j--) 1.287 { 1.288 Swap(arr[j + 1], arr[j]); 1.289 if(j == base) 1.290 { 1.291 break; 1.292 } 1.293 } 1.294 } 1.295 if(top > stack) 1.296 { 1.297 top -= 2; 1.298 base = top[0]; 1.299 limit = top[1]; 1.300 } 1.301 else 1.302 { 1.303 break; 1.304 } 1.305 } 1.306 } 1.307 return true; 1.308 } 1.309 1.310 template<class Array> 1.311 bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end) 1.312 { 1.313 typedef typename Array::ValueType ValueType; 1.314 return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare); 1.315 } 1.316 1.317 //----------------------------------------------------------------------------------- 1.318 // ***** QuickSort 1.319 // 1.320 // Sort an array Array, ArrayPaged, ArrayUnsafe. 1.321 // The array must have GetSize() function. 1.322 // The comparison predicate must be specified. 1.323 template<class Array, class Less> 1.324 void QuickSort(Array& arr, Less less) 1.325 { 1.326 QuickSortSliced(arr, 0, arr.GetSize(), less); 1.327 } 1.328 1.329 // checks for boundaries 1.330 template<class Array, class Less> 1.331 bool QuickSortSafe(Array& arr, Less less) 1.332 { 1.333 return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less); 1.334 } 1.335 1.336 1.337 //----------------------------------------------------------------------------------- 1.338 // ***** QuickSort 1.339 // 1.340 // Sort an array Array, ArrayPaged, ArrayUnsafe. 1.341 // The array must have GetSize() function. 1.342 // The data type must have a defined "<" operator. 1.343 template<class Array> 1.344 void QuickSort(Array& arr) 1.345 { 1.346 typedef typename Array::ValueType ValueType; 1.347 QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); 1.348 } 1.349 1.350 template<class Array> 1.351 bool QuickSortSafe(Array& arr) 1.352 { 1.353 typedef typename Array::ValueType ValueType; 1.354 return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); 1.355 } 1.356 1.357 //----------------------------------------------------------------------------------- 1.358 // ***** InsertionSortSliced 1.359 // 1.360 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. 1.361 // The range is specified with start, end, where "end" is exclusive! 1.362 // The comparison predicate must be specified. 1.363 // Unlike Quick Sort, the Insertion Sort works much slower in average, 1.364 // but may be much faster on almost sorted arrays. Besides, it guarantees 1.365 // that the elements will not be swapped if not necessary. For example, 1.366 // an array with all equal elements will remain "untouched", while 1.367 // Quick Sort will considerably shuffle the elements in this case. 1.368 template<class Array, class Less> 1.369 void InsertionSortSliced(Array& arr, UPInt start, UPInt end, Less less) 1.370 { 1.371 UPInt j = start; 1.372 UPInt i = j + 1; 1.373 UPInt limit = end; 1.374 1.375 for(; i < limit; j = i, i++) 1.376 { 1.377 for(; less(arr[j + 1], arr[j]); j--) 1.378 { 1.379 Swap(arr[j + 1], arr[j]); 1.380 if(j <= start) 1.381 { 1.382 break; 1.383 } 1.384 } 1.385 } 1.386 } 1.387 1.388 1.389 //----------------------------------------------------------------------------------- 1.390 // ***** InsertionSortSliced 1.391 // 1.392 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. 1.393 // The range is specified with start, end, where "end" is exclusive! 1.394 // The data type must have a defined "<" operator. 1.395 template<class Array> 1.396 void InsertionSortSliced(Array& arr, UPInt start, UPInt end) 1.397 { 1.398 typedef typename Array::ValueType ValueType; 1.399 InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare); 1.400 } 1.401 1.402 //----------------------------------------------------------------------------------- 1.403 // ***** InsertionSort 1.404 // 1.405 // Sort an array Array, ArrayPaged, ArrayUnsafe. 1.406 // The array must have GetSize() function. 1.407 // The comparison predicate must be specified. 1.408 1.409 template<class Array, class Less> 1.410 void InsertionSort(Array& arr, Less less) 1.411 { 1.412 InsertionSortSliced(arr, 0, arr.GetSize(), less); 1.413 } 1.414 1.415 //----------------------------------------------------------------------------------- 1.416 // ***** InsertionSort 1.417 // 1.418 // Sort an array Array, ArrayPaged, ArrayUnsafe. 1.419 // The array must have GetSize() function. 1.420 // The data type must have a defined "<" operator. 1.421 template<class Array> 1.422 void InsertionSort(Array& arr) 1.423 { 1.424 typedef typename Array::ValueType ValueType; 1.425 InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); 1.426 } 1.427 1.428 1.429 1.430 //----------------------------------------------------------------------------------- 1.431 // ***** LowerBoundSliced 1.432 // 1.433 template<class Array, class Value, class Less> 1.434 UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less) 1.435 { 1.436 SPInt first = (SPInt)start; 1.437 SPInt len = (SPInt)(end - start); 1.438 SPInt half; 1.439 SPInt middle; 1.440 1.441 while(len > 0) 1.442 { 1.443 half = len >> 1; 1.444 middle = first + half; 1.445 if(less(arr[middle], val)) 1.446 { 1.447 first = middle + 1; 1.448 len = len - half - 1; 1.449 } 1.450 else 1.451 { 1.452 len = half; 1.453 } 1.454 } 1.455 return (UPInt)first; 1.456 } 1.457 1.458 1.459 //----------------------------------------------------------------------------------- 1.460 // ***** LowerBoundSliced 1.461 // 1.462 template<class Array, class Value> 1.463 UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val) 1.464 { 1.465 return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare); 1.466 } 1.467 1.468 //----------------------------------------------------------------------------------- 1.469 // ***** LowerBoundSized 1.470 // 1.471 template<class Array, class Value> 1.472 UPInt LowerBoundSized(const Array& arr, UPInt size, const Value& val) 1.473 { 1.474 return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare); 1.475 } 1.476 1.477 //----------------------------------------------------------------------------------- 1.478 // ***** LowerBound 1.479 // 1.480 template<class Array, class Value, class Less> 1.481 UPInt LowerBound(const Array& arr, const Value& val, Less less) 1.482 { 1.483 return LowerBoundSliced(arr, 0, arr.GetSize(), val, less); 1.484 } 1.485 1.486 1.487 //----------------------------------------------------------------------------------- 1.488 // ***** LowerBound 1.489 // 1.490 template<class Array, class Value> 1.491 UPInt LowerBound(const Array& arr, const Value& val) 1.492 { 1.493 return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare); 1.494 } 1.495 1.496 1.497 1.498 //----------------------------------------------------------------------------------- 1.499 // ***** UpperBoundSliced 1.500 // 1.501 template<class Array, class Value, class Less> 1.502 UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less) 1.503 { 1.504 SPInt first = (SPInt)start; 1.505 SPInt len = (SPInt)(end - start); 1.506 SPInt half; 1.507 SPInt middle; 1.508 1.509 while(len > 0) 1.510 { 1.511 half = len >> 1; 1.512 middle = first + half; 1.513 if(less(val, arr[middle])) 1.514 { 1.515 len = half; 1.516 } 1.517 else 1.518 { 1.519 first = middle + 1; 1.520 len = len - half - 1; 1.521 } 1.522 } 1.523 return (UPInt)first; 1.524 } 1.525 1.526 1.527 //----------------------------------------------------------------------------------- 1.528 // ***** UpperBoundSliced 1.529 // 1.530 template<class Array, class Value> 1.531 UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val) 1.532 { 1.533 return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare); 1.534 } 1.535 1.536 1.537 //----------------------------------------------------------------------------------- 1.538 // ***** UpperBoundSized 1.539 // 1.540 template<class Array, class Value> 1.541 UPInt UpperBoundSized(const Array& arr, UPInt size, const Value& val) 1.542 { 1.543 return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare); 1.544 } 1.545 1.546 1.547 //----------------------------------------------------------------------------------- 1.548 // ***** UpperBound 1.549 // 1.550 template<class Array, class Value, class Less> 1.551 UPInt UpperBound(const Array& arr, const Value& val, Less less) 1.552 { 1.553 return UpperBoundSliced(arr, 0, arr.GetSize(), val, less); 1.554 } 1.555 1.556 1.557 //----------------------------------------------------------------------------------- 1.558 // ***** UpperBound 1.559 // 1.560 template<class Array, class Value> 1.561 UPInt UpperBound(const Array& arr, const Value& val) 1.562 { 1.563 return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare); 1.564 } 1.565 1.566 1.567 //----------------------------------------------------------------------------------- 1.568 // ***** ReverseArray 1.569 // 1.570 template<class Array> void ReverseArray(Array& arr) 1.571 { 1.572 SPInt from = 0; 1.573 SPInt to = arr.GetSize() - 1; 1.574 while(from < to) 1.575 { 1.576 Swap(arr[from], arr[to]); 1.577 ++from; 1.578 --to; 1.579 } 1.580 } 1.581 1.582 1.583 // ***** AppendArray 1.584 // 1.585 template<class CDst, class CSrc> 1.586 void AppendArray(CDst& dst, const CSrc& src) 1.587 { 1.588 UPInt i; 1.589 for(i = 0; i < src.GetSize(); i++) 1.590 dst.PushBack(src[i]); 1.591 } 1.592 1.593 //----------------------------------------------------------------------------------- 1.594 // ***** ArrayAdaptor 1.595 // 1.596 // A simple adapter that provides the GetSize() method and overloads 1.597 // operator []. Used to wrap plain arrays in QuickSort and such. 1.598 template<class T> class ArrayAdaptor 1.599 { 1.600 public: 1.601 typedef T ValueType; 1.602 ArrayAdaptor() : Data(0), Size(0) {} 1.603 ArrayAdaptor(T* ptr, UPInt size) : Data(ptr), Size(size) {} 1.604 UPInt GetSize() const { return Size; } 1.605 const T& operator [] (UPInt i) const { return Data[i]; } 1.606 T& operator [] (UPInt i) { return Data[i]; } 1.607 private: 1.608 T* Data; 1.609 UPInt Size; 1.610 }; 1.611 1.612 1.613 //----------------------------------------------------------------------------------- 1.614 // ***** GConstArrayAdaptor 1.615 // 1.616 // A simple const adapter that provides the GetSize() method and overloads 1.617 // operator []. Used to wrap plain arrays in LowerBound and such. 1.618 template<class T> class ConstArrayAdaptor 1.619 { 1.620 public: 1.621 typedef T ValueType; 1.622 ConstArrayAdaptor() : Data(0), Size(0) {} 1.623 ConstArrayAdaptor(const T* ptr, UPInt size) : Data(ptr), Size(size) {} 1.624 UPInt GetSize() const { return Size; } 1.625 const T& operator [] (UPInt i) const { return Data[i]; } 1.626 private: 1.627 const T* Data; 1.628 UPInt Size; 1.629 }; 1.630 1.631 1.632 1.633 //----------------------------------------------------------------------------------- 1.634 extern const UByte UpperBitTable[256]; 1.635 extern const UByte LowerBitTable[256]; 1.636 1.637 1.638 1.639 //----------------------------------------------------------------------------------- 1.640 inline UByte UpperBit(UPInt val) 1.641 { 1.642 #ifndef OVR_64BIT_POINTERS 1.643 1.644 if (val & 0xFFFF0000) 1.645 { 1.646 return (val & 0xFF000000) ? 1.647 UpperBitTable[(val >> 24) ] + 24: 1.648 UpperBitTable[(val >> 16) & 0xFF] + 16; 1.649 } 1.650 return (val & 0xFF00) ? 1.651 UpperBitTable[(val >> 8) & 0xFF] + 8: 1.652 UpperBitTable[(val ) & 0xFF]; 1.653 1.654 #else 1.655 1.656 if (val & 0xFFFFFFFF00000000) 1.657 { 1.658 if (val & 0xFFFF000000000000) 1.659 { 1.660 return (val & 0xFF00000000000000) ? 1.661 UpperBitTable[(val >> 56) ] + 56: 1.662 UpperBitTable[(val >> 48) & 0xFF] + 48; 1.663 } 1.664 return (val & 0xFF0000000000) ? 1.665 UpperBitTable[(val >> 40) & 0xFF] + 40: 1.666 UpperBitTable[(val >> 32) & 0xFF] + 32; 1.667 } 1.668 else 1.669 { 1.670 if (val & 0xFFFF0000) 1.671 { 1.672 return (val & 0xFF000000) ? 1.673 UpperBitTable[(val >> 24) ] + 24: 1.674 UpperBitTable[(val >> 16) & 0xFF] + 16; 1.675 } 1.676 return (val & 0xFF00) ? 1.677 UpperBitTable[(val >> 8) & 0xFF] + 8: 1.678 UpperBitTable[(val ) & 0xFF]; 1.679 } 1.680 1.681 #endif 1.682 } 1.683 1.684 //----------------------------------------------------------------------------------- 1.685 inline UByte LowerBit(UPInt val) 1.686 { 1.687 #ifndef OVR_64BIT_POINTERS 1.688 1.689 if (val & 0xFFFF) 1.690 { 1.691 return (val & 0xFF) ? 1.692 LowerBitTable[ val & 0xFF]: 1.693 LowerBitTable[(val >> 8) & 0xFF] + 8; 1.694 } 1.695 return (val & 0xFF0000) ? 1.696 LowerBitTable[(val >> 16) & 0xFF] + 16: 1.697 LowerBitTable[(val >> 24) & 0xFF] + 24; 1.698 1.699 #else 1.700 1.701 if (val & 0xFFFFFFFF) 1.702 { 1.703 if (val & 0xFFFF) 1.704 { 1.705 return (val & 0xFF) ? 1.706 LowerBitTable[ val & 0xFF]: 1.707 LowerBitTable[(val >> 8) & 0xFF] + 8; 1.708 } 1.709 return (val & 0xFF0000) ? 1.710 LowerBitTable[(val >> 16) & 0xFF] + 16: 1.711 LowerBitTable[(val >> 24) & 0xFF] + 24; 1.712 } 1.713 else 1.714 { 1.715 if (val & 0xFFFF00000000) 1.716 { 1.717 return (val & 0xFF00000000) ? 1.718 LowerBitTable[(val >> 32) & 0xFF] + 32: 1.719 LowerBitTable[(val >> 40) & 0xFF] + 40; 1.720 } 1.721 return (val & 0xFF000000000000) ? 1.722 LowerBitTable[(val >> 48) & 0xFF] + 48: 1.723 LowerBitTable[(val >> 56) & 0xFF] + 56; 1.724 } 1.725 1.726 #endif 1.727 } 1.728 1.729 1.730 1.731 // ******* Special (optimized) memory routines 1.732 // Note: null (bad) pointer is not tested 1.733 class MemUtil 1.734 { 1.735 public: 1.736 1.737 // Memory compare 1.738 static int Cmp (const void* p1, const void* p2, UPInt byteCount) { return memcmp(p1, p2, byteCount); } 1.739 static int Cmp16(const void* p1, const void* p2, UPInt int16Count); 1.740 static int Cmp32(const void* p1, const void* p2, UPInt int32Count); 1.741 static int Cmp64(const void* p1, const void* p2, UPInt int64Count); 1.742 }; 1.743 1.744 // ** Inline Implementation 1.745 1.746 inline int MemUtil::Cmp16(const void* p1, const void* p2, UPInt int16Count) 1.747 { 1.748 SInt16* pa = (SInt16*)p1; 1.749 SInt16* pb = (SInt16*)p2; 1.750 unsigned ic = 0; 1.751 if (int16Count == 0) 1.752 return 0; 1.753 while (pa[ic] == pb[ic]) 1.754 if (++ic==int16Count) 1.755 return 0; 1.756 return pa[ic] > pb[ic] ? 1 : -1; 1.757 } 1.758 inline int MemUtil::Cmp32(const void* p1, const void* p2, UPInt int32Count) 1.759 { 1.760 SInt32* pa = (SInt32*)p1; 1.761 SInt32* pb = (SInt32*)p2; 1.762 unsigned ic = 0; 1.763 if (int32Count == 0) 1.764 return 0; 1.765 while (pa[ic] == pb[ic]) 1.766 if (++ic==int32Count) 1.767 return 0; 1.768 return pa[ic] > pb[ic] ? 1 : -1; 1.769 } 1.770 inline int MemUtil::Cmp64(const void* p1, const void* p2, UPInt int64Count) 1.771 { 1.772 SInt64* pa = (SInt64*)p1; 1.773 SInt64* pb = (SInt64*)p2; 1.774 unsigned ic = 0; 1.775 if (int64Count == 0) 1.776 return 0; 1.777 while (pa[ic] == pb[ic]) 1.778 if (++ic==int64Count) 1.779 return 0; 1.780 return pa[ic] > pb[ic] ? 1 : -1; 1.781 } 1.782 1.783 // ** End Inline Implementation 1.784 1.785 1.786 //----------------------------------------------------------------------------------- 1.787 // ******* Byte Order Conversions 1.788 namespace ByteUtil { 1.789 1.790 // *** Swap Byte Order 1.791 1.792 // Swap the byte order of a byte array 1.793 inline void SwapOrder(void* pv, int size) 1.794 { 1.795 UByte* pb = (UByte*)pv; 1.796 UByte temp; 1.797 for (int i = 0; i < size>>1; i++) 1.798 { 1.799 temp = pb[size-1-i]; 1.800 pb[size-1-i] = pb[i]; 1.801 pb[i] = temp; 1.802 } 1.803 } 1.804 1.805 // Swap the byte order of primitive types 1.806 inline UByte SwapOrder(UByte v) { return v; } 1.807 inline SByte SwapOrder(SByte v) { return v; } 1.808 inline UInt16 SwapOrder(UInt16 v) { return UInt16(v>>8)|UInt16(v<<8); } 1.809 inline SInt16 SwapOrder(SInt16 v) { return SInt16((UInt16(v)>>8)|(v<<8)); } 1.810 inline UInt32 SwapOrder(UInt32 v) { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); } 1.811 inline SInt32 SwapOrder(SInt32 p) { return (SInt32)SwapOrder(UInt32(p)); } 1.812 inline UInt64 SwapOrder(UInt64 v) 1.813 { 1.814 return (v>>56) | 1.815 ((v&UInt64(0x00FF000000000000))>>40) | 1.816 ((v&UInt64(0x0000FF0000000000))>>24) | 1.817 ((v&UInt64(0x000000FF00000000))>>8) | 1.818 ((v&UInt64(0x00000000FF000000))<<8) | 1.819 ((v&UInt64(0x0000000000FF0000))<<24) | 1.820 ((v&UInt64(0x000000000000FF00))<<40) | 1.821 (v<<56); 1.822 } 1.823 inline SInt64 SwapOrder(SInt64 v) { return (SInt64)SwapOrder(UInt64(v)); } 1.824 inline float SwapOrder(float p) 1.825 { 1.826 union { 1.827 float p; 1.828 UInt32 v; 1.829 } u; 1.830 u.p = p; 1.831 u.v = SwapOrder(u.v); 1.832 return u.p; 1.833 } 1.834 1.835 inline double SwapOrder(double p) 1.836 { 1.837 union { 1.838 double p; 1.839 UInt64 v; 1.840 } u; 1.841 u.p = p; 1.842 u.v = SwapOrder(u.v); 1.843 return u.p; 1.844 } 1.845 1.846 // *** Byte-order conversion 1.847 1.848 #if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN) 1.849 // Little Endian to System (LE) 1.850 inline UByte LEToSystem(UByte v) { return v; } 1.851 inline SByte LEToSystem(SByte v) { return v; } 1.852 inline UInt16 LEToSystem(UInt16 v) { return v; } 1.853 inline SInt16 LEToSystem(SInt16 v) { return v; } 1.854 inline UInt32 LEToSystem(UInt32 v) { return v; } 1.855 inline SInt32 LEToSystem(SInt32 v) { return v; } 1.856 inline UInt64 LEToSystem(UInt64 v) { return v; } 1.857 inline SInt64 LEToSystem(SInt64 v) { return v; } 1.858 inline float LEToSystem(float v) { return v; } 1.859 inline double LEToSystem(double v) { return v; } 1.860 1.861 // Big Endian to System (LE) 1.862 inline UByte BEToSystem(UByte v) { return SwapOrder(v); } 1.863 inline SByte BEToSystem(SByte v) { return SwapOrder(v); } 1.864 inline UInt16 BEToSystem(UInt16 v) { return SwapOrder(v); } 1.865 inline SInt16 BEToSystem(SInt16 v) { return SwapOrder(v); } 1.866 inline UInt32 BEToSystem(UInt32 v) { return SwapOrder(v); } 1.867 inline SInt32 BEToSystem(SInt32 v) { return SwapOrder(v); } 1.868 inline UInt64 BEToSystem(UInt64 v) { return SwapOrder(v); } 1.869 inline SInt64 BEToSystem(SInt64 v) { return SwapOrder(v); } 1.870 inline float BEToSystem(float v) { return SwapOrder(v); } 1.871 inline double BEToSystem(double v) { return SwapOrder(v); } 1.872 1.873 // System (LE) to Little Endian 1.874 inline UByte SystemToLE(UByte v) { return v; } 1.875 inline SByte SystemToLE(SByte v) { return v; } 1.876 inline UInt16 SystemToLE(UInt16 v) { return v; } 1.877 inline SInt16 SystemToLE(SInt16 v) { return v; } 1.878 inline UInt32 SystemToLE(UInt32 v) { return v; } 1.879 inline SInt32 SystemToLE(SInt32 v) { return v; } 1.880 inline UInt64 SystemToLE(UInt64 v) { return v; } 1.881 inline SInt64 SystemToLE(SInt64 v) { return v; } 1.882 inline float SystemToLE(float v) { return v; } 1.883 inline double SystemToLE(double v) { return v; } 1.884 1.885 // System (LE) to Big Endian 1.886 inline UByte SystemToBE(UByte v) { return SwapOrder(v); } 1.887 inline SByte SystemToBE(SByte v) { return SwapOrder(v); } 1.888 inline UInt16 SystemToBE(UInt16 v) { return SwapOrder(v); } 1.889 inline SInt16 SystemToBE(SInt16 v) { return SwapOrder(v); } 1.890 inline UInt32 SystemToBE(UInt32 v) { return SwapOrder(v); } 1.891 inline SInt32 SystemToBE(SInt32 v) { return SwapOrder(v); } 1.892 inline UInt64 SystemToBE(UInt64 v) { return SwapOrder(v); } 1.893 inline SInt64 SystemToBE(SInt64 v) { return SwapOrder(v); } 1.894 inline float SystemToBE(float v) { return SwapOrder(v); } 1.895 inline double SystemToBE(double v) { return SwapOrder(v); } 1.896 1.897 #elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN) 1.898 // Little Endian to System (BE) 1.899 inline UByte LEToSystem(UByte v) { return SwapOrder(v); } 1.900 inline SByte LEToSystem(SByte v) { return SwapOrder(v); } 1.901 inline UInt16 LEToSystem(UInt16 v) { return SwapOrder(v); } 1.902 inline SInt16 LEToSystem(SInt16 v) { return SwapOrder(v); } 1.903 inline UInt32 LEToSystem(UInt32 v) { return SwapOrder(v); } 1.904 inline SInt32 LEToSystem(SInt32 v) { return SwapOrder(v); } 1.905 inline UInt64 LEToSystem(UInt64 v) { return SwapOrder(v); } 1.906 inline SInt64 LEToSystem(SInt64 v) { return SwapOrder(v); } 1.907 inline float LEToSystem(float v) { return SwapOrder(v); } 1.908 inline double LEToSystem(double v) { return SwapOrder(v); } 1.909 1.910 // Big Endian to System (BE) 1.911 inline UByte BEToSystem(UByte v) { return v; } 1.912 inline SByte BEToSystem(SByte v) { return v; } 1.913 inline UInt16 BEToSystem(UInt16 v) { return v; } 1.914 inline SInt16 BEToSystem(SInt16 v) { return v; } 1.915 inline UInt32 BEToSystem(UInt32 v) { return v; } 1.916 inline SInt32 BEToSystem(SInt32 v) { return v; } 1.917 inline UInt64 BEToSystem(UInt64 v) { return v; } 1.918 inline SInt64 BEToSystem(SInt64 v) { return v; } 1.919 inline float BEToSystem(float v) { return v; } 1.920 inline double BEToSystem(double v) { return v; } 1.921 1.922 // System (BE) to Little Endian 1.923 inline UByte SystemToLE(UByte v) { return SwapOrder(v); } 1.924 inline SByte SystemToLE(SByte v) { return SwapOrder(v); } 1.925 inline UInt16 SystemToLE(UInt16 v) { return SwapOrder(v); } 1.926 inline SInt16 SystemToLE(SInt16 v) { return SwapOrder(v); } 1.927 inline UInt32 SystemToLE(UInt32 v) { return SwapOrder(v); } 1.928 inline SInt32 SystemToLE(SInt32 v) { return SwapOrder(v); } 1.929 inline UInt64 SystemToLE(UInt64 v) { return SwapOrder(v); } 1.930 inline SInt64 SystemToLE(SInt64 v) { return SwapOrder(v); } 1.931 inline float SystemToLE(float v) { return SwapOrder(v); } 1.932 inline double SystemToLE(double v) { return SwapOrder(v); } 1.933 1.934 // System (BE) to Big Endian 1.935 inline UByte SystemToBE(UByte v) { return v; } 1.936 inline SByte SystemToBE(SByte v) { return v; } 1.937 inline UInt16 SystemToBE(UInt16 v) { return v; } 1.938 inline SInt16 SystemToBE(SInt16 v) { return v; } 1.939 inline UInt32 SystemToBE(UInt32 v) { return v; } 1.940 inline SInt32 SystemToBE(SInt32 v) { return v; } 1.941 inline UInt64 SystemToBE(UInt64 v) { return v; } 1.942 inline SInt64 SystemToBE(SInt64 v) { return v; } 1.943 inline float SystemToBE(float v) { return v; } 1.944 inline double SystemToBE(double v) { return v; } 1.945 1.946 #else 1.947 #error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN" 1.948 #endif 1.949 1.950 } // namespace ByteUtil 1.951 1.952 1.953 1.954 }} // OVR::Alg 1.955 1.956 #endif 1.957 \ No newline at end of file 1.958 +/************************************************************************************ 1.959 + 1.960 +PublicHeader: OVR.h 1.961 +Filename : OVR_Alg.h 1.962 +Content : Simple general purpose algorithms: Sort, Binary Search, etc. 1.963 +Created : September 19, 2012 1.964 +Notes : 1.965 + 1.966 +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. 1.967 + 1.968 +Use of this software is subject to the terms of the Oculus license 1.969 +agreement provided at the time of installation or download, or which 1.970 +otherwise accompanies this software in either electronic or hard copy form. 1.971 + 1.972 +************************************************************************************/ 1.973 + 1.974 +#ifndef OVR_Alg_h 1.975 +#define OVR_Alg_h 1.976 + 1.977 +#include "OVR_Types.h" 1.978 +#include <string.h> 1.979 + 1.980 +namespace OVR { namespace Alg { 1.981 + 1.982 + 1.983 +//----------------------------------------------------------------------------------- 1.984 +// ***** Operator extensions 1.985 + 1.986 +template <typename T> OVR_FORCE_INLINE void Swap(T &a, T &b) 1.987 +{ T temp(a); a = b; b = temp; } 1.988 + 1.989 + 1.990 +// ***** min/max are not implemented in Visual Studio 6 standard STL 1.991 + 1.992 +template <typename T> OVR_FORCE_INLINE const T Min(const T a, const T b) 1.993 +{ return (a < b) ? a : b; } 1.994 + 1.995 +template <typename T> OVR_FORCE_INLINE const T Max(const T a, const T b) 1.996 +{ return (b < a) ? a : b; } 1.997 + 1.998 +template <typename T> OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal) 1.999 +{ return Max<T>(minVal, Min<T>(v, maxVal)); } 1.1000 + 1.1001 +template <typename T> OVR_FORCE_INLINE int Chop(T f) 1.1002 +{ return (int)f; } 1.1003 + 1.1004 +template <typename T> OVR_FORCE_INLINE T Lerp(T a, T b, T f) 1.1005 +{ return (b - a) * f + a; } 1.1006 + 1.1007 + 1.1008 +// These functions stand to fix a stupid VC++ warning (with /Wp64 on): 1.1009 +// "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data" 1.1010 +// Use these functions instead of gmin/gmax if the argument has size 1.1011 +// of the pointer to avoid the warning. Though, functionally they are 1.1012 +// absolutelly the same as regular gmin/gmax. 1.1013 +template <typename T> OVR_FORCE_INLINE const T PMin(const T a, const T b) 1.1014 +{ 1.1015 + OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt)); 1.1016 + return (a < b) ? a : b; 1.1017 +} 1.1018 +template <typename T> OVR_FORCE_INLINE const T PMax(const T a, const T b) 1.1019 +{ 1.1020 + OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt)); 1.1021 + return (b < a) ? a : b; 1.1022 +} 1.1023 + 1.1024 + 1.1025 +template <typename T> OVR_FORCE_INLINE const T Abs(const T v) 1.1026 +{ return (v>=0) ? v : -v; } 1.1027 + 1.1028 + 1.1029 +//----------------------------------------------------------------------------------- 1.1030 +// ***** OperatorLess 1.1031 +// 1.1032 +template<class T> struct OperatorLess 1.1033 +{ 1.1034 + static bool Compare(const T& a, const T& b) 1.1035 + { 1.1036 + return a < b; 1.1037 + } 1.1038 +}; 1.1039 + 1.1040 + 1.1041 +//----------------------------------------------------------------------------------- 1.1042 +// ***** QuickSortSliced 1.1043 +// 1.1044 +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. 1.1045 +// The range is specified with start, end, where "end" is exclusive! 1.1046 +// The comparison predicate must be specified. 1.1047 +template<class Array, class Less> 1.1048 +void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less) 1.1049 +{ 1.1050 + enum 1.1051 + { 1.1052 + Threshold = 9 1.1053 + }; 1.1054 + 1.1055 + if(end - start < 2) return; 1.1056 + 1.1057 + SPInt stack[80]; 1.1058 + SPInt* top = stack; 1.1059 + SPInt base = (SPInt)start; 1.1060 + SPInt limit = (SPInt)end; 1.1061 + 1.1062 + for(;;) 1.1063 + { 1.1064 + SPInt len = limit - base; 1.1065 + SPInt i, j, pivot; 1.1066 + 1.1067 + if(len > Threshold) 1.1068 + { 1.1069 + // we use base + len/2 as the pivot 1.1070 + pivot = base + len / 2; 1.1071 + Swap(arr[base], arr[pivot]); 1.1072 + 1.1073 + i = base + 1; 1.1074 + j = limit - 1; 1.1075 + 1.1076 + // now ensure that *i <= *base <= *j 1.1077 + if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); 1.1078 + if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); 1.1079 + if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); 1.1080 + 1.1081 + for(;;) 1.1082 + { 1.1083 + do i++; while( less(arr[i], arr[base]) ); 1.1084 + do j--; while( less(arr[base], arr[j]) ); 1.1085 + 1.1086 + if( i > j ) 1.1087 + { 1.1088 + break; 1.1089 + } 1.1090 + 1.1091 + Swap(arr[i], arr[j]); 1.1092 + } 1.1093 + 1.1094 + Swap(arr[base], arr[j]); 1.1095 + 1.1096 + // now, push the largest sub-array 1.1097 + if(j - base > limit - i) 1.1098 + { 1.1099 + top[0] = base; 1.1100 + top[1] = j; 1.1101 + base = i; 1.1102 + } 1.1103 + else 1.1104 + { 1.1105 + top[0] = i; 1.1106 + top[1] = limit; 1.1107 + limit = j; 1.1108 + } 1.1109 + top += 2; 1.1110 + } 1.1111 + else 1.1112 + { 1.1113 + // the sub-array is small, perform insertion sort 1.1114 + j = base; 1.1115 + i = j + 1; 1.1116 + 1.1117 + for(; i < limit; j = i, i++) 1.1118 + { 1.1119 + for(; less(arr[j + 1], arr[j]); j--) 1.1120 + { 1.1121 + Swap(arr[j + 1], arr[j]); 1.1122 + if(j == base) 1.1123 + { 1.1124 + break; 1.1125 + } 1.1126 + } 1.1127 + } 1.1128 + if(top > stack) 1.1129 + { 1.1130 + top -= 2; 1.1131 + base = top[0]; 1.1132 + limit = top[1]; 1.1133 + } 1.1134 + else 1.1135 + { 1.1136 + break; 1.1137 + } 1.1138 + } 1.1139 + } 1.1140 +} 1.1141 + 1.1142 + 1.1143 +//----------------------------------------------------------------------------------- 1.1144 +// ***** QuickSortSliced 1.1145 +// 1.1146 +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. 1.1147 +// The range is specified with start, end, where "end" is exclusive! 1.1148 +// The data type must have a defined "<" operator. 1.1149 +template<class Array> 1.1150 +void QuickSortSliced(Array& arr, UPInt start, UPInt end) 1.1151 +{ 1.1152 + typedef typename Array::ValueType ValueType; 1.1153 + QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare); 1.1154 +} 1.1155 + 1.1156 +// Same as corresponding G_QuickSortSliced but with checking array limits to avoid 1.1157 +// crash in the case of wrong comparator functor. 1.1158 +template<class Array, class Less> 1.1159 +bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end, Less less) 1.1160 +{ 1.1161 + enum 1.1162 + { 1.1163 + Threshold = 9 1.1164 + }; 1.1165 + 1.1166 + if(end - start < 2) return true; 1.1167 + 1.1168 + SPInt stack[80]; 1.1169 + SPInt* top = stack; 1.1170 + SPInt base = (SPInt)start; 1.1171 + SPInt limit = (SPInt)end; 1.1172 + 1.1173 + for(;;) 1.1174 + { 1.1175 + SPInt len = limit - base; 1.1176 + SPInt i, j, pivot; 1.1177 + 1.1178 + if(len > Threshold) 1.1179 + { 1.1180 + // we use base + len/2 as the pivot 1.1181 + pivot = base + len / 2; 1.1182 + Swap(arr[base], arr[pivot]); 1.1183 + 1.1184 + i = base + 1; 1.1185 + j = limit - 1; 1.1186 + 1.1187 + // now ensure that *i <= *base <= *j 1.1188 + if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); 1.1189 + if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); 1.1190 + if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); 1.1191 + 1.1192 + for(;;) 1.1193 + { 1.1194 + do 1.1195 + { 1.1196 + i++; 1.1197 + if (i >= limit) 1.1198 + return false; 1.1199 + } while( less(arr[i], arr[base]) ); 1.1200 + do 1.1201 + { 1.1202 + j--; 1.1203 + if (j < 0) 1.1204 + return false; 1.1205 + } while( less(arr[base], arr[j]) ); 1.1206 + 1.1207 + if( i > j ) 1.1208 + { 1.1209 + break; 1.1210 + } 1.1211 + 1.1212 + Swap(arr[i], arr[j]); 1.1213 + } 1.1214 + 1.1215 + Swap(arr[base], arr[j]); 1.1216 + 1.1217 + // now, push the largest sub-array 1.1218 + if(j - base > limit - i) 1.1219 + { 1.1220 + top[0] = base; 1.1221 + top[1] = j; 1.1222 + base = i; 1.1223 + } 1.1224 + else 1.1225 + { 1.1226 + top[0] = i; 1.1227 + top[1] = limit; 1.1228 + limit = j; 1.1229 + } 1.1230 + top += 2; 1.1231 + } 1.1232 + else 1.1233 + { 1.1234 + // the sub-array is small, perform insertion sort 1.1235 + j = base; 1.1236 + i = j + 1; 1.1237 + 1.1238 + for(; i < limit; j = i, i++) 1.1239 + { 1.1240 + for(; less(arr[j + 1], arr[j]); j--) 1.1241 + { 1.1242 + Swap(arr[j + 1], arr[j]); 1.1243 + if(j == base) 1.1244 + { 1.1245 + break; 1.1246 + } 1.1247 + } 1.1248 + } 1.1249 + if(top > stack) 1.1250 + { 1.1251 + top -= 2; 1.1252 + base = top[0]; 1.1253 + limit = top[1]; 1.1254 + } 1.1255 + else 1.1256 + { 1.1257 + break; 1.1258 + } 1.1259 + } 1.1260 + } 1.1261 + return true; 1.1262 +} 1.1263 + 1.1264 +template<class Array> 1.1265 +bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end) 1.1266 +{ 1.1267 + typedef typename Array::ValueType ValueType; 1.1268 + return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare); 1.1269 +} 1.1270 + 1.1271 +//----------------------------------------------------------------------------------- 1.1272 +// ***** QuickSort 1.1273 +// 1.1274 +// Sort an array Array, ArrayPaged, ArrayUnsafe. 1.1275 +// The array must have GetSize() function. 1.1276 +// The comparison predicate must be specified. 1.1277 +template<class Array, class Less> 1.1278 +void QuickSort(Array& arr, Less less) 1.1279 +{ 1.1280 + QuickSortSliced(arr, 0, arr.GetSize(), less); 1.1281 +} 1.1282 + 1.1283 +// checks for boundaries 1.1284 +template<class Array, class Less> 1.1285 +bool QuickSortSafe(Array& arr, Less less) 1.1286 +{ 1.1287 + return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less); 1.1288 +} 1.1289 + 1.1290 + 1.1291 +//----------------------------------------------------------------------------------- 1.1292 +// ***** QuickSort 1.1293 +// 1.1294 +// Sort an array Array, ArrayPaged, ArrayUnsafe. 1.1295 +// The array must have GetSize() function. 1.1296 +// The data type must have a defined "<" operator. 1.1297 +template<class Array> 1.1298 +void QuickSort(Array& arr) 1.1299 +{ 1.1300 + typedef typename Array::ValueType ValueType; 1.1301 + QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); 1.1302 +} 1.1303 + 1.1304 +template<class Array> 1.1305 +bool QuickSortSafe(Array& arr) 1.1306 +{ 1.1307 + typedef typename Array::ValueType ValueType; 1.1308 + return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); 1.1309 +} 1.1310 + 1.1311 +//----------------------------------------------------------------------------------- 1.1312 +// ***** InsertionSortSliced 1.1313 +// 1.1314 +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. 1.1315 +// The range is specified with start, end, where "end" is exclusive! 1.1316 +// The comparison predicate must be specified. 1.1317 +// Unlike Quick Sort, the Insertion Sort works much slower in average, 1.1318 +// but may be much faster on almost sorted arrays. Besides, it guarantees 1.1319 +// that the elements will not be swapped if not necessary. For example, 1.1320 +// an array with all equal elements will remain "untouched", while 1.1321 +// Quick Sort will considerably shuffle the elements in this case. 1.1322 +template<class Array, class Less> 1.1323 +void InsertionSortSliced(Array& arr, UPInt start, UPInt end, Less less) 1.1324 +{ 1.1325 + UPInt j = start; 1.1326 + UPInt i = j + 1; 1.1327 + UPInt limit = end; 1.1328 + 1.1329 + for(; i < limit; j = i, i++) 1.1330 + { 1.1331 + for(; less(arr[j + 1], arr[j]); j--) 1.1332 + { 1.1333 + Swap(arr[j + 1], arr[j]); 1.1334 + if(j <= start) 1.1335 + { 1.1336 + break; 1.1337 + } 1.1338 + } 1.1339 + } 1.1340 +} 1.1341 + 1.1342 + 1.1343 +//----------------------------------------------------------------------------------- 1.1344 +// ***** InsertionSortSliced 1.1345 +// 1.1346 +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. 1.1347 +// The range is specified with start, end, where "end" is exclusive! 1.1348 +// The data type must have a defined "<" operator. 1.1349 +template<class Array> 1.1350 +void InsertionSortSliced(Array& arr, UPInt start, UPInt end) 1.1351 +{ 1.1352 + typedef typename Array::ValueType ValueType; 1.1353 + InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare); 1.1354 +} 1.1355 + 1.1356 +//----------------------------------------------------------------------------------- 1.1357 +// ***** InsertionSort 1.1358 +// 1.1359 +// Sort an array Array, ArrayPaged, ArrayUnsafe. 1.1360 +// The array must have GetSize() function. 1.1361 +// The comparison predicate must be specified. 1.1362 + 1.1363 +template<class Array, class Less> 1.1364 +void InsertionSort(Array& arr, Less less) 1.1365 +{ 1.1366 + InsertionSortSliced(arr, 0, arr.GetSize(), less); 1.1367 +} 1.1368 + 1.1369 +//----------------------------------------------------------------------------------- 1.1370 +// ***** InsertionSort 1.1371 +// 1.1372 +// Sort an array Array, ArrayPaged, ArrayUnsafe. 1.1373 +// The array must have GetSize() function. 1.1374 +// The data type must have a defined "<" operator. 1.1375 +template<class Array> 1.1376 +void InsertionSort(Array& arr) 1.1377 +{ 1.1378 + typedef typename Array::ValueType ValueType; 1.1379 + InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); 1.1380 +} 1.1381 + 1.1382 + 1.1383 + 1.1384 +//----------------------------------------------------------------------------------- 1.1385 +// ***** LowerBoundSliced 1.1386 +// 1.1387 +template<class Array, class Value, class Less> 1.1388 +UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less) 1.1389 +{ 1.1390 + SPInt first = (SPInt)start; 1.1391 + SPInt len = (SPInt)(end - start); 1.1392 + SPInt half; 1.1393 + SPInt middle; 1.1394 + 1.1395 + while(len > 0) 1.1396 + { 1.1397 + half = len >> 1; 1.1398 + middle = first + half; 1.1399 + if(less(arr[middle], val)) 1.1400 + { 1.1401 + first = middle + 1; 1.1402 + len = len - half - 1; 1.1403 + } 1.1404 + else 1.1405 + { 1.1406 + len = half; 1.1407 + } 1.1408 + } 1.1409 + return (UPInt)first; 1.1410 +} 1.1411 + 1.1412 + 1.1413 +//----------------------------------------------------------------------------------- 1.1414 +// ***** LowerBoundSliced 1.1415 +// 1.1416 +template<class Array, class Value> 1.1417 +UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val) 1.1418 +{ 1.1419 + return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare); 1.1420 +} 1.1421 + 1.1422 +//----------------------------------------------------------------------------------- 1.1423 +// ***** LowerBoundSized 1.1424 +// 1.1425 +template<class Array, class Value> 1.1426 +UPInt LowerBoundSized(const Array& arr, UPInt size, const Value& val) 1.1427 +{ 1.1428 + return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare); 1.1429 +} 1.1430 + 1.1431 +//----------------------------------------------------------------------------------- 1.1432 +// ***** LowerBound 1.1433 +// 1.1434 +template<class Array, class Value, class Less> 1.1435 +UPInt LowerBound(const Array& arr, const Value& val, Less less) 1.1436 +{ 1.1437 + return LowerBoundSliced(arr, 0, arr.GetSize(), val, less); 1.1438 +} 1.1439 + 1.1440 + 1.1441 +//----------------------------------------------------------------------------------- 1.1442 +// ***** LowerBound 1.1443 +// 1.1444 +template<class Array, class Value> 1.1445 +UPInt LowerBound(const Array& arr, const Value& val) 1.1446 +{ 1.1447 + return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare); 1.1448 +} 1.1449 + 1.1450 + 1.1451 + 1.1452 +//----------------------------------------------------------------------------------- 1.1453 +// ***** UpperBoundSliced 1.1454 +// 1.1455 +template<class Array, class Value, class Less> 1.1456 +UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less) 1.1457 +{ 1.1458 + SPInt first = (SPInt)start; 1.1459 + SPInt len = (SPInt)(end - start); 1.1460 + SPInt half; 1.1461 + SPInt middle; 1.1462 + 1.1463 + while(len > 0) 1.1464 + { 1.1465 + half = len >> 1; 1.1466 + middle = first + half; 1.1467 + if(less(val, arr[middle])) 1.1468 + { 1.1469 + len = half; 1.1470 + } 1.1471 + else 1.1472 + { 1.1473 + first = middle + 1; 1.1474 + len = len - half - 1; 1.1475 + } 1.1476 + } 1.1477 + return (UPInt)first; 1.1478 +} 1.1479 + 1.1480 + 1.1481 +//----------------------------------------------------------------------------------- 1.1482 +// ***** UpperBoundSliced 1.1483 +// 1.1484 +template<class Array, class Value> 1.1485 +UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val) 1.1486 +{ 1.1487 + return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare); 1.1488 +} 1.1489 + 1.1490 + 1.1491 +//----------------------------------------------------------------------------------- 1.1492 +// ***** UpperBoundSized 1.1493 +// 1.1494 +template<class Array, class Value> 1.1495 +UPInt UpperBoundSized(const Array& arr, UPInt size, const Value& val) 1.1496 +{ 1.1497 + return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare); 1.1498 +} 1.1499 + 1.1500 + 1.1501 +//----------------------------------------------------------------------------------- 1.1502 +// ***** UpperBound 1.1503 +// 1.1504 +template<class Array, class Value, class Less> 1.1505 +UPInt UpperBound(const Array& arr, const Value& val, Less less) 1.1506 +{ 1.1507 + return UpperBoundSliced(arr, 0, arr.GetSize(), val, less); 1.1508 +} 1.1509 + 1.1510 + 1.1511 +//----------------------------------------------------------------------------------- 1.1512 +// ***** UpperBound 1.1513 +// 1.1514 +template<class Array, class Value> 1.1515 +UPInt UpperBound(const Array& arr, const Value& val) 1.1516 +{ 1.1517 + return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare); 1.1518 +} 1.1519 + 1.1520 + 1.1521 +//----------------------------------------------------------------------------------- 1.1522 +// ***** ReverseArray 1.1523 +// 1.1524 +template<class Array> void ReverseArray(Array& arr) 1.1525 +{ 1.1526 + SPInt from = 0; 1.1527 + SPInt to = arr.GetSize() - 1; 1.1528 + while(from < to) 1.1529 + { 1.1530 + Swap(arr[from], arr[to]); 1.1531 + ++from; 1.1532 + --to; 1.1533 + } 1.1534 +} 1.1535 + 1.1536 + 1.1537 +// ***** AppendArray 1.1538 +// 1.1539 +template<class CDst, class CSrc> 1.1540 +void AppendArray(CDst& dst, const CSrc& src) 1.1541 +{ 1.1542 + UPInt i; 1.1543 + for(i = 0; i < src.GetSize(); i++) 1.1544 + dst.PushBack(src[i]); 1.1545 +} 1.1546 + 1.1547 +//----------------------------------------------------------------------------------- 1.1548 +// ***** ArrayAdaptor 1.1549 +// 1.1550 +// A simple adapter that provides the GetSize() method and overloads 1.1551 +// operator []. Used to wrap plain arrays in QuickSort and such. 1.1552 +template<class T> class ArrayAdaptor 1.1553 +{ 1.1554 +public: 1.1555 + typedef T ValueType; 1.1556 + ArrayAdaptor() : Data(0), Size(0) {} 1.1557 + ArrayAdaptor(T* ptr, UPInt size) : Data(ptr), Size(size) {} 1.1558 + UPInt GetSize() const { return Size; } 1.1559 + const T& operator [] (UPInt i) const { return Data[i]; } 1.1560 + T& operator [] (UPInt i) { return Data[i]; } 1.1561 +private: 1.1562 + T* Data; 1.1563 + UPInt Size; 1.1564 +}; 1.1565 + 1.1566 + 1.1567 +//----------------------------------------------------------------------------------- 1.1568 +// ***** GConstArrayAdaptor 1.1569 +// 1.1570 +// A simple const adapter that provides the GetSize() method and overloads 1.1571 +// operator []. Used to wrap plain arrays in LowerBound and such. 1.1572 +template<class T> class ConstArrayAdaptor 1.1573 +{ 1.1574 +public: 1.1575 + typedef T ValueType; 1.1576 + ConstArrayAdaptor() : Data(0), Size(0) {} 1.1577 + ConstArrayAdaptor(const T* ptr, UPInt size) : Data(ptr), Size(size) {} 1.1578 + UPInt GetSize() const { return Size; } 1.1579 + const T& operator [] (UPInt i) const { return Data[i]; } 1.1580 +private: 1.1581 + const T* Data; 1.1582 + UPInt Size; 1.1583 +}; 1.1584 + 1.1585 + 1.1586 + 1.1587 +//----------------------------------------------------------------------------------- 1.1588 +extern const UByte UpperBitTable[256]; 1.1589 +extern const UByte LowerBitTable[256]; 1.1590 + 1.1591 + 1.1592 + 1.1593 +//----------------------------------------------------------------------------------- 1.1594 +inline UByte UpperBit(UPInt val) 1.1595 +{ 1.1596 +#ifndef OVR_64BIT_POINTERS 1.1597 + 1.1598 + if (val & 0xFFFF0000) 1.1599 + { 1.1600 + return (val & 0xFF000000) ? 1.1601 + UpperBitTable[(val >> 24) ] + 24: 1.1602 + UpperBitTable[(val >> 16) & 0xFF] + 16; 1.1603 + } 1.1604 + return (val & 0xFF00) ? 1.1605 + UpperBitTable[(val >> 8) & 0xFF] + 8: 1.1606 + UpperBitTable[(val ) & 0xFF]; 1.1607 + 1.1608 +#else 1.1609 + 1.1610 + if (val & 0xFFFFFFFF00000000) 1.1611 + { 1.1612 + if (val & 0xFFFF000000000000) 1.1613 + { 1.1614 + return (val & 0xFF00000000000000) ? 1.1615 + UpperBitTable[(val >> 56) ] + 56: 1.1616 + UpperBitTable[(val >> 48) & 0xFF] + 48; 1.1617 + } 1.1618 + return (val & 0xFF0000000000) ? 1.1619 + UpperBitTable[(val >> 40) & 0xFF] + 40: 1.1620 + UpperBitTable[(val >> 32) & 0xFF] + 32; 1.1621 + } 1.1622 + else 1.1623 + { 1.1624 + if (val & 0xFFFF0000) 1.1625 + { 1.1626 + return (val & 0xFF000000) ? 1.1627 + UpperBitTable[(val >> 24) ] + 24: 1.1628 + UpperBitTable[(val >> 16) & 0xFF] + 16; 1.1629 + } 1.1630 + return (val & 0xFF00) ? 1.1631 + UpperBitTable[(val >> 8) & 0xFF] + 8: 1.1632 + UpperBitTable[(val ) & 0xFF]; 1.1633 + } 1.1634 + 1.1635 +#endif 1.1636 +} 1.1637 + 1.1638 +//----------------------------------------------------------------------------------- 1.1639 +inline UByte LowerBit(UPInt val) 1.1640 +{ 1.1641 +#ifndef OVR_64BIT_POINTERS 1.1642 + 1.1643 + if (val & 0xFFFF) 1.1644 + { 1.1645 + return (val & 0xFF) ? 1.1646 + LowerBitTable[ val & 0xFF]: 1.1647 + LowerBitTable[(val >> 8) & 0xFF] + 8; 1.1648 + } 1.1649 + return (val & 0xFF0000) ? 1.1650 + LowerBitTable[(val >> 16) & 0xFF] + 16: 1.1651 + LowerBitTable[(val >> 24) & 0xFF] + 24; 1.1652 + 1.1653 +#else 1.1654 + 1.1655 + if (val & 0xFFFFFFFF) 1.1656 + { 1.1657 + if (val & 0xFFFF) 1.1658 + { 1.1659 + return (val & 0xFF) ? 1.1660 + LowerBitTable[ val & 0xFF]: 1.1661 + LowerBitTable[(val >> 8) & 0xFF] + 8; 1.1662 + } 1.1663 + return (val & 0xFF0000) ? 1.1664 + LowerBitTable[(val >> 16) & 0xFF] + 16: 1.1665 + LowerBitTable[(val >> 24) & 0xFF] + 24; 1.1666 + } 1.1667 + else 1.1668 + { 1.1669 + if (val & 0xFFFF00000000) 1.1670 + { 1.1671 + return (val & 0xFF00000000) ? 1.1672 + LowerBitTable[(val >> 32) & 0xFF] + 32: 1.1673 + LowerBitTable[(val >> 40) & 0xFF] + 40; 1.1674 + } 1.1675 + return (val & 0xFF000000000000) ? 1.1676 + LowerBitTable[(val >> 48) & 0xFF] + 48: 1.1677 + LowerBitTable[(val >> 56) & 0xFF] + 56; 1.1678 + } 1.1679 + 1.1680 +#endif 1.1681 +} 1.1682 + 1.1683 + 1.1684 + 1.1685 +// ******* Special (optimized) memory routines 1.1686 +// Note: null (bad) pointer is not tested 1.1687 +class MemUtil 1.1688 +{ 1.1689 +public: 1.1690 + 1.1691 + // Memory compare 1.1692 + static int Cmp (const void* p1, const void* p2, UPInt byteCount) { return memcmp(p1, p2, byteCount); } 1.1693 + static int Cmp16(const void* p1, const void* p2, UPInt int16Count); 1.1694 + static int Cmp32(const void* p1, const void* p2, UPInt int32Count); 1.1695 + static int Cmp64(const void* p1, const void* p2, UPInt int64Count); 1.1696 +}; 1.1697 + 1.1698 +// ** Inline Implementation 1.1699 + 1.1700 +inline int MemUtil::Cmp16(const void* p1, const void* p2, UPInt int16Count) 1.1701 +{ 1.1702 + SInt16* pa = (SInt16*)p1; 1.1703 + SInt16* pb = (SInt16*)p2; 1.1704 + unsigned ic = 0; 1.1705 + if (int16Count == 0) 1.1706 + return 0; 1.1707 + while (pa[ic] == pb[ic]) 1.1708 + if (++ic==int16Count) 1.1709 + return 0; 1.1710 + return pa[ic] > pb[ic] ? 1 : -1; 1.1711 +} 1.1712 +inline int MemUtil::Cmp32(const void* p1, const void* p2, UPInt int32Count) 1.1713 +{ 1.1714 + SInt32* pa = (SInt32*)p1; 1.1715 + SInt32* pb = (SInt32*)p2; 1.1716 + unsigned ic = 0; 1.1717 + if (int32Count == 0) 1.1718 + return 0; 1.1719 + while (pa[ic] == pb[ic]) 1.1720 + if (++ic==int32Count) 1.1721 + return 0; 1.1722 + return pa[ic] > pb[ic] ? 1 : -1; 1.1723 +} 1.1724 +inline int MemUtil::Cmp64(const void* p1, const void* p2, UPInt int64Count) 1.1725 +{ 1.1726 + SInt64* pa = (SInt64*)p1; 1.1727 + SInt64* pb = (SInt64*)p2; 1.1728 + unsigned ic = 0; 1.1729 + if (int64Count == 0) 1.1730 + return 0; 1.1731 + while (pa[ic] == pb[ic]) 1.1732 + if (++ic==int64Count) 1.1733 + return 0; 1.1734 + return pa[ic] > pb[ic] ? 1 : -1; 1.1735 +} 1.1736 + 1.1737 +// ** End Inline Implementation 1.1738 + 1.1739 + 1.1740 +//----------------------------------------------------------------------------------- 1.1741 +// ******* Byte Order Conversions 1.1742 +namespace ByteUtil { 1.1743 + 1.1744 + // *** Swap Byte Order 1.1745 + 1.1746 + // Swap the byte order of a byte array 1.1747 + inline void SwapOrder(void* pv, int size) 1.1748 + { 1.1749 + UByte* pb = (UByte*)pv; 1.1750 + UByte temp; 1.1751 + for (int i = 0; i < size>>1; i++) 1.1752 + { 1.1753 + temp = pb[size-1-i]; 1.1754 + pb[size-1-i] = pb[i]; 1.1755 + pb[i] = temp; 1.1756 + } 1.1757 + } 1.1758 + 1.1759 + // Swap the byte order of primitive types 1.1760 + inline UByte SwapOrder(UByte v) { return v; } 1.1761 + inline SByte SwapOrder(SByte v) { return v; } 1.1762 + inline UInt16 SwapOrder(UInt16 v) { return UInt16(v>>8)|UInt16(v<<8); } 1.1763 + inline SInt16 SwapOrder(SInt16 v) { return SInt16((UInt16(v)>>8)|(v<<8)); } 1.1764 + inline UInt32 SwapOrder(UInt32 v) { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); } 1.1765 + inline SInt32 SwapOrder(SInt32 p) { return (SInt32)SwapOrder(UInt32(p)); } 1.1766 + inline UInt64 SwapOrder(UInt64 v) 1.1767 + { 1.1768 + return (v>>56) | 1.1769 + ((v&UInt64(0x00FF000000000000))>>40) | 1.1770 + ((v&UInt64(0x0000FF0000000000))>>24) | 1.1771 + ((v&UInt64(0x000000FF00000000))>>8) | 1.1772 + ((v&UInt64(0x00000000FF000000))<<8) | 1.1773 + ((v&UInt64(0x0000000000FF0000))<<24) | 1.1774 + ((v&UInt64(0x000000000000FF00))<<40) | 1.1775 + (v<<56); 1.1776 + } 1.1777 + inline SInt64 SwapOrder(SInt64 v) { return (SInt64)SwapOrder(UInt64(v)); } 1.1778 + inline float SwapOrder(float p) 1.1779 + { 1.1780 + union { 1.1781 + float p; 1.1782 + UInt32 v; 1.1783 + } u; 1.1784 + u.p = p; 1.1785 + u.v = SwapOrder(u.v); 1.1786 + return u.p; 1.1787 + } 1.1788 + 1.1789 + inline double SwapOrder(double p) 1.1790 + { 1.1791 + union { 1.1792 + double p; 1.1793 + UInt64 v; 1.1794 + } u; 1.1795 + u.p = p; 1.1796 + u.v = SwapOrder(u.v); 1.1797 + return u.p; 1.1798 + } 1.1799 + 1.1800 + // *** Byte-order conversion 1.1801 + 1.1802 +#if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN) 1.1803 + // Little Endian to System (LE) 1.1804 + inline UByte LEToSystem(UByte v) { return v; } 1.1805 + inline SByte LEToSystem(SByte v) { return v; } 1.1806 + inline UInt16 LEToSystem(UInt16 v) { return v; } 1.1807 + inline SInt16 LEToSystem(SInt16 v) { return v; } 1.1808 + inline UInt32 LEToSystem(UInt32 v) { return v; } 1.1809 + inline SInt32 LEToSystem(SInt32 v) { return v; } 1.1810 + inline UInt64 LEToSystem(UInt64 v) { return v; } 1.1811 + inline SInt64 LEToSystem(SInt64 v) { return v; } 1.1812 + inline float LEToSystem(float v) { return v; } 1.1813 + inline double LEToSystem(double v) { return v; } 1.1814 + 1.1815 + // Big Endian to System (LE) 1.1816 + inline UByte BEToSystem(UByte v) { return SwapOrder(v); } 1.1817 + inline SByte BEToSystem(SByte v) { return SwapOrder(v); } 1.1818 + inline UInt16 BEToSystem(UInt16 v) { return SwapOrder(v); } 1.1819 + inline SInt16 BEToSystem(SInt16 v) { return SwapOrder(v); } 1.1820 + inline UInt32 BEToSystem(UInt32 v) { return SwapOrder(v); } 1.1821 + inline SInt32 BEToSystem(SInt32 v) { return SwapOrder(v); } 1.1822 + inline UInt64 BEToSystem(UInt64 v) { return SwapOrder(v); } 1.1823 + inline SInt64 BEToSystem(SInt64 v) { return SwapOrder(v); } 1.1824 + inline float BEToSystem(float v) { return SwapOrder(v); } 1.1825 + inline double BEToSystem(double v) { return SwapOrder(v); } 1.1826 + 1.1827 + // System (LE) to Little Endian 1.1828 + inline UByte SystemToLE(UByte v) { return v; } 1.1829 + inline SByte SystemToLE(SByte v) { return v; } 1.1830 + inline UInt16 SystemToLE(UInt16 v) { return v; } 1.1831 + inline SInt16 SystemToLE(SInt16 v) { return v; } 1.1832 + inline UInt32 SystemToLE(UInt32 v) { return v; } 1.1833 + inline SInt32 SystemToLE(SInt32 v) { return v; } 1.1834 + inline UInt64 SystemToLE(UInt64 v) { return v; } 1.1835 + inline SInt64 SystemToLE(SInt64 v) { return v; } 1.1836 + inline float SystemToLE(float v) { return v; } 1.1837 + inline double SystemToLE(double v) { return v; } 1.1838 + 1.1839 + // System (LE) to Big Endian 1.1840 + inline UByte SystemToBE(UByte v) { return SwapOrder(v); } 1.1841 + inline SByte SystemToBE(SByte v) { return SwapOrder(v); } 1.1842 + inline UInt16 SystemToBE(UInt16 v) { return SwapOrder(v); } 1.1843 + inline SInt16 SystemToBE(SInt16 v) { return SwapOrder(v); } 1.1844 + inline UInt32 SystemToBE(UInt32 v) { return SwapOrder(v); } 1.1845 + inline SInt32 SystemToBE(SInt32 v) { return SwapOrder(v); } 1.1846 + inline UInt64 SystemToBE(UInt64 v) { return SwapOrder(v); } 1.1847 + inline SInt64 SystemToBE(SInt64 v) { return SwapOrder(v); } 1.1848 + inline float SystemToBE(float v) { return SwapOrder(v); } 1.1849 + inline double SystemToBE(double v) { return SwapOrder(v); } 1.1850 + 1.1851 +#elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN) 1.1852 + // Little Endian to System (BE) 1.1853 + inline UByte LEToSystem(UByte v) { return SwapOrder(v); } 1.1854 + inline SByte LEToSystem(SByte v) { return SwapOrder(v); } 1.1855 + inline UInt16 LEToSystem(UInt16 v) { return SwapOrder(v); } 1.1856 + inline SInt16 LEToSystem(SInt16 v) { return SwapOrder(v); } 1.1857 + inline UInt32 LEToSystem(UInt32 v) { return SwapOrder(v); } 1.1858 + inline SInt32 LEToSystem(SInt32 v) { return SwapOrder(v); } 1.1859 + inline UInt64 LEToSystem(UInt64 v) { return SwapOrder(v); } 1.1860 + inline SInt64 LEToSystem(SInt64 v) { return SwapOrder(v); } 1.1861 + inline float LEToSystem(float v) { return SwapOrder(v); } 1.1862 + inline double LEToSystem(double v) { return SwapOrder(v); } 1.1863 + 1.1864 + // Big Endian to System (BE) 1.1865 + inline UByte BEToSystem(UByte v) { return v; } 1.1866 + inline SByte BEToSystem(SByte v) { return v; } 1.1867 + inline UInt16 BEToSystem(UInt16 v) { return v; } 1.1868 + inline SInt16 BEToSystem(SInt16 v) { return v; } 1.1869 + inline UInt32 BEToSystem(UInt32 v) { return v; } 1.1870 + inline SInt32 BEToSystem(SInt32 v) { return v; } 1.1871 + inline UInt64 BEToSystem(UInt64 v) { return v; } 1.1872 + inline SInt64 BEToSystem(SInt64 v) { return v; } 1.1873 + inline float BEToSystem(float v) { return v; } 1.1874 + inline double BEToSystem(double v) { return v; } 1.1875 + 1.1876 + // System (BE) to Little Endian 1.1877 + inline UByte SystemToLE(UByte v) { return SwapOrder(v); } 1.1878 + inline SByte SystemToLE(SByte v) { return SwapOrder(v); } 1.1879 + inline UInt16 SystemToLE(UInt16 v) { return SwapOrder(v); } 1.1880 + inline SInt16 SystemToLE(SInt16 v) { return SwapOrder(v); } 1.1881 + inline UInt32 SystemToLE(UInt32 v) { return SwapOrder(v); } 1.1882 + inline SInt32 SystemToLE(SInt32 v) { return SwapOrder(v); } 1.1883 + inline UInt64 SystemToLE(UInt64 v) { return SwapOrder(v); } 1.1884 + inline SInt64 SystemToLE(SInt64 v) { return SwapOrder(v); } 1.1885 + inline float SystemToLE(float v) { return SwapOrder(v); } 1.1886 + inline double SystemToLE(double v) { return SwapOrder(v); } 1.1887 + 1.1888 + // System (BE) to Big Endian 1.1889 + inline UByte SystemToBE(UByte v) { return v; } 1.1890 + inline SByte SystemToBE(SByte v) { return v; } 1.1891 + inline UInt16 SystemToBE(UInt16 v) { return v; } 1.1892 + inline SInt16 SystemToBE(SInt16 v) { return v; } 1.1893 + inline UInt32 SystemToBE(UInt32 v) { return v; } 1.1894 + inline SInt32 SystemToBE(SInt32 v) { return v; } 1.1895 + inline UInt64 SystemToBE(UInt64 v) { return v; } 1.1896 + inline SInt64 SystemToBE(SInt64 v) { return v; } 1.1897 + inline float SystemToBE(float v) { return v; } 1.1898 + inline double SystemToBE(double v) { return v; } 1.1899 + 1.1900 +#else 1.1901 + #error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN" 1.1902 +#endif 1.1903 + 1.1904 +} // namespace ByteUtil 1.1905 + 1.1906 + 1.1907 + 1.1908 +}} // OVR::Alg 1.1909 + 1.1910 +#endif