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 /*
00005 #include "Python.h"
00006 #include "numpy/npy_common.h"
00007 #include "numpy/npy_math.h"
00008 #include "npy_config.h"
00009 */
00010 #include <numpy/ndarraytypes.h>
00011 
00012 
00013 /*
00014  *****************************************************************************
00015  **                        SWAP MACROS                                      **
00016  *****************************************************************************
00017  */
00018 
00019 #define BOOL_SWAP(a,b) {npy_bool tmp = (b); (b)=(a); (a) = tmp;}
00020 #define BYTE_SWAP(a,b) {npy_byte tmp = (b); (b)=(a); (a) = tmp;}
00021 #define UBYTE_SWAP(a,b) {npy_ubyte tmp = (b); (b)=(a); (a) = tmp;}
00022 #define SHORT_SWAP(a,b) {npy_short tmp = (b); (b)=(a); (a) = tmp;}
00023 #define USHORT_SWAP(a,b) {npy_ushort tmp = (b); (b)=(a); (a) = tmp;}
00024 #define INT_SWAP(a,b) {npy_int tmp = (b); (b)=(a); (a) = tmp;}
00025 #define UINT_SWAP(a,b) {npy_uint tmp = (b); (b)=(a); (a) = tmp;}
00026 #define LONG_SWAP(a,b) {npy_long tmp = (b); (b)=(a); (a) = tmp;}
00027 #define ULONG_SWAP(a,b) {npy_ulong tmp = (b); (b)=(a); (a) = tmp;}
00028 #define LONGLONG_SWAP(a,b) {npy_longlong tmp = (b); (b)=(a); (a) = tmp;}
00029 #define ULONGLONG_SWAP(a,b) {npy_ulonglong tmp = (b); (b)=(a); (a) = tmp;}
00030 #define HALF_SWAP(a,b) {npy_half tmp = (b); (b)=(a); (a) = tmp;}
00031 #define FLOAT_SWAP(a,b) {npy_float tmp = (b); (b)=(a); (a) = tmp;}
00032 #define DOUBLE_SWAP(a,b) {npy_double tmp = (b); (b)=(a); (a) = tmp;}
00033 #define LONGDOUBLE_SWAP(a,b) {npy_longdouble tmp = (b); (b)=(a); (a) = tmp;}
00034 #define CFLOAT_SWAP(a,b) {npy_cfloat tmp = (b); (b)=(a); (a) = tmp;}
00035 #define CDOUBLE_SWAP(a,b) {npy_cdouble tmp = (b); (b)=(a); (a) = tmp;}
00036 #define CLONGDOUBLE_SWAP(a,b) {npy_clongdouble tmp = (b); (b)=(a); (a) = tmp;}
00037 
00038 /* Need this for the argsort functions */
00039 #define INTP_SWAP(a,b) {npy_intp tmp = (b); (b)=(a); (a) = tmp;}
00040 
00041 /*
00042  *****************************************************************************
00043  **                        COMPARISON FUNCTIONS                             **
00044  *****************************************************************************
00045  */
00046 
00047 NPY_INLINE static int
00048 BOOL_LT(npy_bool a, npy_bool b)
00049 {
00050     return a < b;
00051 }
00052 
00053 
00054 NPY_INLINE static int
00055 BYTE_LT(npy_byte a, npy_byte b)
00056 {
00057     return a < b;
00058 }
00059 
00060 
00061 NPY_INLINE static int
00062 UBYTE_LT(npy_ubyte a, npy_ubyte b)
00063 {
00064     return a < b;
00065 }
00066 
00067 
00068 NPY_INLINE static int
00069 SHORT_LT(npy_short a, npy_short b)
00070 {
00071     return a < b;
00072 }
00073 
00074 
00075 NPY_INLINE static int
00076 USHORT_LT(npy_ushort a, npy_ushort b)
00077 {
00078     return a < b;
00079 }
00080 
00081 
00082 NPY_INLINE static int
00083 INT_LT(npy_int a, npy_int b)
00084 {
00085     return a < b;
00086 }
00087 
00088 
00089 NPY_INLINE static int
00090 UINT_LT(npy_uint a, npy_uint b)
00091 {
00092     return a < b;
00093 }
00094 
00095 
00096 NPY_INLINE static int
00097 LONG_LT(npy_long a, npy_long b)
00098 {
00099     return a < b;
00100 }
00101 
00102 
00103 NPY_INLINE static int
00104 ULONG_LT(npy_ulong a, npy_ulong b)
00105 {
00106     return a < b;
00107 }
00108 
00109 
00110 NPY_INLINE static int
00111 LONGLONG_LT(npy_longlong a, npy_longlong b)
00112 {
00113     return a < b;
00114 }
00115 
00116 
00117 NPY_INLINE static int
00118 ULONGLONG_LT(npy_ulonglong a, npy_ulonglong b)
00119 {
00120     return a < b;
00121 }
00122 
00123 
00124 NPY_INLINE static int
00125 FLOAT_LT(npy_float a, npy_float b)
00126 {
00127     return a < b || (b != b && a == a);
00128 }
00129 
00130 
00131 NPY_INLINE static int
00132 DOUBLE_LT(npy_double a, npy_double b)
00133 {
00134     return a < b || (b != b && a == a);
00135 }
00136 
00137 
00138 NPY_INLINE static int
00139 LONGDOUBLE_LT(npy_longdouble a, npy_longdouble b)
00140 {
00141     return a < b || (b != b && a == a);
00142 }
00143 
00144 
00145 NPY_INLINE static int
00146 npy_half_isnan(npy_half h)
00147 {
00148     return ((h&0x7c00u) == 0x7c00u) && ((h&0x03ffu) != 0x0000u);
00149 }
00150 
00151 
00152 NPY_INLINE static int
00153 npy_half_lt_nonan(npy_half h1, npy_half h2)
00154 {
00155     if (h1&0x8000u) {
00156         if (h2&0x8000u) {
00157             return (h1&0x7fffu) > (h2&0x7fffu);
00158         } else {
00159             /* Signed zeros are equal, have to check for it */
00160             return (h1 != 0x8000u) || (h2 != 0x0000u);
00161         }
00162     } else {
00163         if (h2&0x8000u) {
00164             return 0;
00165         } else {
00166             return (h1&0x7fffu) < (h2&0x7fffu);
00167         }
00168     }
00169 }
00170 
00171 
00172 NPY_INLINE static int
00173 HALF_LT(npy_half a, npy_half b)
00174 {
00175     int ret;
00176 
00177     if (npy_half_isnan(b)) {
00178         ret = !npy_half_isnan(a);
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 /* The PyObject functions are stubs for later use */
00258 NPY_INLINE static int
00259 PyObject_LT(PyObject *pa, PyObject *pb)
00260 {
00261     return 0;
00262 }
00263 
00264 
00265 NPY_INLINE static void
00266 STRING_COPY(char *s1, char *s2, size_t len)
00267 {
00268     memcpy(s1, s2, len);
00269 }
00270 
00271 
00272 NPY_INLINE static void
00273 STRING_SWAP(char *s1, char *s2, size_t len)
00274 {
00275     while(len--) {
00276         const char t = *s1;
00277         *s1++ = *s2;
00278         *s2++ = t;
00279     }
00280 }
00281 
00282 
00283 NPY_INLINE static int
00284 STRING_LT(char *s1, char *s2, size_t len)
00285 {
00286     const unsigned char *c1 = (unsigned char *)s1;
00287     const unsigned char *c2 = (unsigned char *)s2;
00288     size_t i;
00289     int ret = 0;
00290 
00291     for (i = 0; i < len; ++i) {
00292         if (c1[i] != c2[i]) {
00293             ret = c1[i] < c2[i];
00294             break;
00295         }
00296     }
00297     return ret;
00298 }
00299 
00300 
00301 NPY_INLINE static void
00302 UNICODE_COPY(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
00303 {
00304     while(len--) {
00305         *s1++ = *s2++;
00306     }
00307 }
00308 
00309 
00310 NPY_INLINE static void
00311 UNICODE_SWAP(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
00312 {
00313     while(len--) {
00314         const npy_ucs4 t = *s1;
00315         *s1++ = *s2;
00316         *s2++ = t;
00317     }
00318 }
00319 
00320 
00321 NPY_INLINE static int
00322 UNICODE_LT(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
00323 {
00324     size_t i;
00325     int ret = 0;
00326 
00327     for (i = 0; i < len; ++i) {
00328         if (s1[i] != s2[i]) {
00329             ret = s1[i] < s2[i];
00330             break;
00331         }
00332     }
00333     return ret;
00334 }
00335 
00336 #endif