PageRenderTime 71ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

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

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