Functions.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. /// @file
  6. /// Contains misc functions
  7. #pragma once
  8. #include <anki/util/StdTypes.h>
  9. #include <anki/util/Assert.h>
  10. #include <cmath>
  11. #include <utility>
  12. #include <new>
  13. namespace anki
  14. {
  15. /// @addtogroup util_other
  16. /// @{
  17. /// Pick a random number from min to max
  18. extern I32 randRange(I32 min, I32 max);
  19. /// Pick a random number from min to max
  20. extern U32 randRange(U32 min, U32 max);
  21. /// Pick a random number from min to max
  22. extern F32 randRange(F32 min, F32 max);
  23. /// Pick a random number from min to max
  24. extern F64 randRange(F64 min, F64 max);
  25. extern F32 randFloat(F32 max);
  26. /// Get min of two values.
  27. template<typename T>
  28. inline T min(T a, T b)
  29. {
  30. return (a < b) ? a : b;
  31. }
  32. /// Get max of two values.
  33. template<typename T>
  34. inline T max(T a, T b)
  35. {
  36. return (a > b) ? a : b;
  37. }
  38. template<typename T>
  39. inline T clamp(T v, T minv, T maxv)
  40. {
  41. ANKI_ASSERT(minv < maxv);
  42. return min<T>(max<T>(minv, v), maxv);
  43. }
  44. /// Check if a number os a power of 2
  45. template<typename Int>
  46. inline Bool isPowerOfTwo(Int x)
  47. {
  48. return !(x == 0) && !(x & (x - 1));
  49. }
  50. /// Get the next power of two number. For example if x is 130 this will return
  51. /// 256
  52. template<typename Int>
  53. inline Int nextPowerOfTwo(Int x)
  54. {
  55. return pow(2, ceil(log(x) / log(2)));
  56. }
  57. /// Get align number
  58. /// @param alignment The bytes of alignment
  59. /// @param value The value to align
  60. template<typename Type>
  61. inline Type getAlignedRoundUp(PtrSize alignment, Type value)
  62. {
  63. ANKI_ASSERT(isPowerOfTwo(alignment));
  64. PtrSize v = (PtrSize)value;
  65. v = (v + alignment - 1) & ~(alignment - 1);
  66. return (Type)v;
  67. }
  68. /// Align number
  69. /// @param alignment The bytes of alignment
  70. /// @param value The value to align
  71. template<typename Type>
  72. inline void alignRoundUp(PtrSize alignment, Type& value)
  73. {
  74. value = getAlignedRoundUp(alignment, value);
  75. }
  76. /// Get align number
  77. /// @param alignment The bytes of alignment
  78. /// @param value The value to align
  79. template<typename Type>
  80. inline Type getAlignedRoundDown(PtrSize alignment, Type value)
  81. {
  82. ANKI_ASSERT(isPowerOfTwo(alignment));
  83. PtrSize v = (PtrSize)value;
  84. v &= ~(alignment - 1);
  85. return (Type)v;
  86. }
  87. /// Align number
  88. /// @param alignment The bytes of alignment
  89. /// @param value The value to align
  90. template<typename Type>
  91. inline void alignRoundDown(PtrSize alignment, Type& value)
  92. {
  93. value = getAlignedRoundDown(alignment, value);
  94. }
  95. /// Check if a number is aligned
  96. template<typename Type>
  97. inline Bool isAligned(PtrSize alignment, Type value)
  98. {
  99. return ((PtrSize)value % alignment) == 0;
  100. }
  101. template<typename T>
  102. inline void swapValues(T& a, T& b)
  103. {
  104. T tmp = b;
  105. b = a;
  106. a = tmp;
  107. }
  108. /// Convert any pointer to a number.
  109. template<typename TPtr>
  110. inline PtrSize ptrToNumber(TPtr ptr)
  111. {
  112. ANKI_ASSERT(ptr);
  113. uintptr_t i = reinterpret_cast<uintptr_t>(ptr);
  114. PtrSize size = i;
  115. return size;
  116. }
  117. /// Convert a number to a pointer.
  118. template<typename TPtr>
  119. inline TPtr numberToPtr(PtrSize num)
  120. {
  121. ANKI_ASSERT(num);
  122. uintptr_t i = static_cast<uintptr_t>(num);
  123. TPtr ptr = reinterpret_cast<TPtr>(i);
  124. return ptr;
  125. }
  126. /// A simple template trick to remove the pointer from one type
  127. ///
  128. /// Example:
  129. /// @code
  130. /// double a = 1234.456;
  131. /// RemovePointer<decltype(&a)>::Type b = a;
  132. /// @endcode
  133. /// The b is of type double
  134. template<typename T>
  135. struct RemovePointer;
  136. template<typename T>
  137. struct RemovePointer<T*>
  138. {
  139. typedef T Type;
  140. };
  141. /// Perform a static cast of a pointer
  142. template<typename To, typename From>
  143. To staticCastPtr(From from)
  144. {
  145. #if ANKI_DEBUG == 1
  146. To ptr = dynamic_cast<To>(from);
  147. ANKI_ASSERT(ptr != nullptr);
  148. return ptr;
  149. #else
  150. return static_cast<To>(from);
  151. #endif
  152. }
  153. /// Count bits
  154. inline U32 countBits(U32 number)
  155. {
  156. #if defined(__GNUC__)
  157. return __builtin_popcount(number);
  158. #else
  159. #error "Unimplemented"
  160. #endif
  161. }
  162. /// Check if types are the same.
  163. template<class T, class Y>
  164. struct TypesAreTheSame
  165. {
  166. enum
  167. {
  168. m_value = 0
  169. };
  170. };
  171. template<class T>
  172. struct TypesAreTheSame<T, T>
  173. {
  174. enum
  175. {
  176. m_value = 1
  177. };
  178. };
  179. /// @}
  180. } // end namespace anki