1
#ifndef __NPY_SORT_COMMON_H__
2
#define __NPY_SORT_COMMON_H__
3

4
#include <stdlib.h>
5
#include <numpy/ndarraytypes.h>
6

7
/*
8
 *****************************************************************************
9
 **                        SWAP MACROS                                      **
10
 *****************************************************************************
11
 */
12

13
#define BOOL_SWAP(a,b) {npy_bool tmp = (b); (b)=(a); (a) = tmp;}
14
#define BYTE_SWAP(a,b) {npy_byte tmp = (b); (b)=(a); (a) = tmp;}
15
#define UBYTE_SWAP(a,b) {npy_ubyte tmp = (b); (b)=(a); (a) = tmp;}
16
#define SHORT_SWAP(a,b) {npy_short tmp = (b); (b)=(a); (a) = tmp;}
17
#define USHORT_SWAP(a,b) {npy_ushort tmp = (b); (b)=(a); (a) = tmp;}
18
#define INT_SWAP(a,b) {npy_int tmp = (b); (b)=(a); (a) = tmp;}
19
#define UINT_SWAP(a,b) {npy_uint tmp = (b); (b)=(a); (a) = tmp;}
20
#define LONG_SWAP(a,b) {npy_long tmp = (b); (b)=(a); (a) = tmp;}
21
#define ULONG_SWAP(a,b) {npy_ulong tmp = (b); (b)=(a); (a) = tmp;}
22
#define LONGLONG_SWAP(a,b) {npy_longlong tmp = (b); (b)=(a); (a) = tmp;}
23
#define ULONGLONG_SWAP(a,b) {npy_ulonglong tmp = (b); (b)=(a); (a) = tmp;}
24
#define HALF_SWAP(a,b) {npy_half tmp = (b); (b)=(a); (a) = tmp;}
25
#define FLOAT_SWAP(a,b) {npy_float tmp = (b); (b)=(a); (a) = tmp;}
26
#define DOUBLE_SWAP(a,b) {npy_double tmp = (b); (b)=(a); (a) = tmp;}
27
#define LONGDOUBLE_SWAP(a,b) {npy_longdouble tmp = (b); (b)=(a); (a) = tmp;}
28
#define CFLOAT_SWAP(a,b) {npy_cfloat tmp = (b); (b)=(a); (a) = tmp;}
29
#define CDOUBLE_SWAP(a,b) {npy_cdouble tmp = (b); (b)=(a); (a) = tmp;}
30
#define CLONGDOUBLE_SWAP(a,b) {npy_clongdouble tmp = (b); (b)=(a); (a) = tmp;}
31
#define DATETIME_SWAP(a,b) {npy_datetime tmp = (b); (b)=(a); (a) = tmp;}
32
#define TIMEDELTA_SWAP(a,b) {npy_timedelta tmp = (b); (b)=(a); (a) = tmp;}
33

34
/* Need this for the argsort functions */
35
#define INTP_SWAP(a,b) {npy_intp tmp = (b); (b)=(a); (a) = tmp;}
36

37
/*
38
 *****************************************************************************
39
 **                        COMPARISON FUNCTIONS                             **
40
 *****************************************************************************
41
 */
42

43
NPY_INLINE static int
44
BOOL_LT(npy_bool a, npy_bool b)
45
{
46
    return a < b;
47
}
48

49

50
NPY_INLINE static int
51
BYTE_LT(npy_byte a, npy_byte b)
52
{
53
    return a < b;
54
}
55

56

57
NPY_INLINE static int
58
UBYTE_LT(npy_ubyte a, npy_ubyte b)
59
{
60
    return a < b;
61
}
62

63

64
NPY_INLINE static int
65
SHORT_LT(npy_short a, npy_short b)
66
{
67
    return a < b;
68
}
69

70

71
NPY_INLINE static int
72
USHORT_LT(npy_ushort a, npy_ushort b)
73
{
74
    return a < b;
75
}
76

77

78
NPY_INLINE static int
79
INT_LT(npy_int a, npy_int b)
80
{
81
    return a < b;
82
}
83

