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