17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Bisection algorithms. Drop in replacement for bisect.py
27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielConverted to C by Dmitry Vasiliev (dima at hlabs.spb.ru).
47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel*/
57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python.h"
77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic Py_ssize_t
97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinternal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi)
107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *litem;
127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t mid, res;
137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (lo < 0) {
157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError, "lo must be non-negative");
167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (hi == -1) {
197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hi = PySequence_Size(list);
207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (hi < 0)
217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (lo < hi) {
247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* The (size_t)cast ensures that the addition and subsequent division
257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           are performed as unsigned operations, avoiding difficulties from
267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           signed overflow.  (See issue 13496.) */
277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        mid = ((size_t)lo + hi) / 2;
287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        litem = PySequence_GetItem(list, mid);
297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (litem == NULL)
307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = PyObject_RichCompareBool(item, litem, Py_LT);
327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(litem);
337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res < 0)
347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res)
367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            hi = mid;
377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            lo = mid + 1;
397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return lo;
417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbisect_right(PyObject *self, PyObject *args, PyObject *kw)
457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *list, *item;
477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t lo = 0;
487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t hi = -1;
497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t index;
507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"a", "x", "lo", "hi", NULL};
517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:bisect_right",
537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        keywords, &list, &item, &lo, &hi))
547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    index = internal_bisect_right(list, item, lo, hi);
567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (index < 0)
577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyInt_FromSsize_t(index);
597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(bisect_right_doc,
627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"bisect(a, x[, lo[, hi]]) -> index\n\
637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbisect_right(a, x[, lo[, hi]]) -> index\n\
647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielReturn the index where to insert item x in list a, assuming a is sorted.\n\
667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielThe return value i is such that all e in a[:i] have e <= x, and all e in\n\
687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniela[i:] have e > x.  So if x already appears in the list, i points just\n\
697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbeyond the rightmost x already there\n\
707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielOptional args lo (default 0) and hi (default len(a)) bound the\n\
727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielslice of a to be searched.\n");
737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinsort_right(PyObject *self, PyObject *args, PyObject *kw)
767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *list, *item, *result;
787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t lo = 0;
797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t hi = -1;
807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t index;
817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"a", "x", "lo", "hi", NULL};
827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:insort_right",
847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        keywords, &list, &item, &lo, &hi))
857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    index = internal_bisect_right(list, item, lo, hi);
877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (index < 0)
887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyList_CheckExact(list)) {
907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (PyList_Insert(list, index, item) < 0)
917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } else {
937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = PyObject_CallMethod(list, "insert", "nO",
947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     index, item);
957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (result == NULL)
967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(result);
987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_RETURN_NONE;
1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(insort_right_doc,
1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"insort(a, x[, lo[, hi]])\n\
1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinsort_right(a, x[, lo[, hi]])\n\
1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielInsert item x in list a, and keep it sorted assuming a is sorted.\n\
1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIf x is already in a, insert it to the right of the rightmost x.\n\
1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielOptional args lo (default 0) and hi (default len(a)) bound the\n\
1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielslice of a to be searched.\n");
1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic Py_ssize_t
1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinternal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi)
1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *litem;
1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t mid, res;
1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (lo < 0) {
1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError, "lo must be non-negative");
1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (hi == -1) {
1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hi = PySequence_Size(list);
1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (hi < 0)
1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (lo < hi) {
1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* The (size_t)cast ensures that the addition and subsequent division
1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           are performed as unsigned operations, avoiding difficulties from
1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           signed overflow.  (See issue 13496.) */
1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        mid = ((size_t)lo + hi) / 2;
1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        litem = PySequence_GetItem(list, mid);
1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (litem == NULL)
1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = PyObject_RichCompareBool(litem, item, Py_LT);
1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(litem);
1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res < 0)
1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res)
1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            lo = mid + 1;
1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            hi = mid;
1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return lo;
1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbisect_left(PyObject *self, PyObject *args, PyObject *kw)
1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *list, *item;
1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t lo = 0;
1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t hi = -1;
1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t index;
1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"a", "x", "lo", "hi", NULL};
1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:bisect_left",
1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        keywords, &list, &item, &lo, &hi))
1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    index = internal_bisect_left(list, item, lo, hi);
1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (index < 0)
1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyInt_FromSsize_t(index);
1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(bisect_left_doc,
1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"bisect_left(a, x[, lo[, hi]]) -> index\n\
1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielReturn the index where to insert item x in list a, assuming a is sorted.\n\
1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielThe return value i is such that all e in a[:i] have e < x, and all e in\n\
1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniela[i:] have e >= x.  So if x already appears in the list, i points just\n\
1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbefore the leftmost x already there.\n\
1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielOptional args lo (default 0) and hi (default len(a)) bound the\n\
1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielslice of a to be searched.\n");
1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinsort_left(PyObject *self, PyObject *args, PyObject *kw)
1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *list, *item, *result;
1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t lo = 0;
1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t hi = -1;
1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t index;
1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"a", "x", "lo", "hi", NULL};
1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:insort_left",
1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        keywords, &list, &item, &lo, &hi))
1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    index = internal_bisect_left(list, item, lo, hi);
1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (index < 0)
1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyList_CheckExact(list)) {
1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (PyList_Insert(list, index, item) < 0)
1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } else {
1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = PyObject_CallMethod(list, "insert", "nO",
1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     index, item);
2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (result == NULL)
2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(result);
2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_RETURN_NONE;
2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(insort_left_doc,
2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"insort_left(a, x[, lo[, hi]])\n\
2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielInsert item x in list a, and keep it sorted assuming a is sorted.\n\
2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIf x is already in a, insert it to the left of the leftmost x.\n\
2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielOptional args lo (default 0) and hi (default len(a)) bound the\n\
2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielslice of a to be searched.\n");
2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMethodDef bisect_methods[] = {
2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"bisect_right", (PyCFunction)bisect_right,
2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        METH_VARARGS|METH_KEYWORDS, bisect_right_doc},
2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"bisect", (PyCFunction)bisect_right,
2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        METH_VARARGS|METH_KEYWORDS, bisect_right_doc},
2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"insort_right", (PyCFunction)insort_right,
2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        METH_VARARGS|METH_KEYWORDS, insort_right_doc},
2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"insort", (PyCFunction)insort_right,
2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        METH_VARARGS|METH_KEYWORDS, insort_right_doc},
2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"bisect_left", (PyCFunction)bisect_left,
2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        METH_VARARGS|METH_KEYWORDS, bisect_left_doc},
2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"insort_left", (PyCFunction)insort_left,
2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        METH_VARARGS|METH_KEYWORDS, insort_left_doc},
2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL, NULL} /* sentinel */
2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(module_doc,
2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Bisection algorithms.\n\
2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\n\
2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielThis module provides support for maintaining a list in sorted order without\n\
2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielhaving to sort the list after each insertion. For long lists of items with\n\
2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielexpensive comparison operations, this can be an improvement over the more\n\
2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielcommon approach.\n");
2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyMODINIT_FUNC
2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinit_bisect(void)
2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_InitModule3("_bisect", bisect_methods, module_doc);
2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
247