#ifndef __NPY_BINSEARCH_H__
#define __NPY_BINSEARCH_H__
#include "npy_sort.h"
#include <numpy/npy_common.h>
#include <numpy/ndarraytypes.h>
typedef void (PyArray_BinSearchFunc)(const char*, const char*, char*,
npy_intp, npy_intp,
npy_intp, npy_intp, npy_intp,
PyArrayObject*);
typedef int (PyArray_ArgBinSearchFunc)(const char*, const char*,
const char*, char*,
npy_intp, npy_intp, npy_intp,
npy_intp, npy_intp, npy_intp,
PyArrayObject*);
struct binsearch_map {
enum NPY_TYPES typenum;
PyArray_BinSearchFunc *binsearch[NPY_NSEARCHSIDES];
};
struct argbinsearch_map {
enum NPY_TYPES typenum;
PyArray_ArgBinSearchFunc *argbinsearch[NPY_NSEARCHSIDES];
};
/**begin repeat
*
* #side = left, right#
*/
/**begin repeat1
*
* #suff = bool, byte, ubyte, short, ushort, int, uint, long, ulong,
* longlong, ulonglong, half, float, double, longdouble,
* cfloat, cdouble, clongdouble, datetime, timedelta#
*/
NPY_VISIBILITY_HIDDEN void
binsearch_@side@_@suff@(const char *arr, const char *key, char *ret,
npy_intp arr_len, npy_intp key_len,
npy_intp arr_str, npy_intp key_str, npy_intp ret_str,
PyArrayObject *unused);
NPY_VISIBILITY_HIDDEN int
argbinsearch_@side@_@suff@(const char *arr, const char *key,
const char *sort, char *ret,
npy_intp arr_len, npy_intp key_len,
npy_intp arr_str, npy_intp key_str,
npy_intp sort_str, npy_intp ret_str,
PyArrayObject *unused);
/**end repeat1**/
NPY_VISIBILITY_HIDDEN void
npy_binsearch_@side@(const char *arr, const char *key, char *ret,
npy_intp arr_len, npy_intp key_len,
npy_intp arr_str, npy_intp key_str,
npy_intp ret_str, PyArrayObject *cmp);
NPY_VISIBILITY_HIDDEN int
npy_argbinsearch_@side@(const char *arr, const char *key,
const char *sort, char *ret,
npy_intp arr_len, npy_intp key_len,
npy_intp arr_str, npy_intp key_str,
npy_intp sort_str, npy_intp ret_str,
PyArrayObject *cmp);
/**end repeat**/
/**begin repeat
*
* #arg = , arg#
* #Arg = , Arg#
*/
static struct @arg@binsearch_map _@arg@binsearch_map[] = {
/* If adding new types, make sure to keep them ordered by type num */
/**begin repeat1
*
* #TYPE = BOOL, BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG,
* LONGLONG, ULONGLONG, FLOAT, DOUBLE, LONGDOUBLE,
* CFLOAT, CDOUBLE, CLONGDOUBLE, DATETIME, TIMEDELTA, HALF#
* #suff = bool, byte, ubyte, short, ushort, int, uint, long, ulong,
* longlong, ulonglong, float, double, longdouble,
* cfloat, cdouble, clongdouble, datetime, timedelta, half#
*/
{NPY_@TYPE@,
{
&@arg@binsearch_left_@suff@,
&@arg@binsearch_right_@suff@,
},
},
/**end repeat1**/
};
static PyArray_@Arg@BinSearchFunc *gen@arg@binsearch_map[] = {
&npy_@arg@binsearch_left,
&npy_@arg@binsearch_right,
};
static NPY_INLINE PyArray_@Arg@BinSearchFunc*
get_@arg@binsearch_func(PyArray_Descr *dtype, NPY_SEARCHSIDE side)
{
static npy_intp num_funcs = sizeof(_@arg@binsearch_map) /
sizeof(_@arg@binsearch_map[0]);
npy_intp min_idx = 0;
npy_intp max_idx = num_funcs;
int type = dtype->type_num;
if (side >= NPY_NSEARCHSIDES) {
return NULL;
}
/*
* It seems only fair that a binary search function be searched for
* using a binary search...
*/
while (min_idx < max_idx) {
npy_intp mid_idx = min_idx + ((max_idx - min_idx) >> 1);
if (_@arg@binsearch_map[mid_idx].typenum < type) {
min_idx = mid_idx + 1;
}
else {
max_idx = mid_idx;
}
}
if (min_idx < num_funcs && _@arg@binsearch_map[min_idx].typenum == type) {
return _@arg@binsearch_map[min_idx].@arg@binsearch[side];
}
if (dtype->f->compare) {
return gen@arg@binsearch_map[side];
}
return NULL;
}
/**end repeat**/
#endif