IceUtils.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /**
  3. * Contains misc. useful macros & defines.
  4. * \file IceUtils.h
  5. * \author Pierre Terdiman (collected from various sources)
  6. * \date April, 4, 2000
  7. */
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. // Include Guard
  11. #ifndef __ICEUTILS_H__
  12. #define __ICEUTILS_H__
  13. #define START_RUNONCE { static bool __RunOnce__ = false; if(!__RunOnce__){
  14. #define END_RUNONCE __RunOnce__ = true;}}
  15. //! Reverse all the bits in a 32 bit word (from Steve Baker's Cute Code Collection)
  16. //! (each line can be done in any order.
  17. inline_ void ReverseBits(udword& n)
  18. {
  19. n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
  20. n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
  21. n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
  22. n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
  23. n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
  24. // Etc for larger intergers (64 bits in Java)
  25. // NOTE: the >> operation must be unsigned! (>>> in java)
  26. }
  27. //! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection)
  28. inline_ udword CountBits(udword n)
  29. {
  30. // This relies of the fact that the count of n bits can NOT overflow
  31. // an n bit interger. EG: 1 bit count takes a 1 bit interger, 2 bit counts
  32. // 2 bit interger, 3 bit count requires only a 2 bit interger.
  33. // So we add all bit pairs, then each nible, then each byte etc...
  34. n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1);
  35. n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2);
  36. n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4);
  37. n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8);
  38. n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16);
  39. // Etc for larger intergers (64 bits in Java)
  40. // NOTE: the >> operation must be unsigned! (>>> in java)
  41. return n;
  42. }
  43. //! Even faster?
  44. inline_ udword CountBits2(udword bits)
  45. {
  46. bits = bits - ((bits >> 1) & 0x55555555);
  47. bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333);
  48. bits = ((bits >> 4) + bits) & 0x0F0F0F0F;
  49. return (bits * 0x01010101) >> 24;
  50. }
  51. //! Spread out bits. EG 00001111 -> 0101010101
  52. //! 00001010 -> 0100010000
  53. //! This is used to interleve to intergers to produce a `Morten Key'
  54. //! used in Space Filling Curves (See DrDobbs Journal, July 1999)
  55. //! Order is important.
  56. inline_ void SpreadBits(udword& n)
  57. {
  58. n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16);
  59. n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8);
  60. n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4);
  61. n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2);
  62. n = ( n & 0x11111111) | (( n & 0x22222222) << 1);
  63. }
  64. // Next Largest Power of 2
  65. // Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
  66. // that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
  67. // the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
  68. // largest power of 2. For a 32-bit value:
  69. inline_ udword nlpo2(udword x)
  70. {
  71. x |= (x >> 1);
  72. x |= (x >> 2);
  73. x |= (x >> 4);
  74. x |= (x >> 8);
  75. x |= (x >> 16);
  76. return x+1;
  77. }
  78. //! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection)
  79. inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); }
  80. //! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection)
  81. inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); }
  82. //! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection)
  83. inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<<n); }
  84. //! Classic XOR swap (from Steve Baker's Cute Code Collection)
  85. //! x ^= y; /* x' = (x^y) */
  86. //! y ^= x; /* y' = (y^(x^y)) = x */
  87. //! x ^= y; /* x' = (x^y)^x = y */
  88. inline_ void xorSwap(udword& x, udword& y) { x ^= y; y ^= x; x ^= y; }
  89. inline_ void Swap(udword& x, udword& y) { udword temp = x; x = y; y = temp; }
  90. //! Little/Big endian (from Steve Baker's Cute Code Collection)
  91. //!
  92. //! Extra comments by Kenny Hoff:
  93. //! Determines the byte-ordering of the current machine (little or big endian)
  94. //! by setting an integer value to 1 (so least significant bit is now 1); take
  95. //! the address of the int and cast to a byte pointer (treat integer as an
  96. //! array of four bytes); check the value of the first byte (must be 0 or 1).
  97. //! If the value is 1, then the first byte least significant byte and this
  98. //! implies LITTLE endian. If the value is 0, the first byte is the most
  99. //! significant byte, BIG endian. Examples:
  100. //! integer 1 on BIG endian: 00000000 00000000 00000000 00000001
  101. //! integer 1 on LITTLE endian: 00000001 00000000 00000000 00000000
  102. //!---------------------------------------------------------------------------
  103. //! int IsLittleEndian() { int x=1; return ( ((char*)(&x))[0] ); }
  104. inline_ char LittleEndian() { int i = 1; return *((char*)&i); }
  105. //!< Alternative abs function
  106. inline_ udword abs_(sdword x) { sdword y= x >> 31; return (x^y)-y; }
  107. //!< Alternative min function
  108. inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); }
  109. // Determine if one of the bytes in a 4 byte word is zero
  110. inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); }
  111. // To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0
  112. inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); }
  113. // inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); }
  114. // Most Significant 1 Bit
  115. // Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set)
  116. // can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits.
  117. // This process yields a bit vector with the same most significant 1 as x, but all 1's below it.
  118. // Bitwise AND of the original value with the complement of the "folded" value shifted down by one
  119. // yields the most significant bit. For a 32-bit value:
  120. inline_ udword msb32(udword x)
  121. {
  122. x |= (x >> 1);
  123. x |= (x >> 2);
  124. x |= (x >> 4);
  125. x |= (x >> 8);
  126. x |= (x >> 16);
  127. return (x & ~(x >> 1));
  128. }
  129. /*
  130. "Just call it repeatedly with various input values and always with the same variable as "memory".
  131. The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1
  132. does no filtering at all.
  133. I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed
  134. to the more typical FIR (Finite Impulse Response).
  135. Also, I'd say that you can make more intelligent and interesting filters than this, for example filters
  136. that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter
  137. to be applied before this one, of course."
  138. (JCAB on Flipcode)
  139. */
  140. inline_ float FeedbackFilter(float val, float& memory, float sharpness)
  141. {
  142. ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter");
  143. if(sharpness<0.0f) sharpness = 0.0f;
  144. else if(sharpness>1.0f) sharpness = 1.0f;
  145. return memory = val * sharpness + memory * (1.0f - sharpness);
  146. }
  147. //! If you can guarantee that your input domain (i.e. value of x) is slightly
  148. //! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the
  149. //! following code to clamp the resulting value into [-32768,+32767] range:
  150. inline_ int ClampToInt16(int x)
  151. {
  152. // ASSERT(abs(x) < (int)((1<<31u)-32767));
  153. int delta = 32767 - x;
  154. x += (delta>>31) & delta;
  155. delta = x + 32768;
  156. x -= (delta>>31) & delta;
  157. return x;
  158. }
  159. // Generic functions
  160. template<class Type> inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; }
  161. template<class Type> inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((x<lo) ? lo : (x>hi) ? hi : x); }
  162. template<class Type> inline_ void TSort(Type& a, Type& b)
  163. {
  164. if(a>b) TSwap(a, b);
  165. }
  166. template<class Type> inline_ void TSort(Type& a, Type& b, Type& c)
  167. {
  168. if(a>b) TSwap(a, b);
  169. if(b>c) TSwap(b, c);
  170. if(a>b) TSwap(a, b);
  171. if(b>c) TSwap(b, c);
  172. }
  173. // Prevent nasty user-manipulations (strategy borrowed from Charles Bloom)
  174. // #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); }
  175. // ... actually this is better !
  176. #define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object);
  177. //! TO BE DOCUMENTED
  178. #define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member)
  179. //! TO BE DOCUMENTED
  180. #define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0]))
  181. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  182. /**
  183. * Returns the alignment of the input address.
  184. * \fn Alignment()
  185. * \param address [in] address to check
  186. * \return the best alignment (e.g. 1 for odd addresses, etc)
  187. */
  188. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  189. FUNCTION ICECORE_API udword Alignment(udword address);
  190. #define IS_ALIGNED_2(x) ((x&1)==0)
  191. #define IS_ALIGNED_4(x) ((x&3)==0)
  192. #define IS_ALIGNED_8(x) ((x&7)==0)
  193. inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; }
  194. // Compute implicit coords from an index:
  195. // The idea is to get back 2D coords from a 1D index.
  196. // For example:
  197. //
  198. // 0 1 2 ... nbu-1
  199. // nbu nbu+1 i ...
  200. //
  201. // We have i, we're looking for the equivalent (u=2, v=1) location.
  202. // i = u + v*nbu
  203. // <=> i/nbu = u/nbu + v
  204. // Since 0 <= u < nbu, u/nbu = 0 (integer)
  205. // Hence: v = i/nbu
  206. // Then we simply put it back in the original equation to compute u = i - v*nbu
  207. inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu)
  208. {
  209. v = i / nbu;
  210. u = i - (v * nbu);
  211. }
  212. // In 3D: i = u + v*nbu + w*nbu*nbv
  213. // <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w
  214. // u/(nbu*nbv) is null since u/nbu was null already.
  215. // v/nbv is null as well for the same reason.
  216. // Hence w = i/(nbu*nbv)
  217. // Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu
  218. inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv)
  219. {
  220. w = i / (nbu_nbv);
  221. Compute2DCoords(u, v, i - (w * nbu_nbv), nbu);
  222. }
  223. #endif // __ICEUTILS_H__