OVR_Alg.h 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. /************************************************************************************
  2. PublicHeader: OVR_Kernel.h
  3. Filename : OVR_Alg.h
  4. Content : Simple general purpose algorithms: Sort, Binary Search, etc.
  5. Created : September 19, 2012
  6. Notes :
  7. Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
  8. Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
  9. you may not use the Oculus VR Rift SDK except in compliance with the License,
  10. which is provided at the time of installation or download, or which
  11. otherwise accompanies this software in either electronic or hard copy form.
  12. You may obtain a copy of the License at
  13. http://www.oculusvr.com/licenses/LICENSE-3.2
  14. Unless required by applicable law or agreed to in writing, the Oculus VR SDK
  15. distributed under the License is distributed on an "AS IS" BASIS,
  16. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. See the License for the specific language governing permissions and
  18. limitations under the License.
  19. ************************************************************************************/
  20. #ifndef OVR_Alg_h
  21. #define OVR_Alg_h
  22. #include "OVR_Types.h"
  23. #include <string.h>
  24. #if defined(_MSC_VER)
  25. #include <intrin.h>
  26. #pragma intrinsic(_BitScanForward)
  27. #if defined(_M_AMD64)
  28. #pragma intrinsic(_BitScanForward64)
  29. #endif
  30. #elif defined(__GNUC__) || defined(__clang__)
  31. #include <x86intrin.h>
  32. #endif
  33. namespace OVR { namespace Alg {
  34. inline int CountTrailing0Bits(uint16_t x)
  35. {
  36. #if defined(_MSC_VER)
  37. unsigned long i;
  38. unsigned char nonZero = _BitScanForward(&i, x);
  39. return nonZero ? (int)i : 16;
  40. #elif defined(__GNUC__) || defined(__clang__)
  41. if (x)
  42. return __builtin_ctz(x);
  43. return 16;
  44. #else
  45. if (x)
  46. {
  47. int n = 1;
  48. if((x & 0x000000ff) == 0) {n += 8; x >>= 8;}
  49. if((x & 0x0000000f) == 0) {n += 4; x >>= 4;}
  50. if((x & 0x00000003) == 0) {n += 2; x >>= 2;}
  51. return n - int(x & 1);
  52. }
  53. return 16;
  54. #endif
  55. }
  56. inline int CountTrailing0Bits(uint32_t x)
  57. {
  58. #if defined(_MSC_VER)
  59. unsigned long i;
  60. unsigned char nonZero = _BitScanForward(&i, x);
  61. return nonZero ? (int)i : 32;
  62. #elif defined(__GNUC__) || defined(__clang__)
  63. if (x)
  64. return __builtin_ctz(x);
  65. return 32;
  66. #else
  67. if (x)
  68. {
  69. int n = 1;
  70. if((x & 0x0000ffff) == 0) { n += 16; x >>= 16; }
  71. if((x & 0x000000ff) == 0) { n += 8; x >>= 8; }
  72. if((x & 0x0000000f) == 0) { n += 4; x >>= 4; }
  73. if((x & 0x00000003) == 0) { n += 2; x >>= 2; }
  74. return n - int(x & 1);
  75. }
  76. return 32;
  77. #endif
  78. }
  79. inline int CountTrailing0Bits(uint64_t x)
  80. {
  81. #if defined(_MSC_VER) && defined(_M_AMD64)
  82. unsigned long i;
  83. unsigned char nonZero = _BitScanForward64(&i, x);
  84. return nonZero ? (int)i : 64;
  85. #elif (defined(__GNUC__) || defined(__clang__)) && defined(__x86_64__)
  86. if (x)
  87. return __builtin_ctzll(x);
  88. return 64;
  89. #else
  90. if (x)
  91. {
  92. int n = 1;
  93. if((x & 0xffffffff) == 0) { n += 32; x >>= 32; }
  94. if((x & 0x0000ffff) == 0) { n += 16; x >>= 16; }
  95. if((x & 0x000000ff) == 0) { n += 8; x >>= 8; }
  96. if((x & 0x0000000f) == 0) { n += 4; x >>= 4; }
  97. if((x & 0x00000003) == 0) { n += 2; x >>= 2; }
  98. return n - (int)(uint32_t)(x & 1);
  99. }
  100. return 64;
  101. #endif
  102. }
  103. //-----------------------------------------------------------------------------------
  104. // ***** Operator extensions
  105. template <typename T> OVR_FORCE_INLINE void Swap(T &a, T &b)
  106. { T temp(a); a = b; b = temp; }
  107. // ***** min/max are not implemented in Visual Studio 6 standard STL
  108. template <typename T> OVR_FORCE_INLINE const T Min(const T a, const T b)
  109. { return (a < b) ? a : b; }
  110. template <typename T> OVR_FORCE_INLINE const T Max(const T a, const T b)
  111. { return (b < a) ? a : b; }
  112. template <typename T> OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal)
  113. { return Max<T>(minVal, Min<T>(v, maxVal)); }
  114. template <typename T> OVR_FORCE_INLINE int Chop(T f)
  115. { return (int)f; }
  116. template <typename T> OVR_FORCE_INLINE T Lerp(T a, T b, T f)
  117. { return (b - a) * f + a; }
  118. // These functions stand to fix a stupid VC++ warning (with /Wp64 on):
  119. // "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data"
  120. // Use these functions instead of gmin/gmax if the argument has size
  121. // of the pointer to avoid the warning. Though, functionally they are
  122. // absolutelly the same as regular gmin/gmax.
  123. template <typename T> OVR_FORCE_INLINE const T PMin(const T a, const T b)
  124. {
  125. OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t));
  126. return (a < b) ? a : b;
  127. }
  128. template <typename T> OVR_FORCE_INLINE const T PMax(const T a, const T b)
  129. {
  130. OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t));
  131. return (b < a) ? a : b;
  132. }
  133. template <typename T> OVR_FORCE_INLINE const T Abs(const T v)
  134. { return (v>=0) ? v : -v; }
  135. //-----------------------------------------------------------------------------------
  136. // ***** OperatorLess
  137. //
  138. template<class T> struct OperatorLess
  139. {
  140. static bool Compare(const T& a, const T& b)
  141. {
  142. return a < b;
  143. }
  144. };
  145. //-----------------------------------------------------------------------------------
  146. // ***** QuickSortSliced
  147. //
  148. // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
  149. // The range is specified with start, end, where "end" is exclusive!
  150. // The comparison predicate must be specified.
  151. template<class Array, class Less>
  152. void QuickSortSliced(Array& arr, size_t start, size_t end, Less less)
  153. {
  154. enum
  155. {
  156. Threshold = 9
  157. };
  158. if(end - start < 2) return;
  159. intptr_t stack[80];
  160. intptr_t* top = stack;
  161. intptr_t base = (intptr_t)start;
  162. intptr_t limit = (intptr_t)end;
  163. for(;;)
  164. {
  165. intptr_t len = limit - base;
  166. intptr_t i, j, pivot;
  167. if(len > Threshold)
  168. {
  169. // we use base + len/2 as the pivot
  170. pivot = base + len / 2;
  171. Swap(arr[base], arr[pivot]);
  172. i = base + 1;
  173. j = limit - 1;
  174. // now ensure that *i <= *base <= *j
  175. if(less(arr[j], arr[i])) Swap(arr[j], arr[i]);
  176. if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
  177. if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
  178. for(;;)
  179. {
  180. do i++; while( less(arr[i], arr[base]) );
  181. do j--; while( less(arr[base], arr[j]) );
  182. if( i > j )
  183. {
  184. break;
  185. }
  186. Swap(arr[i], arr[j]);
  187. }
  188. Swap(arr[base], arr[j]);
  189. // now, push the largest sub-array
  190. if(j - base > limit - i)
  191. {
  192. top[0] = base;
  193. top[1] = j;
  194. base = i;
  195. }
  196. else
  197. {
  198. top[0] = i;
  199. top[1] = limit;
  200. limit = j;
  201. }
  202. top += 2;
  203. }
  204. else
  205. {
  206. // the sub-array is small, perform insertion sort
  207. j = base;
  208. i = j + 1;
  209. for(; i < limit; j = i, i++)
  210. {
  211. for(; less(arr[j + 1], arr[j]); j--)
  212. {
  213. Swap(arr[j + 1], arr[j]);
  214. if(j == base)
  215. {
  216. break;
  217. }
  218. }
  219. }
  220. if(top > stack)
  221. {
  222. top -= 2;
  223. base = top[0];
  224. limit = top[1];
  225. }
  226. else
  227. {
  228. break;
  229. }
  230. }
  231. }
  232. }
  233. //-----------------------------------------------------------------------------------
  234. // ***** QuickSortSliced
  235. //
  236. // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
  237. // The range is specified with start, end, where "end" is exclusive!
  238. // The data type must have a defined "<" operator.
  239. template<class Array>
  240. void QuickSortSliced(Array& arr, size_t start, size_t end)
  241. {
  242. typedef typename Array::ValueType ValueType;
  243. QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
  244. }
  245. // Same as corresponding G_QuickSortSliced but with checking array limits to avoid
  246. // crash in the case of wrong comparator functor.
  247. template<class Array, class Less>
  248. bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end, Less less)
  249. {
  250. enum
  251. {
  252. Threshold = 9
  253. };
  254. if(end - start < 2) return true;
  255. intptr_t stack[80];
  256. intptr_t* top = stack;
  257. intptr_t base = (intptr_t)start;
  258. intptr_t limit = (intptr_t)end;
  259. for(;;)
  260. {
  261. intptr_t len = limit - base;
  262. intptr_t i, j, pivot;
  263. if(len > Threshold)
  264. {
  265. // we use base + len/2 as the pivot
  266. pivot = base + len / 2;
  267. Swap(arr[base], arr[pivot]);
  268. i = base + 1;
  269. j = limit - 1;
  270. // now ensure that *i <= *base <= *j
  271. if(less(arr[j], arr[i])) Swap(arr[j], arr[i]);
  272. if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
  273. if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
  274. for(;;)
  275. {
  276. do
  277. {
  278. i++;
  279. if (i >= limit)
  280. return false;
  281. } while( less(arr[i], arr[base]) );
  282. do
  283. {
  284. j--;
  285. if (j < 0)
  286. return false;
  287. } while( less(arr[base], arr[j]) );
  288. if( i > j )
  289. {
  290. break;
  291. }
  292. Swap(arr[i], arr[j]);
  293. }
  294. Swap(arr[base], arr[j]);
  295. // now, push the largest sub-array
  296. if(j - base > limit - i)
  297. {
  298. top[0] = base;
  299. top[1] = j;
  300. base = i;
  301. }
  302. else
  303. {
  304. top[0] = i;
  305. top[1] = limit;
  306. limit = j;
  307. }
  308. top += 2;
  309. }
  310. else
  311. {
  312. // the sub-array is small, perform insertion sort
  313. j = base;
  314. i = j + 1;
  315. for(; i < limit; j = i, i++)
  316. {
  317. for(; less(arr[j + 1], arr[j]); j--)
  318. {
  319. Swap(arr[j + 1], arr[j]);
  320. if(j == base)
  321. {
  322. break;
  323. }
  324. }
  325. }
  326. if(top > stack)
  327. {
  328. top -= 2;
  329. base = top[0];
  330. limit = top[1];
  331. }
  332. else
  333. {
  334. break;
  335. }
  336. }
  337. }
  338. return true;
  339. }
  340. template<class Array>
  341. bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end)
  342. {
  343. typedef typename Array::ValueType ValueType;
  344. return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare);
  345. }
  346. //-----------------------------------------------------------------------------------
  347. // ***** QuickSort
  348. //
  349. // Sort an array Array, ArrayPaged, ArrayUnsafe.
  350. // The array must have GetSize() function.
  351. // The comparison predicate must be specified.
  352. template<class Array, class Less>
  353. void QuickSort(Array& arr, Less less)
  354. {
  355. QuickSortSliced(arr, 0, arr.GetSize(), less);
  356. }
  357. // checks for boundaries
  358. template<class Array, class Less>
  359. bool QuickSortSafe(Array& arr, Less less)
  360. {
  361. return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less);
  362. }
  363. //-----------------------------------------------------------------------------------
  364. // ***** QuickSort
  365. //
  366. // Sort an array Array, ArrayPaged, ArrayUnsafe.
  367. // The array must have GetSize() function.
  368. // The data type must have a defined "<" operator.
  369. template<class Array>
  370. void QuickSort(Array& arr)
  371. {
  372. typedef typename Array::ValueType ValueType;
  373. QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
  374. }
  375. template<class Array>
  376. bool QuickSortSafe(Array& arr)
  377. {
  378. typedef typename Array::ValueType ValueType;
  379. return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
  380. }
  381. //-----------------------------------------------------------------------------------
  382. // ***** InsertionSortSliced
  383. //
  384. // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
  385. // The range is specified with start, end, where "end" is exclusive!
  386. // The comparison predicate must be specified.
  387. // Unlike Quick Sort, the Insertion Sort works much slower in average,
  388. // but may be much faster on almost sorted arrays. Besides, it guarantees
  389. // that the elements will not be swapped if not necessary. For example,
  390. // an array with all equal elements will remain "untouched", while
  391. // Quick Sort will considerably shuffle the elements in this case.
  392. template<class Array, class Less>
  393. void InsertionSortSliced(Array& arr, size_t start, size_t end, Less less)
  394. {
  395. size_t j = start;
  396. size_t i = j + 1;
  397. size_t limit = end;
  398. for(; i < limit; j = i, i++)
  399. {
  400. for(; less(arr[j + 1], arr[j]); j--)
  401. {
  402. Swap(arr[j + 1], arr[j]);
  403. if(j <= start)
  404. {
  405. break;
  406. }
  407. }
  408. }
  409. }
  410. //-----------------------------------------------------------------------------------
  411. // ***** InsertionSortSliced
  412. //
  413. // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
  414. // The range is specified with start, end, where "end" is exclusive!
  415. // The data type must have a defined "<" operator.
  416. template<class Array>
  417. void InsertionSortSliced(Array& arr, size_t start, size_t end)
  418. {
  419. typedef typename Array::ValueType ValueType;
  420. InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
  421. }
  422. //-----------------------------------------------------------------------------------
  423. // ***** InsertionSort
  424. //
  425. // Sort an array Array, ArrayPaged, ArrayUnsafe.
  426. // The array must have GetSize() function.
  427. // The comparison predicate must be specified.
  428. template<class Array, class Less>
  429. void InsertionSort(Array& arr, Less less)
  430. {
  431. InsertionSortSliced(arr, 0, arr.GetSize(), less);
  432. }
  433. //-----------------------------------------------------------------------------------
  434. // ***** InsertionSort
  435. //
  436. // Sort an array Array, ArrayPaged, ArrayUnsafe.
  437. // The array must have GetSize() function.
  438. // The data type must have a defined "<" operator.
  439. template<class Array>
  440. void InsertionSort(Array& arr)
  441. {
  442. typedef typename Array::ValueType ValueType;
  443. InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
  444. }
  445. //-----------------------------------------------------------------------------------
  446. // ***** Median
  447. // Returns a median value of the input array.
  448. // Caveats: partially sorts the array, returns a reference to the array element
  449. // TBD: This needs to be optimized and generalized
  450. //
  451. template<class Array>
  452. typename Array::ValueType& Median(Array& arr)
  453. {
  454. size_t count = arr.GetSize();
  455. size_t mid = (count - 1) / 2;
  456. OVR_ASSERT(count > 0);
  457. for (size_t j = 0; j <= mid; j++)
  458. {
  459. size_t min = j;
  460. for (size_t k = j + 1; k < count; k++)
  461. if (arr[k] < arr[min])
  462. min = k;
  463. Swap(arr[j], arr[min]);
  464. }
  465. return arr[mid];
  466. }
  467. //-----------------------------------------------------------------------------------
  468. // ***** LowerBoundSliced
  469. //
  470. template<class Array, class Value, class Less>
  471. size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less)
  472. {
  473. intptr_t first = (intptr_t)start;
  474. intptr_t len = (intptr_t)(end - start);
  475. intptr_t half;
  476. intptr_t middle;
  477. while(len > 0)
  478. {
  479. half = len >> 1;
  480. middle = first + half;
  481. if(less(arr[middle], val))
  482. {
  483. first = middle + 1;
  484. len = len - half - 1;
  485. }
  486. else
  487. {
  488. len = half;
  489. }
  490. }
  491. return (size_t)first;
  492. }
  493. //-----------------------------------------------------------------------------------
  494. // ***** LowerBoundSliced
  495. //
  496. template<class Array, class Value>
  497. size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val)
  498. {
  499. return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
  500. }
  501. //-----------------------------------------------------------------------------------
  502. // ***** LowerBoundSized
  503. //
  504. template<class Array, class Value>
  505. size_t LowerBoundSized(const Array& arr, size_t size, const Value& val)
  506. {
  507. return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
  508. }
  509. //-----------------------------------------------------------------------------------
  510. // ***** LowerBound
  511. //
  512. template<class Array, class Value, class Less>
  513. size_t LowerBound(const Array& arr, const Value& val, Less less)
  514. {
  515. return LowerBoundSliced(arr, 0, arr.GetSize(), val, less);
  516. }
  517. //-----------------------------------------------------------------------------------
  518. // ***** LowerBound
  519. //
  520. template<class Array, class Value>
  521. size_t LowerBound(const Array& arr, const Value& val)
  522. {
  523. return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
  524. }
  525. //-----------------------------------------------------------------------------------
  526. // ***** UpperBoundSliced
  527. //
  528. template<class Array, class Value, class Less>
  529. size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less)
  530. {
  531. intptr_t first = (intptr_t)start;
  532. intptr_t len = (intptr_t)(end - start);
  533. intptr_t half;
  534. intptr_t middle;
  535. while(len > 0)
  536. {
  537. half = len >> 1;
  538. middle = first + half;
  539. if(less(val, arr[middle]))
  540. {
  541. len = half;
  542. }
  543. else
  544. {
  545. first = middle + 1;
  546. len = len - half - 1;
  547. }
  548. }
  549. return (size_t)first;
  550. }
  551. //-----------------------------------------------------------------------------------
  552. // ***** UpperBoundSliced
  553. //
  554. template<class Array, class Value>
  555. size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val)
  556. {
  557. return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
  558. }
  559. //-----------------------------------------------------------------------------------
  560. // ***** UpperBoundSized
  561. //
  562. template<class Array, class Value>
  563. size_t UpperBoundSized(const Array& arr, size_t size, const Value& val)
  564. {
  565. return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
  566. }
  567. //-----------------------------------------------------------------------------------
  568. // ***** UpperBound
  569. //
  570. template<class Array, class Value, class Less>
  571. size_t UpperBound(const Array& arr, const Value& val, Less less)
  572. {
  573. return UpperBoundSliced(arr, 0, arr.GetSize(), val, less);
  574. }
  575. //-----------------------------------------------------------------------------------
  576. // ***** UpperBound
  577. //
  578. template<class Array, class Value>
  579. size_t UpperBound(const Array& arr, const Value& val)
  580. {
  581. return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
  582. }
  583. //-----------------------------------------------------------------------------------
  584. // ***** ReverseArray
  585. //
  586. template<class Array> void ReverseArray(Array& arr)
  587. {
  588. intptr_t from = 0;
  589. intptr_t to = arr.GetSize() - 1;
  590. while(from < to)
  591. {
  592. Swap(arr[from], arr[to]);
  593. ++from;
  594. --to;
  595. }
  596. }
  597. // ***** AppendArray
  598. //
  599. template<class CDst, class CSrc>
  600. void AppendArray(CDst& dst, const CSrc& src)
  601. {
  602. size_t i;
  603. for(i = 0; i < src.GetSize(); i++)
  604. dst.PushBack(src[i]);
  605. }
  606. //-----------------------------------------------------------------------------------
  607. // ***** ArrayAdaptor
  608. //
  609. // A simple adapter that provides the GetSize() method and overloads
  610. // operator []. Used to wrap plain arrays in QuickSort and such.
  611. template<class T> class ArrayAdaptor
  612. {
  613. public:
  614. typedef T ValueType;
  615. ArrayAdaptor() : Data(0), Size(0) {}
  616. ArrayAdaptor(T* ptr, size_t size) : Data(ptr), Size(size) {}
  617. size_t GetSize() const { return Size; }
  618. int GetSizeI() const { return (int)GetSize(); }
  619. const T& operator [] (size_t i) const { return Data[i]; }
  620. T& operator [] (size_t i) { return Data[i]; }
  621. private:
  622. T* Data;
  623. size_t Size;
  624. };
  625. //-----------------------------------------------------------------------------------
  626. // ***** GConstArrayAdaptor
  627. //
  628. // A simple const adapter that provides the GetSize() method and overloads
  629. // operator []. Used to wrap plain arrays in LowerBound and such.
  630. template<class T> class ConstArrayAdaptor
  631. {
  632. public:
  633. typedef T ValueType;
  634. ConstArrayAdaptor() : Data(0), Size(0) {}
  635. ConstArrayAdaptor(const T* ptr, size_t size) : Data(ptr), Size(size) {}
  636. size_t GetSize() const { return Size; }
  637. int GetSizeI() const { return (int)GetSize(); }
  638. const T& operator [] (size_t i) const { return Data[i]; }
  639. private:
  640. const T* Data;
  641. size_t Size;
  642. };
  643. //-----------------------------------------------------------------------------------
  644. extern const uint8_t UpperBitTable[256];
  645. extern const uint8_t LowerBitTable[256];
  646. //-----------------------------------------------------------------------------------
  647. inline uint8_t UpperBit(size_t val)
  648. {
  649. #ifndef OVR_64BIT_POINTERS
  650. if (val & 0xFFFF0000)
  651. {
  652. return (val & 0xFF000000) ?
  653. UpperBitTable[(val >> 24) ] + 24:
  654. UpperBitTable[(val >> 16) & 0xFF] + 16;
  655. }
  656. return (val & 0xFF00) ?
  657. UpperBitTable[(val >> 8) & 0xFF] + 8:
  658. UpperBitTable[(val ) & 0xFF];
  659. #else
  660. if (val & 0xFFFFFFFF00000000)
  661. {
  662. if (val & 0xFFFF000000000000)
  663. {
  664. return (val & 0xFF00000000000000) ?
  665. UpperBitTable[(val >> 56) ] + 56:
  666. UpperBitTable[(val >> 48) & 0xFF] + 48;
  667. }
  668. return (val & 0xFF0000000000) ?
  669. UpperBitTable[(val >> 40) & 0xFF] + 40:
  670. UpperBitTable[(val >> 32) & 0xFF] + 32;
  671. }
  672. else
  673. {
  674. if (val & 0xFFFF0000)
  675. {
  676. return (val & 0xFF000000) ?
  677. UpperBitTable[(val >> 24) ] + 24:
  678. UpperBitTable[(val >> 16) & 0xFF] + 16;
  679. }
  680. return (val & 0xFF00) ?
  681. UpperBitTable[(val >> 8) & 0xFF] + 8:
  682. UpperBitTable[(val ) & 0xFF];
  683. }
  684. #endif
  685. }
  686. //-----------------------------------------------------------------------------------
  687. inline uint8_t LowerBit(size_t val)
  688. {
  689. #ifndef OVR_64BIT_POINTERS
  690. if (val & 0xFFFF)
  691. {
  692. return (val & 0xFF) ?
  693. LowerBitTable[ val & 0xFF]:
  694. LowerBitTable[(val >> 8) & 0xFF] + 8;
  695. }
  696. return (val & 0xFF0000) ?
  697. LowerBitTable[(val >> 16) & 0xFF] + 16:
  698. LowerBitTable[(val >> 24) & 0xFF] + 24;
  699. #else
  700. if (val & 0xFFFFFFFF)
  701. {
  702. if (val & 0xFFFF)
  703. {
  704. return (val & 0xFF) ?
  705. LowerBitTable[ val & 0xFF]:
  706. LowerBitTable[(val >> 8) & 0xFF] + 8;
  707. }
  708. return (val & 0xFF0000) ?
  709. LowerBitTable[(val >> 16) & 0xFF] + 16:
  710. LowerBitTable[(val >> 24) & 0xFF] + 24;
  711. }
  712. else
  713. {
  714. if (val & 0xFFFF00000000)
  715. {
  716. return (val & 0xFF00000000) ?
  717. LowerBitTable[(val >> 32) & 0xFF] + 32:
  718. LowerBitTable[(val >> 40) & 0xFF] + 40;
  719. }
  720. return (val & 0xFF000000000000) ?
  721. LowerBitTable[(val >> 48) & 0xFF] + 48:
  722. LowerBitTable[(val >> 56) & 0xFF] + 56;
  723. }
  724. #endif
  725. }
  726. // ******* Special (optimized) memory routines
  727. // Note: null (bad) pointer is not tested
  728. class MemUtil
  729. {
  730. public:
  731. // Memory compare
  732. static int Cmp (const void* p1, const void* p2, size_t byteCount) { return memcmp(p1, p2, byteCount); }
  733. static int Cmp16(const void* p1, const void* p2, size_t int16Count);
  734. static int Cmp32(const void* p1, const void* p2, size_t int32Count);
  735. static int Cmp64(const void* p1, const void* p2, size_t int64Count);
  736. };
  737. // ** Inline Implementation
  738. inline int MemUtil::Cmp16(const void* p1, const void* p2, size_t int16Count)
  739. {
  740. int16_t* pa = (int16_t*)p1;
  741. int16_t* pb = (int16_t*)p2;
  742. unsigned ic = 0;
  743. if (int16Count == 0)
  744. return 0;
  745. while (pa[ic] == pb[ic])
  746. if (++ic==int16Count)
  747. return 0;
  748. return pa[ic] > pb[ic] ? 1 : -1;
  749. }
  750. inline int MemUtil::Cmp32(const void* p1, const void* p2, size_t int32Count)
  751. {
  752. int32_t* pa = (int32_t*)p1;
  753. int32_t* pb = (int32_t*)p2;
  754. unsigned ic = 0;
  755. if (int32Count == 0)
  756. return 0;
  757. while (pa[ic] == pb[ic])
  758. if (++ic==int32Count)
  759. return 0;
  760. return pa[ic] > pb[ic] ? 1 : -1;
  761. }
  762. inline int MemUtil::Cmp64(const void* p1, const void* p2, size_t int64Count)
  763. {
  764. int64_t* pa = (int64_t*)p1;
  765. int64_t* pb = (int64_t*)p2;
  766. unsigned ic = 0;
  767. if (int64Count == 0)
  768. return 0;
  769. while (pa[ic] == pb[ic])
  770. if (++ic==int64Count)
  771. return 0;
  772. return pa[ic] > pb[ic] ? 1 : -1;
  773. }
  774. // ** End Inline Implementation
  775. //-----------------------------------------------------------------------------------
  776. // ******* Byte Order Conversions
  777. namespace ByteUtil {
  778. // *** Swap Byte Order
  779. // Swap the byte order of a byte array
  780. inline void SwapOrder(void* pv, int size)
  781. {
  782. uint8_t* pb = (uint8_t*)pv;
  783. uint8_t temp;
  784. for (int i = 0; i < size>>1; i++)
  785. {
  786. temp = pb[size-1-i];
  787. pb[size-1-i] = pb[i];
  788. pb[i] = temp;
  789. }
  790. }
  791. // Swap the byte order of primitive types
  792. inline uint8_t SwapOrder(uint8_t v) { return v; }
  793. inline int8_t SwapOrder(int8_t v) { return v; }
  794. inline uint16_t SwapOrder(uint16_t v) { return uint16_t(v>>8)|uint16_t(v<<8); }
  795. inline int16_t SwapOrder(int16_t v) { return int16_t((uint16_t(v)>>8)|(v<<8)); }
  796. inline uint32_t SwapOrder(uint32_t v) { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); }
  797. inline int32_t SwapOrder(int32_t p) { return (int32_t)SwapOrder(uint32_t(p)); }
  798. inline uint64_t SwapOrder(uint64_t v)
  799. {
  800. return (v>>56) |
  801. ((v&uint64_t(0x00FF000000000000ULL))>>40) |
  802. ((v&uint64_t(0x0000FF0000000000ULL))>>24) |
  803. ((v&uint64_t(0x000000FF00000000ULL))>>8) |
  804. ((v&uint64_t(0x00000000FF000000ULL))<<8) |
  805. ((v&uint64_t(0x0000000000FF0000ULL))<<24) |
  806. ((v&uint64_t(0x000000000000FF00ULL))<<40) |
  807. (v<<56);
  808. }
  809. inline int64_t SwapOrder(int64_t v) { return (int64_t)SwapOrder(uint64_t(v)); }
  810. inline float SwapOrder(float p)
  811. {
  812. union {
  813. float p;
  814. uint32_t v;
  815. } u;
  816. u.p = p;
  817. u.v = SwapOrder(u.v);
  818. return u.p;
  819. }
  820. inline double SwapOrder(double p)
  821. {
  822. union {
  823. double p;
  824. uint64_t v;
  825. } u;
  826. u.p = p;
  827. u.v = SwapOrder(u.v);
  828. return u.p;
  829. }
  830. // *** Byte-order conversion
  831. #if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN)
  832. // Little Endian to System (LE)
  833. inline uint8_t LEToSystem(uint8_t v) { return v; }
  834. inline int8_t LEToSystem(int8_t v) { return v; }
  835. inline uint16_t LEToSystem(uint16_t v) { return v; }
  836. inline int16_t LEToSystem(int16_t v) { return v; }
  837. inline uint32_t LEToSystem(uint32_t v) { return v; }
  838. inline int32_t LEToSystem(int32_t v) { return v; }
  839. inline uint64_t LEToSystem(uint64_t v) { return v; }
  840. inline int64_t LEToSystem(int64_t v) { return v; }
  841. inline float LEToSystem(float v) { return v; }
  842. inline double LEToSystem(double v) { return v; }
  843. // Big Endian to System (LE)
  844. inline uint8_t BEToSystem(uint8_t v) { return SwapOrder(v); }
  845. inline int8_t BEToSystem(int8_t v) { return SwapOrder(v); }
  846. inline uint16_t BEToSystem(uint16_t v) { return SwapOrder(v); }
  847. inline int16_t BEToSystem(int16_t v) { return SwapOrder(v); }
  848. inline uint32_t BEToSystem(uint32_t v) { return SwapOrder(v); }
  849. inline int32_t BEToSystem(int32_t v) { return SwapOrder(v); }
  850. inline uint64_t BEToSystem(uint64_t v) { return SwapOrder(v); }
  851. inline int64_t BEToSystem(int64_t v) { return SwapOrder(v); }
  852. inline float BEToSystem(float v) { return SwapOrder(v); }
  853. inline double BEToSystem(double v) { return SwapOrder(v); }
  854. // System (LE) to Little Endian
  855. inline uint8_t SystemToLE(uint8_t v) { return v; }
  856. inline int8_t SystemToLE(int8_t v) { return v; }
  857. inline uint16_t SystemToLE(uint16_t v) { return v; }
  858. inline int16_t SystemToLE(int16_t v) { return v; }
  859. inline uint32_t SystemToLE(uint32_t v) { return v; }
  860. inline int32_t SystemToLE(int32_t v) { return v; }
  861. inline uint64_t SystemToLE(uint64_t v) { return v; }
  862. inline int64_t SystemToLE(int64_t v) { return v; }
  863. inline float SystemToLE(float v) { return v; }
  864. inline double SystemToLE(double v) { return v; }
  865. // System (LE) to Big Endian
  866. inline uint8_t SystemToBE(uint8_t v) { return SwapOrder(v); }
  867. inline int8_t SystemToBE(int8_t v) { return SwapOrder(v); }
  868. inline uint16_t SystemToBE(uint16_t v) { return SwapOrder(v); }
  869. inline int16_t SystemToBE(int16_t v) { return SwapOrder(v); }
  870. inline uint32_t SystemToBE(uint32_t v) { return SwapOrder(v); }
  871. inline int32_t SystemToBE(int32_t v) { return SwapOrder(v); }
  872. inline uint64_t SystemToBE(uint64_t v) { return SwapOrder(v); }
  873. inline int64_t SystemToBE(int64_t v) { return SwapOrder(v); }
  874. inline float SystemToBE(float v) { return SwapOrder(v); }
  875. inline double SystemToBE(double v) { return SwapOrder(v); }
  876. #elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN)
  877. // Little Endian to System (BE)
  878. inline uint8_t LEToSystem(uint8_t v) { return SwapOrder(v); }
  879. inline int8_t LEToSystem(int8_t v) { return SwapOrder(v); }
  880. inline uint16_t LEToSystem(uint16_t v) { return SwapOrder(v); }
  881. inline int16_t LEToSystem(int16_t v) { return SwapOrder(v); }
  882. inline uint32_t LEToSystem(uint32_t v) { return SwapOrder(v); }
  883. inline int32_t LEToSystem(int32_t v) { return SwapOrder(v); }
  884. inline uint64_t LEToSystem(uint64_t v) { return SwapOrder(v); }
  885. inline int64_t LEToSystem(int64_t v) { return SwapOrder(v); }
  886. inline float LEToSystem(float v) { return SwapOrder(v); }
  887. inline double LEToSystem(double v) { return SwapOrder(v); }
  888. // Big Endian to System (BE)
  889. inline uint8_t BEToSystem(uint8_t v) { return v; }
  890. inline int8_t BEToSystem(int8_t v) { return v; }
  891. inline uint16_t BEToSystem(uint16_t v) { return v; }
  892. inline int16_t BEToSystem(int16_t v) { return v; }
  893. inline uint32_t BEToSystem(uint32_t v) { return v; }
  894. inline int32_t BEToSystem(int32_t v) { return v; }
  895. inline uint64_t BEToSystem(uint64_t v) { return v; }
  896. inline int64_t BEToSystem(int64_t v) { return v; }
  897. inline float BEToSystem(float v) { return v; }
  898. inline double BEToSystem(double v) { return v; }
  899. // System (BE) to Little Endian
  900. inline uint8_t SystemToLE(uint8_t v) { return SwapOrder(v); }
  901. inline int8_t SystemToLE(int8_t v) { return SwapOrder(v); }
  902. inline uint16_t SystemToLE(uint16_t v) { return SwapOrder(v); }
  903. inline int16_t SystemToLE(int16_t v) { return SwapOrder(v); }
  904. inline uint32_t SystemToLE(uint32_t v) { return SwapOrder(v); }
  905. inline int32_t SystemToLE(int32_t v) { return SwapOrder(v); }
  906. inline uint64_t SystemToLE(uint64_t v) { return SwapOrder(v); }
  907. inline int64_t SystemToLE(int64_t v) { return SwapOrder(v); }
  908. inline float SystemToLE(float v) { return SwapOrder(v); }
  909. inline double SystemToLE(double v) { return SwapOrder(v); }
  910. // System (BE) to Big Endian
  911. inline uint8_t SystemToBE(uint8_t v) { return v; }
  912. inline int8_t SystemToBE(int8_t v) { return v; }
  913. inline uint16_t SystemToBE(uint16_t v) { return v; }
  914. inline int16_t SystemToBE(int16_t v) { return v; }
  915. inline uint32_t SystemToBE(uint32_t v) { return v; }
  916. inline int32_t SystemToBE(int32_t v) { return v; }
  917. inline uint64_t SystemToBE(uint64_t v) { return v; }
  918. inline int64_t SystemToBE(int64_t v) { return v; }
  919. inline float SystemToBE(float v) { return v; }
  920. inline double SystemToBE(double v) { return v; }
  921. #else
  922. #error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN"
  923. #endif
  924. } // namespace ByteUtil
  925. // Used primarily for hardware interfacing such as sensor reports, firmware, etc.
  926. // Reported data is all little-endian.
  927. inline uint16_t DecodeUInt16(const uint8_t* buffer)
  928. {
  929. return ByteUtil::LEToSystem ( *(const uint16_t*)buffer );
  930. }
  931. inline int16_t DecodeSInt16(const uint8_t* buffer)
  932. {
  933. return ByteUtil::LEToSystem ( *(const int16_t*)buffer );
  934. }
  935. inline uint32_t DecodeUInt32(const uint8_t* buffer)
  936. {
  937. return ByteUtil::LEToSystem ( *(const uint32_t*)buffer );
  938. }
  939. inline int32_t DecodeSInt32(const uint8_t* buffer)
  940. {
  941. return ByteUtil::LEToSystem ( *(const int32_t*)buffer );
  942. }
  943. inline float DecodeFloat(const uint8_t* buffer)
  944. {
  945. union {
  946. uint32_t U;
  947. float F;
  948. };
  949. U = DecodeUInt32(buffer);
  950. return F;
  951. }
  952. inline void EncodeUInt16(uint8_t* buffer, uint16_t val)
  953. {
  954. *(uint16_t*)buffer = ByteUtil::SystemToLE ( val );
  955. }
  956. inline void EncodeSInt16(uint8_t* buffer, int16_t val)
  957. {
  958. *(int16_t*)buffer = ByteUtil::SystemToLE ( val );
  959. }
  960. inline void EncodeUInt32(uint8_t* buffer, uint32_t val)
  961. {
  962. *(uint32_t*)buffer = ByteUtil::SystemToLE ( val );
  963. }
  964. inline void EncodeSInt32(uint8_t* buffer, int32_t val)
  965. {
  966. *(int32_t*)buffer = ByteUtil::SystemToLE ( val );
  967. }
  968. inline void EncodeFloat(uint8_t* buffer, float val)
  969. {
  970. union {
  971. uint32_t U;
  972. float F;
  973. };
  974. F = val;
  975. EncodeUInt32(buffer, U);
  976. }
  977. // Converts an 8-bit binary-coded decimal
  978. inline int8_t DecodeBCD(uint8_t byte)
  979. {
  980. uint8_t digit1 = (byte >> 4) & 0x0f;
  981. uint8_t digit2 = byte & 0x0f;
  982. int decimal = digit1 * 10 + digit2; // maximum value = 99
  983. return (int8_t)decimal;
  984. }
  985. // Updates the previousCount uint_64t with the new value from the bitCount wrap-around counter newCount32
  986. // Returns the delta as uint32_t
  987. // 0 < bitCount <= 32
  988. template<const unsigned bitCount>
  989. uint32_t inline UpdateWraparoundCounter(uint64_t* previousCount, uint32_t newCount32)
  990. {
  991. OVR_ASSERT(bitCount <= 32);
  992. const uint64_t mask = ((uint64_t)1u << bitCount) - 1;
  993. OVR_ASSERT((newCount32 & ~mask) == 0);
  994. // Do int64_t subtraction to avoid invoking what is technically undefined behavior
  995. int64_t delta = ((int64_t)newCount32 - (int64_t)(*previousCount & mask));
  996. if (delta < 0)
  997. delta += ((uint64_t)1u << bitCount);
  998. *previousCount += delta;
  999. // We know that delta >=0 and < (1u << bitCount), and thus fits in a uint32_t
  1000. return (uint32_t)delta;
  1001. }
  1002. // Returns true if T is a signed built in type and (x + y) would overflow or underflow the storage maximum or minimum of type T.
  1003. template <typename T>
  1004. inline bool SignedAdditionWouldOverflow(T x, T y)
  1005. {
  1006. const T temp = (T)(x + y);
  1007. return ((~(x ^ y)) & (x ^ temp)) < 0;
  1008. }
  1009. // Returns true if T is a signed type and (x - y) would overflow or underflow the storage maximum or minimum of type T.
  1010. template <typename T>
  1011. inline bool SignedSubtractionWouldOverflow(T x, T y)
  1012. {
  1013. y = -y;
  1014. const T temp = (T)(x + y);
  1015. return ((temp ^ x) & (temp ^ y)) < 0;
  1016. }
  1017. // Returns true if T is an unsigned type and (x + y) would overflow the storage maximum of type T.
  1018. template <typename T>
  1019. inline bool UnsignedAdditionWouldOverflow(T x, T y)
  1020. {
  1021. return (T)(x + y) < x;
  1022. }
  1023. // Returns true if T is an unsigned type and (x - y) would underflow the storage minimum of type T.
  1024. template <typename T>
  1025. inline bool UnsignedSubtractionWouldOverflow(T x, T y)
  1026. {
  1027. return y > x;
  1028. }
  1029. // Returns true if T is an unsigned type and (x * y) would overflow the storage maximum of type T.
  1030. template <typename T>
  1031. inline bool UnsignedMultiplyWouldOverflow(T x, T y)
  1032. {
  1033. if(y)
  1034. return (((T)(x * y) / y) != x);
  1035. return false;
  1036. }
  1037. // Returns true if (x * y) would overflow or underflow the storage maximum or minimum of type int32_t.
  1038. inline bool SignedMultiplyWouldOverflow(int32_t x, int32_t y)
  1039. {
  1040. if((y < 0) && (x == (int32_t)INT32_C(0x80000000)))
  1041. return true;
  1042. if(y)
  1043. return (((x * y) / y) != x);
  1044. return false;
  1045. }
  1046. // Returns true if (x * y) would overflow or underflow the storage maximum or minimum of type int64_t.
  1047. inline bool SignedMultiplyWouldOverflow(int64_t x, int64_t y)
  1048. {
  1049. if((y < 0) && (x == (int64_t)INT64_C(0x8000000000000000)))
  1050. return true;
  1051. if(y)
  1052. return (((x * y) / y) != x);
  1053. return false;
  1054. }
  1055. // Returns true if (x / y) would overflow the maximum of type T.
  1056. template <typename T>
  1057. inline bool UnsignedDivisionWouldOverflow(T /*x*/, T y)
  1058. {
  1059. return y == 0;
  1060. }
  1061. // Returns true if (x / y) would overflow or underflow the maximum or mimumum of type T.
  1062. template <typename T>
  1063. inline bool SignedDivisionWouldOverflow(T x, T y)
  1064. {
  1065. return (y == 0) || ((x == (T)((T)1 << ((sizeof(T) * 8) - 1))) && (y == -1));
  1066. }
  1067. }} // OVR::Alg
  1068. #endif