numpy
2.0.0
|
00001 #ifndef __NPY_SORT_COMMON_H__ 00002 #define __NPY_SORT_COMMON_H__ 00003 00004 #include <stdlib.h> 00005 #include <numpy/ndarraytypes.h> 00006 00007 /* 00008 ***************************************************************************** 00009 ** SWAP MACROS ** 00010 ***************************************************************************** 00011 */ 00012 00013 #define BOOL_SWAP(a,b) {npy_bool tmp = (b); (b)=(a); (a) = tmp;} 00014 #define BYTE_SWAP(a,b) {npy_byte tmp = (b); (b)=(a); (a) = tmp;} 00015 #define UBYTE_SWAP(a,b) {npy_ubyte tmp = (b); (b)=(a); (a) = tmp;} 00016 #define SHORT_SWAP(a,b) {npy_short tmp = (b); (b)=(a); (a) = tmp;} 00017 #define USHORT_SWAP(a,b) {npy_ushort tmp = (b); (b)=(a); (a) = tmp;} 00018 #define INT_SWAP(a,b) {npy_int tmp = (b); (b)=(a); (a) = tmp;} 00019 #define UINT_SWAP(a,b) {npy_uint tmp = (b); (b)=(a); (a) = tmp;} 00020 #define LONG_SWAP(a,b) {npy_long tmp = (b); (b)=(a); (a) = tmp;} 00021 #define ULONG_SWAP(a,b) {npy_ulong tmp = (b); (b)=(a); (a) = tmp;} 00022 #define LONGLONG_SWAP(a,b) {npy_longlong tmp = (b); (b)=(a); (a) = tmp;} 00023 #define ULONGLONG_SWAP(a,b) {npy_ulonglong tmp = (b); (b)=(a); (a) = tmp;} 00024 #define HALF_SWAP(a,b) {npy_half tmp = (b); (b)=(a); (a) = tmp;} 00025 #define FLOAT_SWAP(a,b) {npy_float tmp = (b); (b)=(a); (a) = tmp;} 00026 #define DOUBLE_SWAP(a,b) {npy_double tmp = (b); (b)=(a); (a) = tmp;} 00027 #define LONGDOUBLE_SWAP(a,b) {npy_longdouble tmp = (b); (b)=(a); (a) = tmp;} 00028 #define CFLOAT_SWAP(a,b) {npy_cfloat tmp = (b); (b)=(a); (a) = tmp;} 00029 #define CDOUBLE_SWAP(a,b) {npy_cdouble tmp = (b); (b)=(a); (a) = tmp;} 00030 #define CLONGDOUBLE_SWAP(a,b) {npy_clongdouble tmp = (b); (b)=(a); (a) = tmp;} 00031 #define DATETIME_SWAP(a,b) {npy_datetime tmp = (b); (b)=(a); (a) = tmp;} 00032 #define TIMEDELTA_SWAP(a,b) {npy_timedelta tmp = (b); (b)=(a); (a) = tmp;} 00033 00034 /* Need this for the argsort functions */ 00035 #define INTP_SWAP(a,b) {npy_intp tmp = (b); (b)=(a); (a) = tmp;} 00036 00037 /* 00038 ***************************************************************************** 00039 ** COMPARISON FUNCTIONS ** 00040 ***************************************************************************** 00041 */ 00042 00043 NPY_INLINE static int 00044 BOOL_LT(npy_bool a, npy_bool b) 00045 { 00046 return a < b; 00047 } 00048 00049 00050 NPY_INLINE static int 00051 BYTE_LT(npy_byte a, npy_byte b) 00052 { 00053 return a < b; 00054 } 00055 00056 00057 NPY_INLINE static int 00058 UBYTE_LT(npy_ubyte a, npy_ubyte b) 00059 { 00060 return a < b; 00061 } 00062 00063 00064 NPY_INLINE static int 00065 SHORT_LT(npy_short a, npy_short b) 00066 { 00067 return a < b; 00068 } 00069 00070 00071 NPY_INLINE static int 00072 USHORT_LT(npy_ushort a, npy_ushort b) 00073 { 00074 return a < b; 00075 } 00076 00077 00078 NPY_INLINE static int 00079 INT_LT(npy_int a, npy_int b) 00080 { 00081 return a < b; 00082 } 00083 00084 00085 NPY_INLINE static int 00086 UINT_LT(npy_uint a, npy_uint b) 00087 { 00088 return a < b; 00089 } 00090 00091 00092 NPY_INLINE static int 00093 LONG_LT(npy_long a, npy_long b) 00094 { 00095 return a < b; 00096 } 00097 00098 00099 NPY_INLINE static int 00100 ULONG_LT(npy_ulong a, npy_ulong b) 00101 { 00102 return a < b; 00103 } 00104 00105 00106 NPY_INLINE static int 00107 LONGLONG_LT(npy_longlong a, npy_longlong b) 00108 { 00109 return a < b; 00110 } 00111 00112 00113 NPY_INLINE static int 00114 ULONGLONG_LT(npy_ulonglong a, npy_ulonglong b) 00115 { 00116 return a < b; 00117 } 00118 00119 00120 NPY_INLINE static int 00121 FLOAT_LT(npy_float a, npy_float b) 00122 { 00123 return a < b || (b != b && a == a); 00124 } 00125 00126 00127 NPY_INLINE static int 00128 DOUBLE_LT(npy_double a, npy_double b) 00129 { 00130 return a < b || (b != b && a == a); 00131 } 00132 00133 00134 NPY_INLINE static int 00135 LONGDOUBLE_LT(npy_longdouble a, npy_longdouble b) 00136 { 00137 return a < b || (b != b && a == a); 00138 } 00139 00140 00141 NPY_INLINE static int 00142 npy_half_isnan(npy_half h) 00143 { 00144 return ((h&0x7c00u) == 0x7c00u) && ((h&0x03ffu) != 0x0000u); 00145 } 00146 00147 00148 NPY_INLINE static int 00149 npy_half_lt_nonan(npy_half h1, npy_half h2) 00150 { 00151 if (h1&0x8000u) { 00152 if (h2&0x8000u) { 00153 return (h1&0x7fffu) > (h2&0x7fffu); 00154 } 00155 else { 00156 /* Signed zeros are equal, have to check for it */ 00157 return (h1 != 0x8000u) || (h2 != 0x0000u); 00158 } 00159 } 00160 else { 00161 if (h2&0x8000u) { 00162 return 0; 00163 } 00164 else { 00165 return (h1&0x7fffu) < (h2&0x7fffu); 00166 } 00167 } 00168 } 00169 00170 00171 NPY_INLINE static int 00172 HALF_LT(npy_half a, npy_half b) 00173 { 00174 int ret; 00175 00176 if (npy_half_isnan(b)) { 00177 ret = !npy_half_isnan(a); 00178 } 00179 else { 00180 ret = !npy_half_isnan(a) && npy_half_lt_nonan(a, b); 00181 } 00182 00183 return ret; 00184 } 00185 00186 /* 00187 * For inline functions SUN recommends not using a return in the then part 00188 * of an if statement. It's a SUN compiler thing, so assign the return value 00189 * to a variable instead. 00190 */ 00191 NPY_INLINE static int 00192 CFLOAT_LT(npy_cfloat a, npy_cfloat b) 00193 { 00194 int ret; 00195 00196 if (a.real < b.real) { 00197 ret = a.imag == a.imag || b.imag != b.imag; 00198 } 00199 else if (a.real > b.real) { 00200 ret = b.imag != b.imag && a.imag == a.imag; 00201 } 00202 else if (a.real == b.real || (a.real != a.real && b.real != b.real)) { 00203 ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag); 00204 } 00205 else { 00206 ret = b.real != b.real; 00207 } 00208 00209 return ret; 00210 } 00211 00212 00213 NPY_INLINE static int 00214 CDOUBLE_LT(npy_cdouble a, npy_cdouble b) 00215 { 00216 int ret; 00217 00218 if (a.real < b.real) { 00219 ret = a.imag == a.imag || b.imag != b.imag; 00220 } 00221 else if (a.real > b.real) { 00222 ret = b.imag != b.imag && a.imag == a.imag; 00223 } 00224 else if (a.real == b.real || (a.real != a.real && b.real != b.real)) { 00225 ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag); 00226 } 00227 else { 00228 ret = b.real != b.real; 00229 } 00230 00231 return ret; 00232 } 00233 00234 00235 NPY_INLINE static int 00236 CLONGDOUBLE_LT(npy_clongdouble a, npy_clongdouble b) 00237 { 00238 int ret; 00239 00240 if (a.real < b.real) { 00241 ret = a.imag == a.imag || b.imag != b.imag; 00242 } 00243 else if (a.real > b.real) { 00244 ret = b.imag != b.imag && a.imag == a.imag; 00245 } 00246 else if (a.real == b.real || (a.real != a.real && b.real != b.real)) { 00247 ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag); 00248 } 00249 else { 00250 ret = b.real != b.real; 00251 } 00252 00253 return ret; 00254 } 00255 00256 00257 NPY_INLINE static void 00258 STRING_COPY(char *s1, char *s2, size_t len) 00259 { 00260 memcpy(s1, s2, len); 00261 } 00262 00263 00264 NPY_INLINE static void 00265 STRING_SWAP(char *s1, char *s2, size_t len) 00266 { 00267 while(len--) { 00268 const char t = *s1; 00269 *s1++ = *s2; 00270 *s2++ = t; 00271 } 00272 } 00273 00274 00275 NPY_INLINE static int 00276 STRING_LT(char *s1, char *s2, size_t len) 00277 { 00278 const unsigned char *c1 = (unsigned char *)s1; 00279 const unsigned char *c2 = (unsigned char *)s2; 00280 size_t i; 00281 int ret = 0; 00282 00283 for (i = 0; i < len; ++i) { 00284 if (c1[i] != c2[i]) { 00285 ret = c1[i] < c2[i]; 00286 break; 00287 } 00288 } 00289 return ret; 00290 } 00291 00292 00293 NPY_INLINE static void 00294 UNICODE_COPY(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) 00295 { 00296 while(len--) { 00297 *s1++ = *s2++; 00298 } 00299 } 00300 00301 00302 NPY_INLINE static void 00303 UNICODE_SWAP(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) 00304 { 00305 while(len--) { 00306 const npy_ucs4 t = *s1; 00307 *s1++ = *s2; 00308 *s2++ = t; 00309 } 00310 } 00311 00312 00313 NPY_INLINE static int 00314 UNICODE_LT(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) 00315 { 00316 size_t i; 00317 int ret = 0; 00318 00319 for (i = 0; i < len; ++i) { 00320 if (s1[i] != s2[i]) { 00321 ret = s1[i] < s2[i]; 00322 break; 00323 } 00324 } 00325 return ret; 00326 } 00327 00328 00329 NPY_INLINE static int 00330 DATETIME_LT(npy_datetime a, npy_datetime b) 00331 { 00332 return a < b; 00333 } 00334 00335 00336 NPY_INLINE static int 00337 TIMEDELTA_LT(npy_timedelta a, npy_timedelta b) 00338 { 00339 return a < b; 00340 } 00341 00342 00343 NPY_INLINE static void 00344 GENERIC_COPY(char *a, char *b, size_t len) 00345 { 00346 memcpy(a, b, len); 00347 } 00348 00349 00350 NPY_INLINE static void 00351 GENERIC_SWAP(char *a, char *b, size_t len) 00352 { 00353 while(len--) { 00354 const char t = *a; 00355 *a++ = *b; 00356 *b++ = t; 00357 } 00358 } 00359 00360 #endif