84

85
NPY_INLINE static int
86
UINT_LT(npy_uint a, npy_uint b)
87
{
88
    return a < b;
89
}
90

91

92
NPY_INLINE static int
93
LONG_LT(npy_long a, npy_long b)
94
{
95
    return a < b;
96
}
97

98

99
NPY_INLINE static int
100
ULONG_LT(npy_ulong a, npy_ulong b)
101
{
102
    return a < b;
103
}
104

105

106
NPY_INLINE static int
107
LONGLONG_LT(npy_longlong a, npy_longlong b)
108
{
109
    return a < b;
110
}
111

112

113
NPY_INLINE static int
114
ULONGLONG_LT(npy_ulonglong a, npy_ulonglong b)
115
{
116
    return a < b;
117
}
118

119

120
NPY_INLINE static int
121
FLOAT_LT(npy_float a, npy_float b)
122
{
123 1
    return a < b || (b != b && a == a);
124
}
125

126

127
NPY_INLINE static int
128
DOUBLE_LT(npy_double a, npy_double b)
129
{
130 1
    return a < b || (b != b && a == a);
131
}
132

133

134
NPY_INLINE static int
135
LONGDOUBLE_LT(npy_longdouble a, npy_longdouble b)
136
{
137 1
    return a < b || (b != b && a == a);
138
}
139

140

141
NPY_INLINE static int
142
npy_half_isnan(npy_half h)
143
{
144 1
    return ((h&0x7c00u) == 0x7c00u) && ((h&0x03ffu) != 0x0000u);
145
}
146

147

148
NPY_INLINE static int
149
npy_half_lt_nonan(npy_half h1, npy_half h2)
150
{
151 1
    if (h1&0x8000u) {
152 1
        if (h2&0x8000u) {
153 1
            return (h1&0x7fffu) > (h2&0x7fffu);
154
        }
155
        else {
156
            /* Signed zeros are equal, have to check for it */
157 1
            return (h1 != 0x8000u) || (h2 != 0x0000u);
158
        }
159
    }
160
    else {
161 1
        if (h2&0x8000u) {
162
            return 0;
163
        }
164
        else {
165 1
            return (h1&0x7fffu) < (h2&0x7fffu);
166
        }
167
    }
168
}
169

170

171
NPY_INLINE static int
172 1
HALF_LT(npy_half a, npy_half b)
173
{
174
    int ret;
175

176 1
    if (npy_half_isnan(b)) {
177 0
        ret = !npy_half_isnan(a);
178
    }
179
    else {
180 1
        ret = !npy_half_isnan(a) && npy_half_lt_nonan(a, b);
181
    }
182

183 1
    return ret;
184
}
185

186
/*
187
 * For inline functions SUN recommends not using a return in the then part
188
 * of an if statement. It's a SUN compiler thing, so assign the return value
189
 * to a variable instead.
190
 */
191
NPY_INLINE static int
192 1
CFLOAT_LT(npy_cfloat a, npy_cfloat b)
193
{
194
    int ret;
195

196 1
    if (a.real < b.real) {
197 1
        ret = a.imag == a.imag || b.imag != b.imag;
198
    }
199 1
    else if (a.real > b.real) {
200 1
        ret = b.imag != b.imag && a.imag == a.imag;
201
    }
202 1
    else if (a.real == b.real || (a.real != a.real && b.real != b.real)) {
203 1
        ret =  a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag);
204
    }
205
    else {
206 0
        ret = b.real != b.real;
207
    }
208

209 1
    return ret;
210
}
211

212

213
NPY_INLINE static int
214 1
CDOUBLE_LT(npy_cdouble a, npy_cdouble b)
215
{
216
    int ret;
217

218 1
    if (a.real < b.real) {
219 1
        ret = a.imag == a.imag || b.imag != b.imag;
220
    }
221 1
    else if (a.real > b.real) {
222 1
        ret = b.imag != b.imag && a.imag == a.imag;
223
    }
224 1
    else if (a.real == b.real || (a.real != a.real && b.real != b.real)) {
225 1
        ret =  a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag);
226
    }
