numpy  2.0.0
src/npysort/npysort_common.h
Go to the documentation of this file.
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