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