PageRenderTime 78ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/numpy/core/src/npysort/npysort_common.h

https://github.com/WeatherGod/numpy
C Header | 351 lines | 262 code | 72 blank | 17 comment | 99 complexity | 8ac6b9840ffceb778254ea95bfbf5341 MD5 | raw file
  1. #ifndef __NPY_SORT_COMMON_H__
  2. #define __NPY_SORT_COMMON_H__
  3. #include <stdlib.h>
  4. #include <numpy/ndarraytypes.h>
  5. /*
  6. *****************************************************************************
  7. ** SWAP MACROS **
  8. *****************************************************************************
  9. */
  10. #define BOOL_SWAP(a,b) {npy_bool tmp = (b); (b)=(a); (a) = tmp;}
  11. #define BYTE_SWAP(a,b) {npy_byte tmp = (b); (b)=(a); (a) = tmp;}
  12. #define UBYTE_SWAP(a,b) {npy_ubyte tmp = (b); (b)=(a); (a) = tmp;}
  13. #define SHORT_SWAP(a,b) {npy_short tmp = (b); (b)=(a); (a) = tmp;}
  14. #define USHORT_SWAP(a,b) {npy_ushort tmp = (b); (b)=(a); (a) = tmp;}
  15. #define INT_SWAP(a,b) {npy_int tmp = (b); (b)=(a); (a) = tmp;}
  16. #define UINT_SWAP(a,b) {npy_uint tmp = (b); (b)=(a); (a) = tmp;}
  17. #define LONG_SWAP(a,b) {npy_long tmp = (b); (b)=(a); (a) = tmp;}
  18. #define ULONG_SWAP(a,b) {npy_ulong tmp = (b); (b)=(a); (a) = tmp;}
  19. #define LONGLONG_SWAP(a,b) {npy_longlong tmp = (b); (b)=(a); (a) = tmp;}
  20. #define ULONGLONG_SWAP(a,b) {npy_ulonglong tmp = (b); (b)=(a); (a) = tmp;}
  21. #define HALF_SWAP(a,b) {npy_half tmp = (b); (b)=(a); (a) = tmp;}
  22. #define FLOAT_SWAP(a,b) {npy_float tmp = (b); (b)=(a); (a) = tmp;}
  23. #define DOUBLE_SWAP(a,b) {npy_double tmp = (b); (b)=(a); (a) = tmp;}
  24. #define LONGDOUBLE_SWAP(a,b) {npy_longdouble tmp = (b); (b)=(a); (a) = tmp;}
  25. #define CFLOAT_SWAP(a,b) {npy_cfloat tmp = (b); (b)=(a); (a) = tmp;}
  26. #define CDOUBLE_SWAP(a,b) {npy_cdouble tmp = (b); (b)=(a); (a) = tmp;}
  27. #define CLONGDOUBLE_SWAP(a,b) {npy_clongdouble tmp = (b); (b)=(a); (a) = tmp;}
  28. /* Need this for the argsort functions */
  29. #define INTP_SWAP(a,b) {npy_intp tmp = (b); (b)=(a); (a) = tmp;}
  30. /*
  31. *****************************************************************************
  32. ** COMPARISON FUNCTIONS **
  33. *****************************************************************************
  34. */
  35. NPY_INLINE static int
  36. BOOL_LT(npy_bool a, npy_bool b)
  37. {
  38. return a < b;
  39. }
  40. NPY_INLINE static int
  41. BYTE_LT(npy_byte a, npy_byte b)
  42. {
  43. return a < b;
  44. }
  45. NPY_INLINE static int
  46. UBYTE_LT(npy_ubyte a, npy_ubyte b)
  47. {
  48. return a < b;
  49. }
  50. NPY_INLINE static int
  51. SHORT_LT(npy_short a, npy_short b)
  52. {
  53. return a < b;
  54. }
  55. NPY_INLINE static int
  56. USHORT_LT(npy_ushort a, npy_ushort b)
  57. {
  58. return a < b;
  59. }
  60. NPY_INLINE static int
  61. INT_LT(npy_int a, npy_int b)
  62. {
  63. return a < b;
  64. }
  65. NPY_INLINE static int
  66. UINT_LT(npy_uint a, npy_uint b)
  67. {
  68. return a < b;
  69. }
  70. NPY_INLINE static int
  71. LONG_LT(npy_long a, npy_long b)
  72. {
  73. return a < b;
  74. }
  75. NPY_INLINE static int
  76. ULONG_LT(npy_ulong a, npy_ulong b)
  77. {
  78. return a < b;
  79. }
  80. NPY_INLINE static int
  81. LONGLONG_LT(npy_longlong a, npy_longlong b)
  82. {
  83. return a < b;
  84. }
  85. NPY_INLINE static int
  86. ULONGLONG_LT(npy_ulonglong a, npy_ulonglong b)
  87. {
  88. return a < b;
  89. }
  90. NPY_INLINE static int
  91. FLOAT_LT(npy_float a, npy_float b)
  92. {
  93. return a < b || (b != b && a == a);
  94. }
  95. NPY_INLINE static int
  96. DOUBLE_LT(npy_double a, npy_double b)
  97. {
  98. return a < b || (b != b && a == a);
  99. }
  100. NPY_INLINE static int
  101. LONGDOUBLE_LT(npy_longdouble a, npy_longdouble b)
  102. {
  103. return a < b || (b != b && a == a);
  104. }
  105. NPY_INLINE static int
  106. npy_half_isnan(npy_half h)
  107. {
  108. return ((h&0x7c00u) == 0x7c00u) && ((h&0x03ffu) != 0x0000u);
  109. }
  110. NPY_INLINE static int
  111. npy_half_lt_nonan(npy_half h1, npy_half h2)
  112. {
  113. if (h1&0x8000u) {
  114. if (h2&0x8000u) {
  115. return (h1&0x7fffu) > (h2&0x7fffu);
  116. }
  117. else {
  118. /* Signed zeros are equal, have to check for it */
  119. return (h1 != 0x8000u) || (h2 != 0x0000u);
  120. }
  121. }
  122. else {
  123. if (h2&0x8000u) {
  124. return 0;
  125. }
  126. else {
  127. return (h1&0x7fffu) < (h2&0x7fffu);
  128. }
  129. }
  130. }
  131. NPY_INLINE static int
  132. HALF_LT(npy_half a, npy_half b)
  133. {
  134. int ret;
  135. if (npy_half_isnan(b)) {
  136. ret = !npy_half_isnan(a);
  137. }
  138. else {
  139. ret = !npy_half_isnan(a) && npy_half_lt_nonan(a, b);
  140. }
  141. return ret;
  142. }
  143. /*
  144. * For inline functions SUN recommends not using a return in the then part
  145. * of an if statement. It's a SUN compiler thing, so assign the return value
  146. * to a variable instead.
  147. */
  148. NPY_INLINE static int
  149. CFLOAT_LT(npy_cfloat a, npy_cfloat b)
  150. {
  151. int ret;
  152. if (a.real < b.real) {
  153. ret = a.imag == a.imag || b.imag != b.imag;
  154. }
  155. else if (a.real > b.real) {
  156. ret = b.imag != b.imag && a.imag == a.imag;
  157. }
  158. else if (a.real == b.real || (a.real != a.real && b.real != b.real)) {
  159. ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag);
  160. }
  161. else {
  162. ret = b.real != b.real;
  163. }
  164. return ret;
  165. }
  166. NPY_INLINE static int
  167. CDOUBLE_LT(npy_cdouble a, npy_cdouble b)
  168. {
  169. int ret;
  170. if (a.real < b.real) {
  171. ret = a.imag == a.imag || b.imag != b.imag;
  172. }
  173. else if (a.real > b.real) {
  174. ret = b.imag != b.imag && a.imag == a.imag;
  175. }
  176. else if (a.real == b.real || (a.real != a.real && b.real != b.real)) {
  177. ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag);
  178. }
  179. else {
  180. ret = b.real != b.real;
  181. }
  182. return ret;
  183. }
  184. NPY_INLINE static int
  185. CLONGDOUBLE_LT(npy_clongdouble a, npy_clongdouble b)
  186. {
  187. int ret;
  188. if (a.real < b.real) {
  189. ret = a.imag == a.imag || b.imag != b.imag;
  190. }
  191. else if (a.real > b.real) {
  192. ret = b.imag != b.imag && a.imag == a.imag;
  193. }
  194. else if (a.real == b.real || (a.real != a.real && b.real != b.real)) {
  195. ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag);
  196. }
  197. else {
  198. ret = b.real != b.real;
  199. }
  200. return ret;
  201. }
  202. NPY_INLINE static void
  203. STRING_COPY(char *s1, char *s2, size_t len)
  204. {
  205. memcpy(s1, s2, len);
  206. }
  207. NPY_INLINE static void
  208. STRING_SWAP(char *s1, char *s2, size_t len)
  209. {
  210. while(len--) {
  211. const char t = *s1;
  212. *s1++ = *s2;
  213. *s2++ = t;
  214. }
  215. }
  216. NPY_INLINE static int
  217. STRING_LT(char *s1, char *s2, size_t len)
  218. {
  219. const unsigned char *c1 = (unsigned char *)s1;
  220. const unsigned char *c2 = (unsigned char *)s2;
  221. size_t i;
  222. int ret = 0;
  223. for (i = 0; i < len; ++i) {
  224. if (c1[i] != c2[i]) {
  225. ret = c1[i] < c2[i];
  226. break;
  227. }
  228. }
  229. return ret;
  230. }
  231. NPY_INLINE static void
  232. UNICODE_COPY(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
  233. {
  234. while(len--) {
  235. *s1++ = *s2++;
  236. }
  237. }
  238. NPY_INLINE static void
  239. UNICODE_SWAP(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
  240. {
  241. while(len--) {
  242. const npy_ucs4 t = *s1;
  243. *s1++ = *s2;
  244. *s2++ = t;
  245. }
  246. }
  247. NPY_INLINE static int
  248. UNICODE_LT(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
  249. {
  250. size_t i;
  251. int ret = 0;
  252. for (i = 0; i < len; ++i) {
  253. if (s1[i] != s2[i]) {
  254. ret = s1[i] < s2[i];
  255. break;
  256. }
  257. }
  258. return ret;
  259. }
  260. NPY_INLINE static void
  261. GENERIC_COPY(char *a, char *b, size_t len)
  262. {
  263. memcpy(a, b, len);
  264. }
  265. NPY_INLINE static void
  266. GENERIC_SWAP(char *a, char *b, size_t len)
  267. {
  268. while(len--) {
  269. const char t = *a;
  270. *a++ = *b;
  271. *b++ = t;
  272. }
  273. }
  274. NPY_INLINE static int
  275. GENERIC_LT(char *a, char *b, int (*cmp)(const void *, const void *))
  276. {
  277. return cmp(a, b) < 0;
  278. }
  279. #endif