PageRenderTime 57ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

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

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