188 lines
4.0 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #include <lol/engine-internal.h>
  11. namespace lol
  12. {
  13. /*
  14. * hash implementations
  15. */
  16. static class HashData
  17. {
  18. public:
  19. HashData()
  20. {
  21. /* Initialise CRC32 table */
  22. for (int i = 0; i < 256; i++)
  23. {
  24. uint32_t tmp = i;
  25. for (int j = 8; j--; )
  26. tmp = (tmp >> 1) ^ ((tmp & 1) ? 0xedb88320 : 0);
  27. crc32_table[i] = tmp;
  28. }
  29. }
  30. uint32_t crc32_table[256];
  31. }
  32. const data;
  33. /*
  34. * Helper hash functions
  35. */
  36. static inline uint32_t Hash8(uint8_t x)
  37. {
  38. uint32_t ret = 0xffffffffu;
  39. ret = data.crc32_table[(uint8_t)(ret ^ x)] ^ (ret >> 8);
  40. return ret ^ 0xffffffffu;
  41. }
  42. static inline uint32_t Hash16(uint16_t x)
  43. {
  44. uint32_t ret = 0xffffffffu;
  45. ret = data.crc32_table[(uint8_t)(ret ^ x)] ^ (ret >> 8);
  46. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 8))] ^ (ret >> 8);
  47. return ret ^ 0xffffffffu;
  48. }
  49. static inline uint32_t Hash32(uint32_t x)
  50. {
  51. uint32_t ret = 0xffffffffu;
  52. ret = data.crc32_table[(uint8_t)(ret ^ x)] ^ (ret >> 8);
  53. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 8))] ^ (ret >> 8);
  54. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 16))] ^ (ret >> 8);
  55. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 24))] ^ (ret >> 8);
  56. return ret ^ 0xffffffffu;
  57. }
  58. static inline uint32_t Hash64(uint64_t x)
  59. {
  60. uint32_t ret = 0xffffffffu;
  61. ret = data.crc32_table[(uint8_t)(ret ^ x)] ^ (ret >> 8);
  62. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 8))] ^ (ret >> 8);
  63. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 16))] ^ (ret >> 8);
  64. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 24))] ^ (ret >> 8);
  65. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 32))] ^ (ret >> 8);
  66. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 40))] ^ (ret >> 8);
  67. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 48))] ^ (ret >> 8);
  68. ret = data.crc32_table[(uint8_t)(ret ^ (x >> 56))] ^ (ret >> 8);
  69. return ret ^ 0xffffffffu;
  70. }
  71. /*
  72. * Integer hash functions
  73. */
  74. uint32_t hash<int8_t>::operator ()(int8_t x) const
  75. {
  76. return Hash8((uint8_t)x);
  77. }
  78. uint32_t hash<uint8_t>::operator ()(uint8_t x) const
  79. {
  80. return Hash8(x);
  81. }
  82. uint32_t hash<int16_t>::operator ()(int16_t x) const
  83. {
  84. return Hash16((uint16_t)x);
  85. }
  86. uint32_t hash<uint16_t>::operator ()(uint16_t x) const
  87. {
  88. return Hash16(x);
  89. }
  90. uint32_t hash<int32_t>::operator ()(int32_t x) const
  91. {
  92. return Hash32((uint32_t)x);
  93. }
  94. uint32_t hash<uint32_t>::operator ()(uint32_t x) const
  95. {
  96. return Hash32(x);
  97. }
  98. uint32_t hash<int64_t>::operator ()(int64_t x) const
  99. {
  100. return Hash64((uint64_t)x);
  101. }
  102. uint32_t hash<uint64_t>::operator ()(uint64_t x) const
  103. {
  104. return Hash64(x);
  105. }
  106. /*
  107. * Floating-point hash functions
  108. */
  109. uint32_t hash<half>::operator ()(half f) const
  110. {
  111. return Hash16(f.bits);
  112. }
  113. uint32_t hash<float>::operator ()(float f) const
  114. {
  115. union { float tmp; uint32_t x; } u = { f };
  116. return Hash32(u.x);
  117. }
  118. uint32_t hash<double>::operator ()(double f) const
  119. {
  120. union { double tmp; uint64_t x; } u = { f };
  121. return Hash64(u.x);
  122. }
  123. /*
  124. * String and array hash functions
  125. */
  126. static uint32_t HashCharString(char const *s)
  127. {
  128. uint32_t ret = 0xffffffffu, ch;
  129. while ((ch = (uint8_t)*s++))
  130. ret = data.crc32_table[(uint8_t)(ret ^ ch)] ^ (ret >> 8);
  131. return ret ^ 0xffffffffu;
  132. }
  133. uint32_t hash<char const *>::operator ()(char const *s) const
  134. {
  135. return HashCharString(s);
  136. }
  137. uint32_t hash<std::string>::operator ()(std::string const &s) const
  138. {
  139. return HashCharString(&s[0]);
  140. }
  141. uint32_t hash<char const *>::operator ()(String const &s) const
  142. {
  143. return HashCharString(&s[0]);
  144. }
  145. uint32_t hash<String>::operator ()(String const &s) const
  146. {
  147. return HashCharString(&s[0]);
  148. }
  149. uint32_t hash<String>::operator ()(char const *s) const
  150. {
  151. return HashCharString(s);
  152. }
  153. } /* namespace lol */