227
    else {
228 1
        ret = b.real != b.real;
229
    }
230

231 1
    return ret;
232
}
233

234

235
NPY_INLINE static int
236 1
CLONGDOUBLE_LT(npy_clongdouble a, npy_clongdouble b)
237
{
238
    int ret;
239

240 1
    if (a.real < b.real) {
241 1
        ret = a.imag == a.imag || b.imag != b.imag;
242
    }
243 1
    else if (a.real > b.real) {
244 1
        ret = b.imag != b.imag && a.imag == a.imag;
245
    }
246 1
    else if (a.real == b.real || (a.real != a.real && b.real != b.real)) {
247 1
        ret =  a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag);
248
    }
249
    else {
250 0
        ret = b.real != b.real;
251
    }
252

253 1
    return ret;
254
}
255

256

257
NPY_INLINE static void
258
STRING_COPY(char *s1, char *s2, size_t len)
259
{
260 1
    memcpy(s1, s2, len);
261
}
262

263

264
NPY_INLINE static void
265
STRING_SWAP(char *s1, char *s2, size_t len)
266
{
267 1
    while(len--) {
268 1
        const char t = *s1;
269 1
        *s1++ = *s2;
270 1
        *s2++ = t;
271
    }
272
}
273

274

275
NPY_INLINE static int
276
STRING_LT(const char *s1, const char *s2, size_t len)
277
{
278 1
    const unsigned char *c1 = (const unsigned char *)s1;
279 1
    const unsigned char *c2 = (const unsigned char *)s2;
280
    size_t i;
281 1
    int ret = 0;
282

283 1
    for (i = 0; i < len; ++i) {
284 1
        if (c1[i] != c2[i]) {
285 1
            ret = c1[i] < c2[i];
286
            break;
287
        }
288
    }
289
    return ret;
290
}
291

292

293
NPY_INLINE static void
294
UNICODE_COPY(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
295
{
296 1
    while(len--) {
297 1
        *s1++ = *s2++;
298
    }
299
}
300

301

302
NPY_INLINE static void
303
UNICODE_SWAP(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
304
{
305 1
    while(len--) {
306 1
        const npy_ucs4 t = *s1;
307 1
        *s1++ = *s2;
308 1
        *s2++ = t;
309
    }
310
}
311

312

313
NPY_INLINE static int
314
UNICODE_LT(const npy_ucs4 *s1, const npy_ucs4 *s2, size_t len)
315
{
316
    size_t i;
317 1
    int ret = 0;
318

319 1
    for (i = 0; i < len; ++i) {
320 1
        if (s1[i] != s2[i]) {
321 1
            ret = s1[i] < s2[i];
322
            break;
323
        }
324
    }
325
    return ret;
326
}
327

328

329
NPY_INLINE static int
330
DATETIME_LT(npy_datetime a, npy_datetime b)
331
{
332 1
    if (a == NPY_DATETIME_NAT) {
333
        return 0;
334
    }
335

336 1
    if (b == NPY_DATETIME_NAT) {
337
        return 1;
338
    }
339

340 1
    return a < b;
341
}
342

343

344
NPY_INLINE static int
345
TIMEDELTA_LT(npy_timedelta a, npy_timedelta b)
346
{
347 1
    if (a == NPY_DATETIME_NAT) {
348
        return 0;
349
    }
350

351 1
    if (b == NPY_DATETIME_NAT) {
352
        return 1;
353
    }
354

355 1
    return a < b;
356
}
357

358

359
NPY_INLINE static void
360
GENERIC_COPY(char *a, char *b, size_t len)
361
{
362 1
    memcpy(a, b, len);
363
}
364

365

366
NPY_INLINE static void
367
GENERIC_SWAP(char *a, char *b, size_t len)
368
{
369 1
    while(len--) {
370 1
        const char t = *a;
371 1
        *a++ = *b;
372 1
        *b++ = t;
373
    }
374
}
375

376
#endif

Read our documentation on viewing source code .

Loading