17db96d56Sopenharmony_ci/* List object implementation */
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci#include "Python.h"
47db96d56Sopenharmony_ci#include "pycore_abstract.h"      // _PyIndex_Check()
57db96d56Sopenharmony_ci#include "pycore_interp.h"        // PyInterpreterState.list
67db96d56Sopenharmony_ci#include "pycore_list.h"          // struct _Py_list_state
77db96d56Sopenharmony_ci#include "pycore_object.h"        // _PyObject_GC_TRACK()
87db96d56Sopenharmony_ci#include "pycore_tuple.h"         // _PyTuple_FromArray()
97db96d56Sopenharmony_ci#include <stddef.h>
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci/*[clinic input]
127db96d56Sopenharmony_ciclass list "PyListObject *" "&PyList_Type"
137db96d56Sopenharmony_ci[clinic start generated code]*/
147db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f9b222678f9f71e0]*/
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci#include "clinic/listobject.c.h"
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci_Py_DECLARE_STR(list_err, "list index out of range");
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci#if PyList_MAXFREELIST > 0
217db96d56Sopenharmony_cistatic struct _Py_list_state *
227db96d56Sopenharmony_ciget_list_state(void)
237db96d56Sopenharmony_ci{
247db96d56Sopenharmony_ci    PyInterpreterState *interp = _PyInterpreterState_GET();
257db96d56Sopenharmony_ci    return &interp->list;
267db96d56Sopenharmony_ci}
277db96d56Sopenharmony_ci#endif
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci/* Ensure ob_item has room for at least newsize elements, and set
317db96d56Sopenharmony_ci * ob_size to newsize.  If newsize > ob_size on entry, the content
327db96d56Sopenharmony_ci * of the new slots at exit is undefined heap trash; it's the caller's
337db96d56Sopenharmony_ci * responsibility to overwrite them with sane values.
347db96d56Sopenharmony_ci * The number of allocated elements may grow, shrink, or stay the same.
357db96d56Sopenharmony_ci * Failure is impossible if newsize <= self.allocated on entry, although
367db96d56Sopenharmony_ci * that partly relies on an assumption that the system realloc() never
377db96d56Sopenharmony_ci * fails when passed a number of bytes <= the number of bytes last
387db96d56Sopenharmony_ci * allocated (the C standard doesn't guarantee this, but it's hard to
397db96d56Sopenharmony_ci * imagine a realloc implementation where it wouldn't be true).
407db96d56Sopenharmony_ci * Note that self->ob_item may change, and even if newsize is less
417db96d56Sopenharmony_ci * than ob_size on entry.
427db96d56Sopenharmony_ci */
437db96d56Sopenharmony_cistatic int
447db96d56Sopenharmony_cilist_resize(PyListObject *self, Py_ssize_t newsize)
457db96d56Sopenharmony_ci{
467db96d56Sopenharmony_ci    PyObject **items;
477db96d56Sopenharmony_ci    size_t new_allocated, num_allocated_bytes;
487db96d56Sopenharmony_ci    Py_ssize_t allocated = self->allocated;
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci    /* Bypass realloc() when a previous overallocation is large enough
517db96d56Sopenharmony_ci       to accommodate the newsize.  If the newsize falls lower than half
527db96d56Sopenharmony_ci       the allocated size, then proceed with the realloc() to shrink the list.
537db96d56Sopenharmony_ci    */
547db96d56Sopenharmony_ci    if (allocated >= newsize && newsize >= (allocated >> 1)) {
557db96d56Sopenharmony_ci        assert(self->ob_item != NULL || newsize == 0);
567db96d56Sopenharmony_ci        Py_SET_SIZE(self, newsize);
577db96d56Sopenharmony_ci        return 0;
587db96d56Sopenharmony_ci    }
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci    /* This over-allocates proportional to the list size, making room
617db96d56Sopenharmony_ci     * for additional growth.  The over-allocation is mild, but is
627db96d56Sopenharmony_ci     * enough to give linear-time amortized behavior over a long
637db96d56Sopenharmony_ci     * sequence of appends() in the presence of a poorly-performing
647db96d56Sopenharmony_ci     * system realloc().
657db96d56Sopenharmony_ci     * Add padding to make the allocated size multiple of 4.
667db96d56Sopenharmony_ci     * The growth pattern is:  0, 4, 8, 16, 24, 32, 40, 52, 64, 76, ...
677db96d56Sopenharmony_ci     * Note: new_allocated won't overflow because the largest possible value
687db96d56Sopenharmony_ci     *       is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.
697db96d56Sopenharmony_ci     */
707db96d56Sopenharmony_ci    new_allocated = ((size_t)newsize + (newsize >> 3) + 6) & ~(size_t)3;
717db96d56Sopenharmony_ci    /* Do not overallocate if the new size is closer to overallocated size
727db96d56Sopenharmony_ci     * than to the old size.
737db96d56Sopenharmony_ci     */
747db96d56Sopenharmony_ci    if (newsize - Py_SIZE(self) > (Py_ssize_t)(new_allocated - newsize))
757db96d56Sopenharmony_ci        new_allocated = ((size_t)newsize + 3) & ~(size_t)3;
767db96d56Sopenharmony_ci
777db96d56Sopenharmony_ci    if (newsize == 0)
787db96d56Sopenharmony_ci        new_allocated = 0;
797db96d56Sopenharmony_ci    if (new_allocated <= (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) {
807db96d56Sopenharmony_ci        num_allocated_bytes = new_allocated * sizeof(PyObject *);
817db96d56Sopenharmony_ci        items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes);
827db96d56Sopenharmony_ci    }
837db96d56Sopenharmony_ci    else {
847db96d56Sopenharmony_ci        // integer overflow
857db96d56Sopenharmony_ci        items = NULL;
867db96d56Sopenharmony_ci    }
877db96d56Sopenharmony_ci    if (items == NULL) {
887db96d56Sopenharmony_ci        PyErr_NoMemory();
897db96d56Sopenharmony_ci        return -1;
907db96d56Sopenharmony_ci    }
917db96d56Sopenharmony_ci    self->ob_item = items;
927db96d56Sopenharmony_ci    Py_SET_SIZE(self, newsize);
937db96d56Sopenharmony_ci    self->allocated = new_allocated;
947db96d56Sopenharmony_ci    return 0;
957db96d56Sopenharmony_ci}
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_cistatic int
987db96d56Sopenharmony_cilist_preallocate_exact(PyListObject *self, Py_ssize_t size)
997db96d56Sopenharmony_ci{
1007db96d56Sopenharmony_ci    assert(self->ob_item == NULL);
1017db96d56Sopenharmony_ci    assert(size > 0);
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ci    /* Since the Python memory allocator has granularity of 16 bytes on 64-bit
1047db96d56Sopenharmony_ci     * platforms (8 on 32-bit), there is no benefit of allocating space for
1057db96d56Sopenharmony_ci     * the odd number of items, and there is no drawback of rounding the
1067db96d56Sopenharmony_ci     * allocated size up to the nearest even number.
1077db96d56Sopenharmony_ci     */
1087db96d56Sopenharmony_ci    size = (size + 1) & ~(size_t)1;
1097db96d56Sopenharmony_ci    PyObject **items = PyMem_New(PyObject*, size);
1107db96d56Sopenharmony_ci    if (items == NULL) {
1117db96d56Sopenharmony_ci        PyErr_NoMemory();
1127db96d56Sopenharmony_ci        return -1;
1137db96d56Sopenharmony_ci    }
1147db96d56Sopenharmony_ci    self->ob_item = items;
1157db96d56Sopenharmony_ci    self->allocated = size;
1167db96d56Sopenharmony_ci    return 0;
1177db96d56Sopenharmony_ci}
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_civoid
1207db96d56Sopenharmony_ci_PyList_ClearFreeList(PyInterpreterState *interp)
1217db96d56Sopenharmony_ci{
1227db96d56Sopenharmony_ci#if PyList_MAXFREELIST > 0
1237db96d56Sopenharmony_ci    struct _Py_list_state *state = &interp->list;
1247db96d56Sopenharmony_ci    while (state->numfree) {
1257db96d56Sopenharmony_ci        PyListObject *op = state->free_list[--state->numfree];
1267db96d56Sopenharmony_ci        assert(PyList_CheckExact(op));
1277db96d56Sopenharmony_ci        PyObject_GC_Del(op);
1287db96d56Sopenharmony_ci    }
1297db96d56Sopenharmony_ci#endif
1307db96d56Sopenharmony_ci}
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_civoid
1337db96d56Sopenharmony_ci_PyList_Fini(PyInterpreterState *interp)
1347db96d56Sopenharmony_ci{
1357db96d56Sopenharmony_ci    _PyList_ClearFreeList(interp);
1367db96d56Sopenharmony_ci#if defined(Py_DEBUG) && PyList_MAXFREELIST > 0
1377db96d56Sopenharmony_ci    struct _Py_list_state *state = &interp->list;
1387db96d56Sopenharmony_ci    state->numfree = -1;
1397db96d56Sopenharmony_ci#endif
1407db96d56Sopenharmony_ci}
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_ci/* Print summary info about the state of the optimized allocator */
1437db96d56Sopenharmony_civoid
1447db96d56Sopenharmony_ci_PyList_DebugMallocStats(FILE *out)
1457db96d56Sopenharmony_ci{
1467db96d56Sopenharmony_ci#if PyList_MAXFREELIST > 0
1477db96d56Sopenharmony_ci    struct _Py_list_state *state = get_list_state();
1487db96d56Sopenharmony_ci    _PyDebugAllocatorStats(out,
1497db96d56Sopenharmony_ci                           "free PyListObject",
1507db96d56Sopenharmony_ci                           state->numfree, sizeof(PyListObject));
1517db96d56Sopenharmony_ci#endif
1527db96d56Sopenharmony_ci}
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ciPyObject *
1557db96d56Sopenharmony_ciPyList_New(Py_ssize_t size)
1567db96d56Sopenharmony_ci{
1577db96d56Sopenharmony_ci    PyListObject *op;
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_ci    if (size < 0) {
1607db96d56Sopenharmony_ci        PyErr_BadInternalCall();
1617db96d56Sopenharmony_ci        return NULL;
1627db96d56Sopenharmony_ci    }
1637db96d56Sopenharmony_ci
1647db96d56Sopenharmony_ci#if PyList_MAXFREELIST > 0
1657db96d56Sopenharmony_ci    struct _Py_list_state *state = get_list_state();
1667db96d56Sopenharmony_ci#ifdef Py_DEBUG
1677db96d56Sopenharmony_ci    // PyList_New() must not be called after _PyList_Fini()
1687db96d56Sopenharmony_ci    assert(state->numfree != -1);
1697db96d56Sopenharmony_ci#endif
1707db96d56Sopenharmony_ci    if (PyList_MAXFREELIST && state->numfree) {
1717db96d56Sopenharmony_ci        state->numfree--;
1727db96d56Sopenharmony_ci        op = state->free_list[state->numfree];
1737db96d56Sopenharmony_ci        OBJECT_STAT_INC(from_freelist);
1747db96d56Sopenharmony_ci        _Py_NewReference((PyObject *)op);
1757db96d56Sopenharmony_ci    }
1767db96d56Sopenharmony_ci    else
1777db96d56Sopenharmony_ci#endif
1787db96d56Sopenharmony_ci    {
1797db96d56Sopenharmony_ci        op = PyObject_GC_New(PyListObject, &PyList_Type);
1807db96d56Sopenharmony_ci        if (op == NULL) {
1817db96d56Sopenharmony_ci            return NULL;
1827db96d56Sopenharmony_ci        }
1837db96d56Sopenharmony_ci    }
1847db96d56Sopenharmony_ci    if (size <= 0) {
1857db96d56Sopenharmony_ci        op->ob_item = NULL;
1867db96d56Sopenharmony_ci    }
1877db96d56Sopenharmony_ci    else {
1887db96d56Sopenharmony_ci        op->ob_item = (PyObject **) PyMem_Calloc(size, sizeof(PyObject *));
1897db96d56Sopenharmony_ci        if (op->ob_item == NULL) {
1907db96d56Sopenharmony_ci            Py_DECREF(op);
1917db96d56Sopenharmony_ci            return PyErr_NoMemory();
1927db96d56Sopenharmony_ci        }
1937db96d56Sopenharmony_ci    }
1947db96d56Sopenharmony_ci    Py_SET_SIZE(op, size);
1957db96d56Sopenharmony_ci    op->allocated = size;
1967db96d56Sopenharmony_ci    _PyObject_GC_TRACK(op);
1977db96d56Sopenharmony_ci    return (PyObject *) op;
1987db96d56Sopenharmony_ci}
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_cistatic PyObject *
2017db96d56Sopenharmony_cilist_new_prealloc(Py_ssize_t size)
2027db96d56Sopenharmony_ci{
2037db96d56Sopenharmony_ci    assert(size > 0);
2047db96d56Sopenharmony_ci    PyListObject *op = (PyListObject *) PyList_New(0);
2057db96d56Sopenharmony_ci    if (op == NULL) {
2067db96d56Sopenharmony_ci        return NULL;
2077db96d56Sopenharmony_ci    }
2087db96d56Sopenharmony_ci    assert(op->ob_item == NULL);
2097db96d56Sopenharmony_ci    op->ob_item = PyMem_New(PyObject *, size);
2107db96d56Sopenharmony_ci    if (op->ob_item == NULL) {
2117db96d56Sopenharmony_ci        Py_DECREF(op);
2127db96d56Sopenharmony_ci        return PyErr_NoMemory();
2137db96d56Sopenharmony_ci    }
2147db96d56Sopenharmony_ci    op->allocated = size;
2157db96d56Sopenharmony_ci    return (PyObject *) op;
2167db96d56Sopenharmony_ci}
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ciPy_ssize_t
2197db96d56Sopenharmony_ciPyList_Size(PyObject *op)
2207db96d56Sopenharmony_ci{
2217db96d56Sopenharmony_ci    if (!PyList_Check(op)) {
2227db96d56Sopenharmony_ci        PyErr_BadInternalCall();
2237db96d56Sopenharmony_ci        return -1;
2247db96d56Sopenharmony_ci    }
2257db96d56Sopenharmony_ci    else
2267db96d56Sopenharmony_ci        return Py_SIZE(op);
2277db96d56Sopenharmony_ci}
2287db96d56Sopenharmony_ci
2297db96d56Sopenharmony_cistatic inline int
2307db96d56Sopenharmony_civalid_index(Py_ssize_t i, Py_ssize_t limit)
2317db96d56Sopenharmony_ci{
2327db96d56Sopenharmony_ci    /* The cast to size_t lets us use just a single comparison
2337db96d56Sopenharmony_ci       to check whether i is in the range: 0 <= i < limit.
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_ci       See:  Section 14.2 "Bounds Checking" in the Agner Fog
2367db96d56Sopenharmony_ci       optimization manual found at:
2377db96d56Sopenharmony_ci       https://www.agner.org/optimize/optimizing_cpp.pdf
2387db96d56Sopenharmony_ci    */
2397db96d56Sopenharmony_ci    return (size_t) i < (size_t) limit;
2407db96d56Sopenharmony_ci}
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_ciPyObject *
2437db96d56Sopenharmony_ciPyList_GetItem(PyObject *op, Py_ssize_t i)
2447db96d56Sopenharmony_ci{
2457db96d56Sopenharmony_ci    if (!PyList_Check(op)) {
2467db96d56Sopenharmony_ci        PyErr_BadInternalCall();
2477db96d56Sopenharmony_ci        return NULL;
2487db96d56Sopenharmony_ci    }
2497db96d56Sopenharmony_ci    if (!valid_index(i, Py_SIZE(op))) {
2507db96d56Sopenharmony_ci        _Py_DECLARE_STR(list_err, "list index out of range");
2517db96d56Sopenharmony_ci        PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err));
2527db96d56Sopenharmony_ci        return NULL;
2537db96d56Sopenharmony_ci    }
2547db96d56Sopenharmony_ci    return ((PyListObject *)op) -> ob_item[i];
2557db96d56Sopenharmony_ci}
2567db96d56Sopenharmony_ci
2577db96d56Sopenharmony_ciint
2587db96d56Sopenharmony_ciPyList_SetItem(PyObject *op, Py_ssize_t i,
2597db96d56Sopenharmony_ci               PyObject *newitem)
2607db96d56Sopenharmony_ci{
2617db96d56Sopenharmony_ci    PyObject **p;
2627db96d56Sopenharmony_ci    if (!PyList_Check(op)) {
2637db96d56Sopenharmony_ci        Py_XDECREF(newitem);
2647db96d56Sopenharmony_ci        PyErr_BadInternalCall();
2657db96d56Sopenharmony_ci        return -1;
2667db96d56Sopenharmony_ci    }
2677db96d56Sopenharmony_ci    if (!valid_index(i, Py_SIZE(op))) {
2687db96d56Sopenharmony_ci        Py_XDECREF(newitem);
2697db96d56Sopenharmony_ci        PyErr_SetString(PyExc_IndexError,
2707db96d56Sopenharmony_ci                        "list assignment index out of range");
2717db96d56Sopenharmony_ci        return -1;
2727db96d56Sopenharmony_ci    }
2737db96d56Sopenharmony_ci    p = ((PyListObject *)op) -> ob_item + i;
2747db96d56Sopenharmony_ci    Py_XSETREF(*p, newitem);
2757db96d56Sopenharmony_ci    return 0;
2767db96d56Sopenharmony_ci}
2777db96d56Sopenharmony_ci
2787db96d56Sopenharmony_cistatic int
2797db96d56Sopenharmony_ciins1(PyListObject *self, Py_ssize_t where, PyObject *v)
2807db96d56Sopenharmony_ci{
2817db96d56Sopenharmony_ci    Py_ssize_t i, n = Py_SIZE(self);
2827db96d56Sopenharmony_ci    PyObject **items;
2837db96d56Sopenharmony_ci    if (v == NULL) {
2847db96d56Sopenharmony_ci        PyErr_BadInternalCall();
2857db96d56Sopenharmony_ci        return -1;
2867db96d56Sopenharmony_ci    }
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci    assert((size_t)n + 1 < PY_SSIZE_T_MAX);
2897db96d56Sopenharmony_ci    if (list_resize(self, n+1) < 0)
2907db96d56Sopenharmony_ci        return -1;
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ci    if (where < 0) {
2937db96d56Sopenharmony_ci        where += n;
2947db96d56Sopenharmony_ci        if (where < 0)
2957db96d56Sopenharmony_ci            where = 0;
2967db96d56Sopenharmony_ci    }
2977db96d56Sopenharmony_ci    if (where > n)
2987db96d56Sopenharmony_ci        where = n;
2997db96d56Sopenharmony_ci    items = self->ob_item;
3007db96d56Sopenharmony_ci    for (i = n; --i >= where; )
3017db96d56Sopenharmony_ci        items[i+1] = items[i];
3027db96d56Sopenharmony_ci    Py_INCREF(v);
3037db96d56Sopenharmony_ci    items[where] = v;
3047db96d56Sopenharmony_ci    return 0;
3057db96d56Sopenharmony_ci}
3067db96d56Sopenharmony_ci
3077db96d56Sopenharmony_ciint
3087db96d56Sopenharmony_ciPyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)
3097db96d56Sopenharmony_ci{
3107db96d56Sopenharmony_ci    if (!PyList_Check(op)) {
3117db96d56Sopenharmony_ci        PyErr_BadInternalCall();
3127db96d56Sopenharmony_ci        return -1;
3137db96d56Sopenharmony_ci    }
3147db96d56Sopenharmony_ci    return ins1((PyListObject *)op, where, newitem);
3157db96d56Sopenharmony_ci}
3167db96d56Sopenharmony_ci
3177db96d56Sopenharmony_ci/* internal, used by _PyList_AppendTakeRef */
3187db96d56Sopenharmony_ciint
3197db96d56Sopenharmony_ci_PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem)
3207db96d56Sopenharmony_ci{
3217db96d56Sopenharmony_ci    Py_ssize_t len = PyList_GET_SIZE(self);
3227db96d56Sopenharmony_ci    assert(self->allocated == -1 || self->allocated == len);
3237db96d56Sopenharmony_ci    if (list_resize(self, len + 1) < 0) {
3247db96d56Sopenharmony_ci        Py_DECREF(newitem);
3257db96d56Sopenharmony_ci        return -1;
3267db96d56Sopenharmony_ci    }
3277db96d56Sopenharmony_ci    PyList_SET_ITEM(self, len, newitem);
3287db96d56Sopenharmony_ci    return 0;
3297db96d56Sopenharmony_ci}
3307db96d56Sopenharmony_ci
3317db96d56Sopenharmony_ciint
3327db96d56Sopenharmony_ciPyList_Append(PyObject *op, PyObject *newitem)
3337db96d56Sopenharmony_ci{
3347db96d56Sopenharmony_ci    if (PyList_Check(op) && (newitem != NULL)) {
3357db96d56Sopenharmony_ci        Py_INCREF(newitem);
3367db96d56Sopenharmony_ci        return _PyList_AppendTakeRef((PyListObject *)op, newitem);
3377db96d56Sopenharmony_ci    }
3387db96d56Sopenharmony_ci    PyErr_BadInternalCall();
3397db96d56Sopenharmony_ci    return -1;
3407db96d56Sopenharmony_ci}
3417db96d56Sopenharmony_ci
3427db96d56Sopenharmony_ci/* Methods */
3437db96d56Sopenharmony_ci
3447db96d56Sopenharmony_cistatic void
3457db96d56Sopenharmony_cilist_dealloc(PyListObject *op)
3467db96d56Sopenharmony_ci{
3477db96d56Sopenharmony_ci    Py_ssize_t i;
3487db96d56Sopenharmony_ci    PyObject_GC_UnTrack(op);
3497db96d56Sopenharmony_ci    Py_TRASHCAN_BEGIN(op, list_dealloc)
3507db96d56Sopenharmony_ci    if (op->ob_item != NULL) {
3517db96d56Sopenharmony_ci        /* Do it backwards, for Christian Tismer.
3527db96d56Sopenharmony_ci           There's a simple test case where somehow this reduces
3537db96d56Sopenharmony_ci           thrashing when a *very* large list is created and
3547db96d56Sopenharmony_ci           immediately deleted. */
3557db96d56Sopenharmony_ci        i = Py_SIZE(op);
3567db96d56Sopenharmony_ci        while (--i >= 0) {
3577db96d56Sopenharmony_ci            Py_XDECREF(op->ob_item[i]);
3587db96d56Sopenharmony_ci        }
3597db96d56Sopenharmony_ci        PyMem_Free(op->ob_item);
3607db96d56Sopenharmony_ci    }
3617db96d56Sopenharmony_ci#if PyList_MAXFREELIST > 0
3627db96d56Sopenharmony_ci    struct _Py_list_state *state = get_list_state();
3637db96d56Sopenharmony_ci#ifdef Py_DEBUG
3647db96d56Sopenharmony_ci    // list_dealloc() must not be called after _PyList_Fini()
3657db96d56Sopenharmony_ci    assert(state->numfree != -1);
3667db96d56Sopenharmony_ci#endif
3677db96d56Sopenharmony_ci    if (state->numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) {
3687db96d56Sopenharmony_ci        state->free_list[state->numfree++] = op;
3697db96d56Sopenharmony_ci        OBJECT_STAT_INC(to_freelist);
3707db96d56Sopenharmony_ci    }
3717db96d56Sopenharmony_ci    else
3727db96d56Sopenharmony_ci#endif
3737db96d56Sopenharmony_ci    {
3747db96d56Sopenharmony_ci        Py_TYPE(op)->tp_free((PyObject *)op);
3757db96d56Sopenharmony_ci    }
3767db96d56Sopenharmony_ci    Py_TRASHCAN_END
3777db96d56Sopenharmony_ci}
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_cistatic PyObject *
3807db96d56Sopenharmony_cilist_repr(PyListObject *v)
3817db96d56Sopenharmony_ci{
3827db96d56Sopenharmony_ci    Py_ssize_t i;
3837db96d56Sopenharmony_ci    PyObject *s;
3847db96d56Sopenharmony_ci    _PyUnicodeWriter writer;
3857db96d56Sopenharmony_ci
3867db96d56Sopenharmony_ci    if (Py_SIZE(v) == 0) {
3877db96d56Sopenharmony_ci        return PyUnicode_FromString("[]");
3887db96d56Sopenharmony_ci    }
3897db96d56Sopenharmony_ci
3907db96d56Sopenharmony_ci    i = Py_ReprEnter((PyObject*)v);
3917db96d56Sopenharmony_ci    if (i != 0) {
3927db96d56Sopenharmony_ci        return i > 0 ? PyUnicode_FromString("[...]") : NULL;
3937db96d56Sopenharmony_ci    }
3947db96d56Sopenharmony_ci
3957db96d56Sopenharmony_ci    _PyUnicodeWriter_Init(&writer);
3967db96d56Sopenharmony_ci    writer.overallocate = 1;
3977db96d56Sopenharmony_ci    /* "[" + "1" + ", 2" * (len - 1) + "]" */
3987db96d56Sopenharmony_ci    writer.min_length = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1;
3997db96d56Sopenharmony_ci
4007db96d56Sopenharmony_ci    if (_PyUnicodeWriter_WriteChar(&writer, '[') < 0)
4017db96d56Sopenharmony_ci        goto error;
4027db96d56Sopenharmony_ci
4037db96d56Sopenharmony_ci    /* Do repr() on each element.  Note that this may mutate the list,
4047db96d56Sopenharmony_ci       so must refetch the list size on each iteration. */
4057db96d56Sopenharmony_ci    for (i = 0; i < Py_SIZE(v); ++i) {
4067db96d56Sopenharmony_ci        if (i > 0) {
4077db96d56Sopenharmony_ci            if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
4087db96d56Sopenharmony_ci                goto error;
4097db96d56Sopenharmony_ci        }
4107db96d56Sopenharmony_ci
4117db96d56Sopenharmony_ci        s = PyObject_Repr(v->ob_item[i]);
4127db96d56Sopenharmony_ci        if (s == NULL)
4137db96d56Sopenharmony_ci            goto error;
4147db96d56Sopenharmony_ci
4157db96d56Sopenharmony_ci        if (_PyUnicodeWriter_WriteStr(&writer, s) < 0) {
4167db96d56Sopenharmony_ci            Py_DECREF(s);
4177db96d56Sopenharmony_ci            goto error;
4187db96d56Sopenharmony_ci        }
4197db96d56Sopenharmony_ci        Py_DECREF(s);
4207db96d56Sopenharmony_ci    }
4217db96d56Sopenharmony_ci
4227db96d56Sopenharmony_ci    writer.overallocate = 0;
4237db96d56Sopenharmony_ci    if (_PyUnicodeWriter_WriteChar(&writer, ']') < 0)
4247db96d56Sopenharmony_ci        goto error;
4257db96d56Sopenharmony_ci
4267db96d56Sopenharmony_ci    Py_ReprLeave((PyObject *)v);
4277db96d56Sopenharmony_ci    return _PyUnicodeWriter_Finish(&writer);
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_cierror:
4307db96d56Sopenharmony_ci    _PyUnicodeWriter_Dealloc(&writer);
4317db96d56Sopenharmony_ci    Py_ReprLeave((PyObject *)v);
4327db96d56Sopenharmony_ci    return NULL;
4337db96d56Sopenharmony_ci}
4347db96d56Sopenharmony_ci
4357db96d56Sopenharmony_cistatic Py_ssize_t
4367db96d56Sopenharmony_cilist_length(PyListObject *a)
4377db96d56Sopenharmony_ci{
4387db96d56Sopenharmony_ci    return Py_SIZE(a);
4397db96d56Sopenharmony_ci}
4407db96d56Sopenharmony_ci
4417db96d56Sopenharmony_cistatic int
4427db96d56Sopenharmony_cilist_contains(PyListObject *a, PyObject *el)
4437db96d56Sopenharmony_ci{
4447db96d56Sopenharmony_ci    PyObject *item;
4457db96d56Sopenharmony_ci    Py_ssize_t i;
4467db96d56Sopenharmony_ci    int cmp;
4477db96d56Sopenharmony_ci
4487db96d56Sopenharmony_ci    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) {
4497db96d56Sopenharmony_ci        item = PyList_GET_ITEM(a, i);
4507db96d56Sopenharmony_ci        Py_INCREF(item);
4517db96d56Sopenharmony_ci        cmp = PyObject_RichCompareBool(item, el, Py_EQ);
4527db96d56Sopenharmony_ci        Py_DECREF(item);
4537db96d56Sopenharmony_ci    }
4547db96d56Sopenharmony_ci    return cmp;
4557db96d56Sopenharmony_ci}
4567db96d56Sopenharmony_ci
4577db96d56Sopenharmony_cistatic PyObject *
4587db96d56Sopenharmony_cilist_item(PyListObject *a, Py_ssize_t i)
4597db96d56Sopenharmony_ci{
4607db96d56Sopenharmony_ci    if (!valid_index(i, Py_SIZE(a))) {
4617db96d56Sopenharmony_ci        PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err));
4627db96d56Sopenharmony_ci        return NULL;
4637db96d56Sopenharmony_ci    }
4647db96d56Sopenharmony_ci    Py_INCREF(a->ob_item[i]);
4657db96d56Sopenharmony_ci    return a->ob_item[i];
4667db96d56Sopenharmony_ci}
4677db96d56Sopenharmony_ci
4687db96d56Sopenharmony_cistatic PyObject *
4697db96d56Sopenharmony_cilist_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
4707db96d56Sopenharmony_ci{
4717db96d56Sopenharmony_ci    PyListObject *np;
4727db96d56Sopenharmony_ci    PyObject **src, **dest;
4737db96d56Sopenharmony_ci    Py_ssize_t i, len;
4747db96d56Sopenharmony_ci    len = ihigh - ilow;
4757db96d56Sopenharmony_ci    if (len <= 0) {
4767db96d56Sopenharmony_ci        return PyList_New(0);
4777db96d56Sopenharmony_ci    }
4787db96d56Sopenharmony_ci    np = (PyListObject *) list_new_prealloc(len);
4797db96d56Sopenharmony_ci    if (np == NULL)
4807db96d56Sopenharmony_ci        return NULL;
4817db96d56Sopenharmony_ci
4827db96d56Sopenharmony_ci    src = a->ob_item + ilow;
4837db96d56Sopenharmony_ci    dest = np->ob_item;
4847db96d56Sopenharmony_ci    for (i = 0; i < len; i++) {
4857db96d56Sopenharmony_ci        PyObject *v = src[i];
4867db96d56Sopenharmony_ci        Py_INCREF(v);
4877db96d56Sopenharmony_ci        dest[i] = v;
4887db96d56Sopenharmony_ci    }
4897db96d56Sopenharmony_ci    Py_SET_SIZE(np, len);
4907db96d56Sopenharmony_ci    return (PyObject *)np;
4917db96d56Sopenharmony_ci}
4927db96d56Sopenharmony_ci
4937db96d56Sopenharmony_ciPyObject *
4947db96d56Sopenharmony_ciPyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
4957db96d56Sopenharmony_ci{
4967db96d56Sopenharmony_ci    if (!PyList_Check(a)) {
4977db96d56Sopenharmony_ci        PyErr_BadInternalCall();
4987db96d56Sopenharmony_ci        return NULL;
4997db96d56Sopenharmony_ci    }
5007db96d56Sopenharmony_ci    if (ilow < 0) {
5017db96d56Sopenharmony_ci        ilow = 0;
5027db96d56Sopenharmony_ci    }
5037db96d56Sopenharmony_ci    else if (ilow > Py_SIZE(a)) {
5047db96d56Sopenharmony_ci        ilow = Py_SIZE(a);
5057db96d56Sopenharmony_ci    }
5067db96d56Sopenharmony_ci    if (ihigh < ilow) {
5077db96d56Sopenharmony_ci        ihigh = ilow;
5087db96d56Sopenharmony_ci    }
5097db96d56Sopenharmony_ci    else if (ihigh > Py_SIZE(a)) {
5107db96d56Sopenharmony_ci        ihigh = Py_SIZE(a);
5117db96d56Sopenharmony_ci    }
5127db96d56Sopenharmony_ci    return list_slice((PyListObject *)a, ilow, ihigh);
5137db96d56Sopenharmony_ci}
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_cistatic PyObject *
5167db96d56Sopenharmony_cilist_concat(PyListObject *a, PyObject *bb)
5177db96d56Sopenharmony_ci{
5187db96d56Sopenharmony_ci    Py_ssize_t size;
5197db96d56Sopenharmony_ci    Py_ssize_t i;
5207db96d56Sopenharmony_ci    PyObject **src, **dest;
5217db96d56Sopenharmony_ci    PyListObject *np;
5227db96d56Sopenharmony_ci    if (!PyList_Check(bb)) {
5237db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
5247db96d56Sopenharmony_ci                  "can only concatenate list (not \"%.200s\") to list",
5257db96d56Sopenharmony_ci                  Py_TYPE(bb)->tp_name);
5267db96d56Sopenharmony_ci        return NULL;
5277db96d56Sopenharmony_ci    }
5287db96d56Sopenharmony_ci#define b ((PyListObject *)bb)
5297db96d56Sopenharmony_ci    assert((size_t)Py_SIZE(a) + (size_t)Py_SIZE(b) < PY_SSIZE_T_MAX);
5307db96d56Sopenharmony_ci    size = Py_SIZE(a) + Py_SIZE(b);
5317db96d56Sopenharmony_ci    if (size == 0) {
5327db96d56Sopenharmony_ci        return PyList_New(0);
5337db96d56Sopenharmony_ci    }
5347db96d56Sopenharmony_ci    np = (PyListObject *) list_new_prealloc(size);
5357db96d56Sopenharmony_ci    if (np == NULL) {
5367db96d56Sopenharmony_ci        return NULL;
5377db96d56Sopenharmony_ci    }
5387db96d56Sopenharmony_ci    src = a->ob_item;
5397db96d56Sopenharmony_ci    dest = np->ob_item;
5407db96d56Sopenharmony_ci    for (i = 0; i < Py_SIZE(a); i++) {
5417db96d56Sopenharmony_ci        PyObject *v = src[i];
5427db96d56Sopenharmony_ci        Py_INCREF(v);
5437db96d56Sopenharmony_ci        dest[i] = v;
5447db96d56Sopenharmony_ci    }
5457db96d56Sopenharmony_ci    src = b->ob_item;
5467db96d56Sopenharmony_ci    dest = np->ob_item + Py_SIZE(a);
5477db96d56Sopenharmony_ci    for (i = 0; i < Py_SIZE(b); i++) {
5487db96d56Sopenharmony_ci        PyObject *v = src[i];
5497db96d56Sopenharmony_ci        Py_INCREF(v);
5507db96d56Sopenharmony_ci        dest[i] = v;
5517db96d56Sopenharmony_ci    }
5527db96d56Sopenharmony_ci    Py_SET_SIZE(np, size);
5537db96d56Sopenharmony_ci    return (PyObject *)np;
5547db96d56Sopenharmony_ci#undef b
5557db96d56Sopenharmony_ci}
5567db96d56Sopenharmony_ci
5577db96d56Sopenharmony_cistatic PyObject *
5587db96d56Sopenharmony_cilist_repeat(PyListObject *a, Py_ssize_t n)
5597db96d56Sopenharmony_ci{
5607db96d56Sopenharmony_ci    Py_ssize_t size;
5617db96d56Sopenharmony_ci    PyListObject *np;
5627db96d56Sopenharmony_ci    if (n < 0)
5637db96d56Sopenharmony_ci        n = 0;
5647db96d56Sopenharmony_ci    if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n)
5657db96d56Sopenharmony_ci        return PyErr_NoMemory();
5667db96d56Sopenharmony_ci    size = Py_SIZE(a) * n;
5677db96d56Sopenharmony_ci    if (size == 0)
5687db96d56Sopenharmony_ci        return PyList_New(0);
5697db96d56Sopenharmony_ci    np = (PyListObject *) list_new_prealloc(size);
5707db96d56Sopenharmony_ci    if (np == NULL)
5717db96d56Sopenharmony_ci        return NULL;
5727db96d56Sopenharmony_ci    PyObject **dest = np->ob_item;
5737db96d56Sopenharmony_ci    PyObject **dest_end = dest + size;
5747db96d56Sopenharmony_ci    if (Py_SIZE(a) == 1) {
5757db96d56Sopenharmony_ci        PyObject *elem = a->ob_item[0];
5767db96d56Sopenharmony_ci        Py_SET_REFCNT(elem, Py_REFCNT(elem) + n);
5777db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG
5787db96d56Sopenharmony_ci        _Py_RefTotal += n;
5797db96d56Sopenharmony_ci#endif
5807db96d56Sopenharmony_ci        while (dest < dest_end) {
5817db96d56Sopenharmony_ci            *dest++ = elem;
5827db96d56Sopenharmony_ci        }
5837db96d56Sopenharmony_ci    }
5847db96d56Sopenharmony_ci    else {
5857db96d56Sopenharmony_ci        PyObject **src = a->ob_item;
5867db96d56Sopenharmony_ci        PyObject **src_end = src + Py_SIZE(a);
5877db96d56Sopenharmony_ci        while (src < src_end) {
5887db96d56Sopenharmony_ci            Py_SET_REFCNT(*src, Py_REFCNT(*src) + n);
5897db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG
5907db96d56Sopenharmony_ci            _Py_RefTotal += n;
5917db96d56Sopenharmony_ci#endif
5927db96d56Sopenharmony_ci            *dest++ = *src++;
5937db96d56Sopenharmony_ci        }
5947db96d56Sopenharmony_ci        // Now src chases after dest in the same buffer
5957db96d56Sopenharmony_ci        src = np->ob_item;
5967db96d56Sopenharmony_ci        while (dest < dest_end) {
5977db96d56Sopenharmony_ci            *dest++ = *src++;
5987db96d56Sopenharmony_ci        }
5997db96d56Sopenharmony_ci    }
6007db96d56Sopenharmony_ci    Py_SET_SIZE(np, size);
6017db96d56Sopenharmony_ci    return (PyObject *) np;
6027db96d56Sopenharmony_ci}
6037db96d56Sopenharmony_ci
6047db96d56Sopenharmony_cistatic int
6057db96d56Sopenharmony_ci_list_clear(PyListObject *a)
6067db96d56Sopenharmony_ci{
6077db96d56Sopenharmony_ci    Py_ssize_t i;
6087db96d56Sopenharmony_ci    PyObject **item = a->ob_item;
6097db96d56Sopenharmony_ci    if (item != NULL) {
6107db96d56Sopenharmony_ci        /* Because XDECREF can recursively invoke operations on
6117db96d56Sopenharmony_ci           this list, we make it empty first. */
6127db96d56Sopenharmony_ci        i = Py_SIZE(a);
6137db96d56Sopenharmony_ci        Py_SET_SIZE(a, 0);
6147db96d56Sopenharmony_ci        a->ob_item = NULL;
6157db96d56Sopenharmony_ci        a->allocated = 0;
6167db96d56Sopenharmony_ci        while (--i >= 0) {
6177db96d56Sopenharmony_ci            Py_XDECREF(item[i]);
6187db96d56Sopenharmony_ci        }
6197db96d56Sopenharmony_ci        PyMem_Free(item);
6207db96d56Sopenharmony_ci    }
6217db96d56Sopenharmony_ci    /* Never fails; the return value can be ignored.
6227db96d56Sopenharmony_ci       Note that there is no guarantee that the list is actually empty
6237db96d56Sopenharmony_ci       at this point, because XDECREF may have populated it again! */
6247db96d56Sopenharmony_ci    return 0;
6257db96d56Sopenharmony_ci}
6267db96d56Sopenharmony_ci
6277db96d56Sopenharmony_ci/* a[ilow:ihigh] = v if v != NULL.
6287db96d56Sopenharmony_ci * del a[ilow:ihigh] if v == NULL.
6297db96d56Sopenharmony_ci *
6307db96d56Sopenharmony_ci * Special speed gimmick:  when v is NULL and ihigh - ilow <= 8, it's
6317db96d56Sopenharmony_ci * guaranteed the call cannot fail.
6327db96d56Sopenharmony_ci */
6337db96d56Sopenharmony_cistatic int
6347db96d56Sopenharmony_cilist_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
6357db96d56Sopenharmony_ci{
6367db96d56Sopenharmony_ci    /* Because [X]DECREF can recursively invoke list operations on
6377db96d56Sopenharmony_ci       this list, we must postpone all [X]DECREF activity until
6387db96d56Sopenharmony_ci       after the list is back in its canonical shape.  Therefore
6397db96d56Sopenharmony_ci       we must allocate an additional array, 'recycle', into which
6407db96d56Sopenharmony_ci       we temporarily copy the items that are deleted from the
6417db96d56Sopenharmony_ci       list. :-( */
6427db96d56Sopenharmony_ci    PyObject *recycle_on_stack[8];
6437db96d56Sopenharmony_ci    PyObject **recycle = recycle_on_stack; /* will allocate more if needed */
6447db96d56Sopenharmony_ci    PyObject **item;
6457db96d56Sopenharmony_ci    PyObject **vitem = NULL;
6467db96d56Sopenharmony_ci    PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */
6477db96d56Sopenharmony_ci    Py_ssize_t n; /* # of elements in replacement list */
6487db96d56Sopenharmony_ci    Py_ssize_t norig; /* # of elements in list getting replaced */
6497db96d56Sopenharmony_ci    Py_ssize_t d; /* Change in size */
6507db96d56Sopenharmony_ci    Py_ssize_t k;
6517db96d56Sopenharmony_ci    size_t s;
6527db96d56Sopenharmony_ci    int result = -1;            /* guilty until proved innocent */
6537db96d56Sopenharmony_ci#define b ((PyListObject *)v)
6547db96d56Sopenharmony_ci    if (v == NULL)
6557db96d56Sopenharmony_ci        n = 0;
6567db96d56Sopenharmony_ci    else {
6577db96d56Sopenharmony_ci        if (a == b) {
6587db96d56Sopenharmony_ci            /* Special case "a[i:j] = a" -- copy b first */
6597db96d56Sopenharmony_ci            v = list_slice(b, 0, Py_SIZE(b));
6607db96d56Sopenharmony_ci            if (v == NULL)
6617db96d56Sopenharmony_ci                return result;
6627db96d56Sopenharmony_ci            result = list_ass_slice(a, ilow, ihigh, v);
6637db96d56Sopenharmony_ci            Py_DECREF(v);
6647db96d56Sopenharmony_ci            return result;
6657db96d56Sopenharmony_ci        }
6667db96d56Sopenharmony_ci        v_as_SF = PySequence_Fast(v, "can only assign an iterable");
6677db96d56Sopenharmony_ci        if(v_as_SF == NULL)
6687db96d56Sopenharmony_ci            goto Error;
6697db96d56Sopenharmony_ci        n = PySequence_Fast_GET_SIZE(v_as_SF);
6707db96d56Sopenharmony_ci        vitem = PySequence_Fast_ITEMS(v_as_SF);
6717db96d56Sopenharmony_ci    }
6727db96d56Sopenharmony_ci    if (ilow < 0)
6737db96d56Sopenharmony_ci        ilow = 0;
6747db96d56Sopenharmony_ci    else if (ilow > Py_SIZE(a))
6757db96d56Sopenharmony_ci        ilow = Py_SIZE(a);
6767db96d56Sopenharmony_ci
6777db96d56Sopenharmony_ci    if (ihigh < ilow)
6787db96d56Sopenharmony_ci        ihigh = ilow;
6797db96d56Sopenharmony_ci    else if (ihigh > Py_SIZE(a))
6807db96d56Sopenharmony_ci        ihigh = Py_SIZE(a);
6817db96d56Sopenharmony_ci
6827db96d56Sopenharmony_ci    norig = ihigh - ilow;
6837db96d56Sopenharmony_ci    assert(norig >= 0);
6847db96d56Sopenharmony_ci    d = n - norig;
6857db96d56Sopenharmony_ci    if (Py_SIZE(a) + d == 0) {
6867db96d56Sopenharmony_ci        Py_XDECREF(v_as_SF);
6877db96d56Sopenharmony_ci        return _list_clear(a);
6887db96d56Sopenharmony_ci    }
6897db96d56Sopenharmony_ci    item = a->ob_item;
6907db96d56Sopenharmony_ci    /* recycle the items that we are about to remove */
6917db96d56Sopenharmony_ci    s = norig * sizeof(PyObject *);
6927db96d56Sopenharmony_ci    /* If norig == 0, item might be NULL, in which case we may not memcpy from it. */
6937db96d56Sopenharmony_ci    if (s) {
6947db96d56Sopenharmony_ci        if (s > sizeof(recycle_on_stack)) {
6957db96d56Sopenharmony_ci            recycle = (PyObject **)PyMem_Malloc(s);
6967db96d56Sopenharmony_ci            if (recycle == NULL) {
6977db96d56Sopenharmony_ci                PyErr_NoMemory();
6987db96d56Sopenharmony_ci                goto Error;
6997db96d56Sopenharmony_ci            }
7007db96d56Sopenharmony_ci        }
7017db96d56Sopenharmony_ci        memcpy(recycle, &item[ilow], s);
7027db96d56Sopenharmony_ci    }
7037db96d56Sopenharmony_ci
7047db96d56Sopenharmony_ci    if (d < 0) { /* Delete -d items */
7057db96d56Sopenharmony_ci        Py_ssize_t tail;
7067db96d56Sopenharmony_ci        tail = (Py_SIZE(a) - ihigh) * sizeof(PyObject *);
7077db96d56Sopenharmony_ci        memmove(&item[ihigh+d], &item[ihigh], tail);
7087db96d56Sopenharmony_ci        if (list_resize(a, Py_SIZE(a) + d) < 0) {
7097db96d56Sopenharmony_ci            memmove(&item[ihigh], &item[ihigh+d], tail);
7107db96d56Sopenharmony_ci            memcpy(&item[ilow], recycle, s);
7117db96d56Sopenharmony_ci            goto Error;
7127db96d56Sopenharmony_ci        }
7137db96d56Sopenharmony_ci        item = a->ob_item;
7147db96d56Sopenharmony_ci    }
7157db96d56Sopenharmony_ci    else if (d > 0) { /* Insert d items */
7167db96d56Sopenharmony_ci        k = Py_SIZE(a);
7177db96d56Sopenharmony_ci        if (list_resize(a, k+d) < 0)
7187db96d56Sopenharmony_ci            goto Error;
7197db96d56Sopenharmony_ci        item = a->ob_item;
7207db96d56Sopenharmony_ci        memmove(&item[ihigh+d], &item[ihigh],
7217db96d56Sopenharmony_ci            (k - ihigh)*sizeof(PyObject *));
7227db96d56Sopenharmony_ci    }
7237db96d56Sopenharmony_ci    for (k = 0; k < n; k++, ilow++) {
7247db96d56Sopenharmony_ci        PyObject *w = vitem[k];
7257db96d56Sopenharmony_ci        Py_XINCREF(w);
7267db96d56Sopenharmony_ci        item[ilow] = w;
7277db96d56Sopenharmony_ci    }
7287db96d56Sopenharmony_ci    for (k = norig - 1; k >= 0; --k)
7297db96d56Sopenharmony_ci        Py_XDECREF(recycle[k]);
7307db96d56Sopenharmony_ci    result = 0;
7317db96d56Sopenharmony_ci Error:
7327db96d56Sopenharmony_ci    if (recycle != recycle_on_stack)
7337db96d56Sopenharmony_ci        PyMem_Free(recycle);
7347db96d56Sopenharmony_ci    Py_XDECREF(v_as_SF);
7357db96d56Sopenharmony_ci    return result;
7367db96d56Sopenharmony_ci#undef b
7377db96d56Sopenharmony_ci}
7387db96d56Sopenharmony_ci
7397db96d56Sopenharmony_ciint
7407db96d56Sopenharmony_ciPyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
7417db96d56Sopenharmony_ci{
7427db96d56Sopenharmony_ci    if (!PyList_Check(a)) {
7437db96d56Sopenharmony_ci        PyErr_BadInternalCall();
7447db96d56Sopenharmony_ci        return -1;
7457db96d56Sopenharmony_ci    }
7467db96d56Sopenharmony_ci    return list_ass_slice((PyListObject *)a, ilow, ihigh, v);
7477db96d56Sopenharmony_ci}
7487db96d56Sopenharmony_ci
7497db96d56Sopenharmony_cistatic PyObject *
7507db96d56Sopenharmony_cilist_inplace_repeat(PyListObject *self, Py_ssize_t n)
7517db96d56Sopenharmony_ci{
7527db96d56Sopenharmony_ci    PyObject **items;
7537db96d56Sopenharmony_ci    Py_ssize_t size, i, j, p;
7547db96d56Sopenharmony_ci
7557db96d56Sopenharmony_ci
7567db96d56Sopenharmony_ci    size = PyList_GET_SIZE(self);
7577db96d56Sopenharmony_ci    if (size == 0 || n == 1) {
7587db96d56Sopenharmony_ci        Py_INCREF(self);
7597db96d56Sopenharmony_ci        return (PyObject *)self;
7607db96d56Sopenharmony_ci    }
7617db96d56Sopenharmony_ci
7627db96d56Sopenharmony_ci    if (n < 1) {
7637db96d56Sopenharmony_ci        (void)_list_clear(self);
7647db96d56Sopenharmony_ci        Py_INCREF(self);
7657db96d56Sopenharmony_ci        return (PyObject *)self;
7667db96d56Sopenharmony_ci    }
7677db96d56Sopenharmony_ci
7687db96d56Sopenharmony_ci    if (size > PY_SSIZE_T_MAX / n) {
7697db96d56Sopenharmony_ci        return PyErr_NoMemory();
7707db96d56Sopenharmony_ci    }
7717db96d56Sopenharmony_ci
7727db96d56Sopenharmony_ci    if (list_resize(self, size*n) < 0)
7737db96d56Sopenharmony_ci        return NULL;
7747db96d56Sopenharmony_ci
7757db96d56Sopenharmony_ci    p = size;
7767db96d56Sopenharmony_ci    items = self->ob_item;
7777db96d56Sopenharmony_ci    for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */
7787db96d56Sopenharmony_ci        for (j = 0; j < size; j++) {
7797db96d56Sopenharmony_ci            PyObject *o = items[j];
7807db96d56Sopenharmony_ci            Py_INCREF(o);
7817db96d56Sopenharmony_ci            items[p++] = o;
7827db96d56Sopenharmony_ci        }
7837db96d56Sopenharmony_ci    }
7847db96d56Sopenharmony_ci    Py_INCREF(self);
7857db96d56Sopenharmony_ci    return (PyObject *)self;
7867db96d56Sopenharmony_ci}
7877db96d56Sopenharmony_ci
7887db96d56Sopenharmony_cistatic int
7897db96d56Sopenharmony_cilist_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v)
7907db96d56Sopenharmony_ci{
7917db96d56Sopenharmony_ci    if (!valid_index(i, Py_SIZE(a))) {
7927db96d56Sopenharmony_ci        PyErr_SetString(PyExc_IndexError,
7937db96d56Sopenharmony_ci                        "list assignment index out of range");
7947db96d56Sopenharmony_ci        return -1;
7957db96d56Sopenharmony_ci    }
7967db96d56Sopenharmony_ci    if (v == NULL)
7977db96d56Sopenharmony_ci        return list_ass_slice(a, i, i+1, v);
7987db96d56Sopenharmony_ci    Py_INCREF(v);
7997db96d56Sopenharmony_ci    Py_SETREF(a->ob_item[i], v);
8007db96d56Sopenharmony_ci    return 0;
8017db96d56Sopenharmony_ci}
8027db96d56Sopenharmony_ci
8037db96d56Sopenharmony_ci/*[clinic input]
8047db96d56Sopenharmony_cilist.insert
8057db96d56Sopenharmony_ci
8067db96d56Sopenharmony_ci    index: Py_ssize_t
8077db96d56Sopenharmony_ci    object: object
8087db96d56Sopenharmony_ci    /
8097db96d56Sopenharmony_ci
8107db96d56Sopenharmony_ciInsert object before index.
8117db96d56Sopenharmony_ci[clinic start generated code]*/
8127db96d56Sopenharmony_ci
8137db96d56Sopenharmony_cistatic PyObject *
8147db96d56Sopenharmony_cilist_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object)
8157db96d56Sopenharmony_ci/*[clinic end generated code: output=7f35e32f60c8cb78 input=858514cf894c7eab]*/
8167db96d56Sopenharmony_ci{
8177db96d56Sopenharmony_ci    if (ins1(self, index, object) == 0)
8187db96d56Sopenharmony_ci        Py_RETURN_NONE;
8197db96d56Sopenharmony_ci    return NULL;
8207db96d56Sopenharmony_ci}
8217db96d56Sopenharmony_ci
8227db96d56Sopenharmony_ci/*[clinic input]
8237db96d56Sopenharmony_cilist.clear
8247db96d56Sopenharmony_ci
8257db96d56Sopenharmony_ciRemove all items from list.
8267db96d56Sopenharmony_ci[clinic start generated code]*/
8277db96d56Sopenharmony_ci
8287db96d56Sopenharmony_cistatic PyObject *
8297db96d56Sopenharmony_cilist_clear_impl(PyListObject *self)
8307db96d56Sopenharmony_ci/*[clinic end generated code: output=67a1896c01f74362 input=ca3c1646856742f6]*/
8317db96d56Sopenharmony_ci{
8327db96d56Sopenharmony_ci    _list_clear(self);
8337db96d56Sopenharmony_ci    Py_RETURN_NONE;
8347db96d56Sopenharmony_ci}
8357db96d56Sopenharmony_ci
8367db96d56Sopenharmony_ci/*[clinic input]
8377db96d56Sopenharmony_cilist.copy
8387db96d56Sopenharmony_ci
8397db96d56Sopenharmony_ciReturn a shallow copy of the list.
8407db96d56Sopenharmony_ci[clinic start generated code]*/
8417db96d56Sopenharmony_ci
8427db96d56Sopenharmony_cistatic PyObject *
8437db96d56Sopenharmony_cilist_copy_impl(PyListObject *self)
8447db96d56Sopenharmony_ci/*[clinic end generated code: output=ec6b72d6209d418e input=6453ab159e84771f]*/
8457db96d56Sopenharmony_ci{
8467db96d56Sopenharmony_ci    return list_slice(self, 0, Py_SIZE(self));
8477db96d56Sopenharmony_ci}
8487db96d56Sopenharmony_ci
8497db96d56Sopenharmony_ci/*[clinic input]
8507db96d56Sopenharmony_cilist.append
8517db96d56Sopenharmony_ci
8527db96d56Sopenharmony_ci     object: object
8537db96d56Sopenharmony_ci     /
8547db96d56Sopenharmony_ci
8557db96d56Sopenharmony_ciAppend object to the end of the list.
8567db96d56Sopenharmony_ci[clinic start generated code]*/
8577db96d56Sopenharmony_ci
8587db96d56Sopenharmony_cistatic PyObject *
8597db96d56Sopenharmony_cilist_append(PyListObject *self, PyObject *object)
8607db96d56Sopenharmony_ci/*[clinic end generated code: output=7c096003a29c0eae input=43a3fe48a7066e91]*/
8617db96d56Sopenharmony_ci{
8627db96d56Sopenharmony_ci    if (_PyList_AppendTakeRef(self, Py_NewRef(object)) < 0) {
8637db96d56Sopenharmony_ci        return NULL;
8647db96d56Sopenharmony_ci    }
8657db96d56Sopenharmony_ci    Py_RETURN_NONE;
8667db96d56Sopenharmony_ci}
8677db96d56Sopenharmony_ci
8687db96d56Sopenharmony_ci/*[clinic input]
8697db96d56Sopenharmony_cilist.extend
8707db96d56Sopenharmony_ci
8717db96d56Sopenharmony_ci     iterable: object
8727db96d56Sopenharmony_ci     /
8737db96d56Sopenharmony_ci
8747db96d56Sopenharmony_ciExtend list by appending elements from the iterable.
8757db96d56Sopenharmony_ci[clinic start generated code]*/
8767db96d56Sopenharmony_ci
8777db96d56Sopenharmony_cistatic PyObject *
8787db96d56Sopenharmony_cilist_extend(PyListObject *self, PyObject *iterable)
8797db96d56Sopenharmony_ci/*[clinic end generated code: output=630fb3bca0c8e789 input=9ec5ba3a81be3a4d]*/
8807db96d56Sopenharmony_ci{
8817db96d56Sopenharmony_ci    PyObject *it;      /* iter(v) */
8827db96d56Sopenharmony_ci    Py_ssize_t m;                  /* size of self */
8837db96d56Sopenharmony_ci    Py_ssize_t n;                  /* guess for size of iterable */
8847db96d56Sopenharmony_ci    Py_ssize_t i;
8857db96d56Sopenharmony_ci    PyObject *(*iternext)(PyObject *);
8867db96d56Sopenharmony_ci
8877db96d56Sopenharmony_ci    /* Special cases:
8887db96d56Sopenharmony_ci       1) lists and tuples which can use PySequence_Fast ops
8897db96d56Sopenharmony_ci       2) extending self to self requires making a copy first
8907db96d56Sopenharmony_ci    */
8917db96d56Sopenharmony_ci    if (PyList_CheckExact(iterable) || PyTuple_CheckExact(iterable) ||
8927db96d56Sopenharmony_ci                (PyObject *)self == iterable) {
8937db96d56Sopenharmony_ci        PyObject **src, **dest;
8947db96d56Sopenharmony_ci        iterable = PySequence_Fast(iterable, "argument must be iterable");
8957db96d56Sopenharmony_ci        if (!iterable)
8967db96d56Sopenharmony_ci            return NULL;
8977db96d56Sopenharmony_ci        n = PySequence_Fast_GET_SIZE(iterable);
8987db96d56Sopenharmony_ci        if (n == 0) {
8997db96d56Sopenharmony_ci            /* short circuit when iterable is empty */
9007db96d56Sopenharmony_ci            Py_DECREF(iterable);
9017db96d56Sopenharmony_ci            Py_RETURN_NONE;
9027db96d56Sopenharmony_ci        }
9037db96d56Sopenharmony_ci        m = Py_SIZE(self);
9047db96d56Sopenharmony_ci        /* It should not be possible to allocate a list large enough to cause
9057db96d56Sopenharmony_ci        an overflow on any relevant platform */
9067db96d56Sopenharmony_ci        assert(m < PY_SSIZE_T_MAX - n);
9077db96d56Sopenharmony_ci        if (self->ob_item == NULL) {
9087db96d56Sopenharmony_ci            if (list_preallocate_exact(self, n) < 0) {
9097db96d56Sopenharmony_ci                return NULL;
9107db96d56Sopenharmony_ci            }
9117db96d56Sopenharmony_ci            Py_SET_SIZE(self, n);
9127db96d56Sopenharmony_ci        }
9137db96d56Sopenharmony_ci        else if (list_resize(self, m + n) < 0) {
9147db96d56Sopenharmony_ci            Py_DECREF(iterable);
9157db96d56Sopenharmony_ci            return NULL;
9167db96d56Sopenharmony_ci        }
9177db96d56Sopenharmony_ci        /* note that we may still have self == iterable here for the
9187db96d56Sopenharmony_ci         * situation a.extend(a), but the following code works
9197db96d56Sopenharmony_ci         * in that case too.  Just make sure to resize self
9207db96d56Sopenharmony_ci         * before calling PySequence_Fast_ITEMS.
9217db96d56Sopenharmony_ci         */
9227db96d56Sopenharmony_ci        /* populate the end of self with iterable's items */
9237db96d56Sopenharmony_ci        src = PySequence_Fast_ITEMS(iterable);
9247db96d56Sopenharmony_ci        dest = self->ob_item + m;
9257db96d56Sopenharmony_ci        for (i = 0; i < n; i++) {
9267db96d56Sopenharmony_ci            PyObject *o = src[i];
9277db96d56Sopenharmony_ci            Py_INCREF(o);
9287db96d56Sopenharmony_ci            dest[i] = o;
9297db96d56Sopenharmony_ci        }
9307db96d56Sopenharmony_ci        Py_DECREF(iterable);
9317db96d56Sopenharmony_ci        Py_RETURN_NONE;
9327db96d56Sopenharmony_ci    }
9337db96d56Sopenharmony_ci
9347db96d56Sopenharmony_ci    it = PyObject_GetIter(iterable);
9357db96d56Sopenharmony_ci    if (it == NULL)
9367db96d56Sopenharmony_ci        return NULL;
9377db96d56Sopenharmony_ci    iternext = *Py_TYPE(it)->tp_iternext;
9387db96d56Sopenharmony_ci
9397db96d56Sopenharmony_ci    /* Guess a result list size. */
9407db96d56Sopenharmony_ci    n = PyObject_LengthHint(iterable, 8);
9417db96d56Sopenharmony_ci    if (n < 0) {
9427db96d56Sopenharmony_ci        Py_DECREF(it);
9437db96d56Sopenharmony_ci        return NULL;
9447db96d56Sopenharmony_ci    }
9457db96d56Sopenharmony_ci    m = Py_SIZE(self);
9467db96d56Sopenharmony_ci    if (m > PY_SSIZE_T_MAX - n) {
9477db96d56Sopenharmony_ci        /* m + n overflowed; on the chance that n lied, and there really
9487db96d56Sopenharmony_ci         * is enough room, ignore it.  If n was telling the truth, we'll
9497db96d56Sopenharmony_ci         * eventually run out of memory during the loop.
9507db96d56Sopenharmony_ci         */
9517db96d56Sopenharmony_ci    }
9527db96d56Sopenharmony_ci    else if (self->ob_item == NULL) {
9537db96d56Sopenharmony_ci        if (n && list_preallocate_exact(self, n) < 0)
9547db96d56Sopenharmony_ci            goto error;
9557db96d56Sopenharmony_ci    }
9567db96d56Sopenharmony_ci    else {
9577db96d56Sopenharmony_ci        /* Make room. */
9587db96d56Sopenharmony_ci        if (list_resize(self, m + n) < 0)
9597db96d56Sopenharmony_ci            goto error;
9607db96d56Sopenharmony_ci        /* Make the list sane again. */
9617db96d56Sopenharmony_ci        Py_SET_SIZE(self, m);
9627db96d56Sopenharmony_ci    }
9637db96d56Sopenharmony_ci
9647db96d56Sopenharmony_ci    /* Run iterator to exhaustion. */
9657db96d56Sopenharmony_ci    for (;;) {
9667db96d56Sopenharmony_ci        PyObject *item = iternext(it);
9677db96d56Sopenharmony_ci        if (item == NULL) {
9687db96d56Sopenharmony_ci            if (PyErr_Occurred()) {
9697db96d56Sopenharmony_ci                if (PyErr_ExceptionMatches(PyExc_StopIteration))
9707db96d56Sopenharmony_ci                    PyErr_Clear();
9717db96d56Sopenharmony_ci                else
9727db96d56Sopenharmony_ci                    goto error;
9737db96d56Sopenharmony_ci            }
9747db96d56Sopenharmony_ci            break;
9757db96d56Sopenharmony_ci        }
9767db96d56Sopenharmony_ci        if (Py_SIZE(self) < self->allocated) {
9777db96d56Sopenharmony_ci            /* steals ref */
9787db96d56Sopenharmony_ci            PyList_SET_ITEM(self, Py_SIZE(self), item);
9797db96d56Sopenharmony_ci            Py_SET_SIZE(self, Py_SIZE(self) + 1);
9807db96d56Sopenharmony_ci        }
9817db96d56Sopenharmony_ci        else {
9827db96d56Sopenharmony_ci            if (_PyList_AppendTakeRef(self, item) < 0)
9837db96d56Sopenharmony_ci                goto error;
9847db96d56Sopenharmony_ci        }
9857db96d56Sopenharmony_ci    }
9867db96d56Sopenharmony_ci
9877db96d56Sopenharmony_ci    /* Cut back result list if initial guess was too large. */
9887db96d56Sopenharmony_ci    if (Py_SIZE(self) < self->allocated) {
9897db96d56Sopenharmony_ci        if (list_resize(self, Py_SIZE(self)) < 0)
9907db96d56Sopenharmony_ci            goto error;
9917db96d56Sopenharmony_ci    }
9927db96d56Sopenharmony_ci
9937db96d56Sopenharmony_ci    Py_DECREF(it);
9947db96d56Sopenharmony_ci    Py_RETURN_NONE;
9957db96d56Sopenharmony_ci
9967db96d56Sopenharmony_ci  error:
9977db96d56Sopenharmony_ci    Py_DECREF(it);
9987db96d56Sopenharmony_ci    return NULL;
9997db96d56Sopenharmony_ci}
10007db96d56Sopenharmony_ci
10017db96d56Sopenharmony_ciPyObject *
10027db96d56Sopenharmony_ci_PyList_Extend(PyListObject *self, PyObject *iterable)
10037db96d56Sopenharmony_ci{
10047db96d56Sopenharmony_ci    return list_extend(self, iterable);
10057db96d56Sopenharmony_ci}
10067db96d56Sopenharmony_ci
10077db96d56Sopenharmony_cistatic PyObject *
10087db96d56Sopenharmony_cilist_inplace_concat(PyListObject *self, PyObject *other)
10097db96d56Sopenharmony_ci{
10107db96d56Sopenharmony_ci    PyObject *result;
10117db96d56Sopenharmony_ci
10127db96d56Sopenharmony_ci    result = list_extend(self, other);
10137db96d56Sopenharmony_ci    if (result == NULL)
10147db96d56Sopenharmony_ci        return result;
10157db96d56Sopenharmony_ci    Py_DECREF(result);
10167db96d56Sopenharmony_ci    Py_INCREF(self);
10177db96d56Sopenharmony_ci    return (PyObject *)self;
10187db96d56Sopenharmony_ci}
10197db96d56Sopenharmony_ci
10207db96d56Sopenharmony_ci/*[clinic input]
10217db96d56Sopenharmony_cilist.pop
10227db96d56Sopenharmony_ci
10237db96d56Sopenharmony_ci    index: Py_ssize_t = -1
10247db96d56Sopenharmony_ci    /
10257db96d56Sopenharmony_ci
10267db96d56Sopenharmony_ciRemove and return item at index (default last).
10277db96d56Sopenharmony_ci
10287db96d56Sopenharmony_ciRaises IndexError if list is empty or index is out of range.
10297db96d56Sopenharmony_ci[clinic start generated code]*/
10307db96d56Sopenharmony_ci
10317db96d56Sopenharmony_cistatic PyObject *
10327db96d56Sopenharmony_cilist_pop_impl(PyListObject *self, Py_ssize_t index)
10337db96d56Sopenharmony_ci/*[clinic end generated code: output=6bd69dcb3f17eca8 input=b83675976f329e6f]*/
10347db96d56Sopenharmony_ci{
10357db96d56Sopenharmony_ci    PyObject *v;
10367db96d56Sopenharmony_ci    int status;
10377db96d56Sopenharmony_ci
10387db96d56Sopenharmony_ci    if (Py_SIZE(self) == 0) {
10397db96d56Sopenharmony_ci        /* Special-case most common failure cause */
10407db96d56Sopenharmony_ci        PyErr_SetString(PyExc_IndexError, "pop from empty list");
10417db96d56Sopenharmony_ci        return NULL;
10427db96d56Sopenharmony_ci    }
10437db96d56Sopenharmony_ci    if (index < 0)
10447db96d56Sopenharmony_ci        index += Py_SIZE(self);
10457db96d56Sopenharmony_ci    if (!valid_index(index, Py_SIZE(self))) {
10467db96d56Sopenharmony_ci        PyErr_SetString(PyExc_IndexError, "pop index out of range");
10477db96d56Sopenharmony_ci        return NULL;
10487db96d56Sopenharmony_ci    }
10497db96d56Sopenharmony_ci    v = self->ob_item[index];
10507db96d56Sopenharmony_ci    if (index == Py_SIZE(self) - 1) {
10517db96d56Sopenharmony_ci        status = list_resize(self, Py_SIZE(self) - 1);
10527db96d56Sopenharmony_ci        if (status >= 0)
10537db96d56Sopenharmony_ci            return v; /* and v now owns the reference the list had */
10547db96d56Sopenharmony_ci        else
10557db96d56Sopenharmony_ci            return NULL;
10567db96d56Sopenharmony_ci    }
10577db96d56Sopenharmony_ci    Py_INCREF(v);
10587db96d56Sopenharmony_ci    status = list_ass_slice(self, index, index+1, (PyObject *)NULL);
10597db96d56Sopenharmony_ci    if (status < 0) {
10607db96d56Sopenharmony_ci        Py_DECREF(v);
10617db96d56Sopenharmony_ci        return NULL;
10627db96d56Sopenharmony_ci    }
10637db96d56Sopenharmony_ci    return v;
10647db96d56Sopenharmony_ci}
10657db96d56Sopenharmony_ci
10667db96d56Sopenharmony_ci/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */
10677db96d56Sopenharmony_cistatic void
10687db96d56Sopenharmony_cireverse_slice(PyObject **lo, PyObject **hi)
10697db96d56Sopenharmony_ci{
10707db96d56Sopenharmony_ci    assert(lo && hi);
10717db96d56Sopenharmony_ci
10727db96d56Sopenharmony_ci    --hi;
10737db96d56Sopenharmony_ci    while (lo < hi) {
10747db96d56Sopenharmony_ci        PyObject *t = *lo;
10757db96d56Sopenharmony_ci        *lo = *hi;
10767db96d56Sopenharmony_ci        *hi = t;
10777db96d56Sopenharmony_ci        ++lo;
10787db96d56Sopenharmony_ci        --hi;
10797db96d56Sopenharmony_ci    }
10807db96d56Sopenharmony_ci}
10817db96d56Sopenharmony_ci
10827db96d56Sopenharmony_ci/* Lots of code for an adaptive, stable, natural mergesort.  There are many
10837db96d56Sopenharmony_ci * pieces to this algorithm; read listsort.txt for overviews and details.
10847db96d56Sopenharmony_ci */
10857db96d56Sopenharmony_ci
10867db96d56Sopenharmony_ci/* A sortslice contains a pointer to an array of keys and a pointer to
10877db96d56Sopenharmony_ci * an array of corresponding values.  In other words, keys[i]
10887db96d56Sopenharmony_ci * corresponds with values[i].  If values == NULL, then the keys are
10897db96d56Sopenharmony_ci * also the values.
10907db96d56Sopenharmony_ci *
10917db96d56Sopenharmony_ci * Several convenience routines are provided here, so that keys and
10927db96d56Sopenharmony_ci * values are always moved in sync.
10937db96d56Sopenharmony_ci */
10947db96d56Sopenharmony_ci
10957db96d56Sopenharmony_citypedef struct {
10967db96d56Sopenharmony_ci    PyObject **keys;
10977db96d56Sopenharmony_ci    PyObject **values;
10987db96d56Sopenharmony_ci} sortslice;
10997db96d56Sopenharmony_ci
11007db96d56Sopenharmony_ciPy_LOCAL_INLINE(void)
11017db96d56Sopenharmony_cisortslice_copy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j)
11027db96d56Sopenharmony_ci{
11037db96d56Sopenharmony_ci    s1->keys[i] = s2->keys[j];
11047db96d56Sopenharmony_ci    if (s1->values != NULL)
11057db96d56Sopenharmony_ci        s1->values[i] = s2->values[j];
11067db96d56Sopenharmony_ci}
11077db96d56Sopenharmony_ci
11087db96d56Sopenharmony_ciPy_LOCAL_INLINE(void)
11097db96d56Sopenharmony_cisortslice_copy_incr(sortslice *dst, sortslice *src)
11107db96d56Sopenharmony_ci{
11117db96d56Sopenharmony_ci    *dst->keys++ = *src->keys++;
11127db96d56Sopenharmony_ci    if (dst->values != NULL)
11137db96d56Sopenharmony_ci        *dst->values++ = *src->values++;
11147db96d56Sopenharmony_ci}
11157db96d56Sopenharmony_ci
11167db96d56Sopenharmony_ciPy_LOCAL_INLINE(void)
11177db96d56Sopenharmony_cisortslice_copy_decr(sortslice *dst, sortslice *src)
11187db96d56Sopenharmony_ci{
11197db96d56Sopenharmony_ci    *dst->keys-- = *src->keys--;
11207db96d56Sopenharmony_ci    if (dst->values != NULL)
11217db96d56Sopenharmony_ci        *dst->values-- = *src->values--;
11227db96d56Sopenharmony_ci}
11237db96d56Sopenharmony_ci
11247db96d56Sopenharmony_ci
11257db96d56Sopenharmony_ciPy_LOCAL_INLINE(void)
11267db96d56Sopenharmony_cisortslice_memcpy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j,
11277db96d56Sopenharmony_ci                 Py_ssize_t n)
11287db96d56Sopenharmony_ci{
11297db96d56Sopenharmony_ci    memcpy(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n);
11307db96d56Sopenharmony_ci    if (s1->values != NULL)
11317db96d56Sopenharmony_ci        memcpy(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n);
11327db96d56Sopenharmony_ci}
11337db96d56Sopenharmony_ci
11347db96d56Sopenharmony_ciPy_LOCAL_INLINE(void)
11357db96d56Sopenharmony_cisortslice_memmove(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j,
11367db96d56Sopenharmony_ci                  Py_ssize_t n)
11377db96d56Sopenharmony_ci{
11387db96d56Sopenharmony_ci    memmove(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n);
11397db96d56Sopenharmony_ci    if (s1->values != NULL)
11407db96d56Sopenharmony_ci        memmove(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n);
11417db96d56Sopenharmony_ci}
11427db96d56Sopenharmony_ci
11437db96d56Sopenharmony_ciPy_LOCAL_INLINE(void)
11447db96d56Sopenharmony_cisortslice_advance(sortslice *slice, Py_ssize_t n)
11457db96d56Sopenharmony_ci{
11467db96d56Sopenharmony_ci    slice->keys += n;
11477db96d56Sopenharmony_ci    if (slice->values != NULL)
11487db96d56Sopenharmony_ci        slice->values += n;
11497db96d56Sopenharmony_ci}
11507db96d56Sopenharmony_ci
11517db96d56Sopenharmony_ci/* Comparison function: ms->key_compare, which is set at run-time in
11527db96d56Sopenharmony_ci * listsort_impl to optimize for various special cases.
11537db96d56Sopenharmony_ci * Returns -1 on error, 1 if x < y, 0 if x >= y.
11547db96d56Sopenharmony_ci */
11557db96d56Sopenharmony_ci
11567db96d56Sopenharmony_ci#define ISLT(X, Y) (*(ms->key_compare))(X, Y, ms)
11577db96d56Sopenharmony_ci
11587db96d56Sopenharmony_ci/* Compare X to Y via "<".  Goto "fail" if the comparison raises an
11597db96d56Sopenharmony_ci   error.  Else "k" is set to true iff X<Y, and an "if (k)" block is
11607db96d56Sopenharmony_ci   started.  It makes more sense in context <wink>.  X and Y are PyObject*s.
11617db96d56Sopenharmony_ci*/
11627db96d56Sopenharmony_ci#define IFLT(X, Y) if ((k = ISLT(X, Y)) < 0) goto fail;  \
11637db96d56Sopenharmony_ci           if (k)
11647db96d56Sopenharmony_ci
11657db96d56Sopenharmony_ci/* The maximum number of entries in a MergeState's pending-runs stack.
11667db96d56Sopenharmony_ci * For a list with n elements, this needs at most floor(log2(n)) + 1 entries
11677db96d56Sopenharmony_ci * even if we didn't force runs to a minimal length.  So the number of bits
11687db96d56Sopenharmony_ci * in a Py_ssize_t is plenty large enough for all cases.
11697db96d56Sopenharmony_ci */
11707db96d56Sopenharmony_ci#define MAX_MERGE_PENDING (SIZEOF_SIZE_T * 8)
11717db96d56Sopenharmony_ci
11727db96d56Sopenharmony_ci/* When we get into galloping mode, we stay there until both runs win less
11737db96d56Sopenharmony_ci * often than MIN_GALLOP consecutive times.  See listsort.txt for more info.
11747db96d56Sopenharmony_ci */
11757db96d56Sopenharmony_ci#define MIN_GALLOP 7
11767db96d56Sopenharmony_ci
11777db96d56Sopenharmony_ci/* Avoid malloc for small temp arrays. */
11787db96d56Sopenharmony_ci#define MERGESTATE_TEMP_SIZE 256
11797db96d56Sopenharmony_ci
11807db96d56Sopenharmony_ci/* One MergeState exists on the stack per invocation of mergesort.  It's just
11817db96d56Sopenharmony_ci * a convenient way to pass state around among the helper functions.
11827db96d56Sopenharmony_ci */
11837db96d56Sopenharmony_cistruct s_slice {
11847db96d56Sopenharmony_ci    sortslice base;
11857db96d56Sopenharmony_ci    Py_ssize_t len;   /* length of run */
11867db96d56Sopenharmony_ci    int power; /* node "level" for powersort merge strategy */
11877db96d56Sopenharmony_ci};
11887db96d56Sopenharmony_ci
11897db96d56Sopenharmony_citypedef struct s_MergeState MergeState;
11907db96d56Sopenharmony_cistruct s_MergeState {
11917db96d56Sopenharmony_ci    /* This controls when we get *into* galloping mode.  It's initialized
11927db96d56Sopenharmony_ci     * to MIN_GALLOP.  merge_lo and merge_hi tend to nudge it higher for
11937db96d56Sopenharmony_ci     * random data, and lower for highly structured data.
11947db96d56Sopenharmony_ci     */
11957db96d56Sopenharmony_ci    Py_ssize_t min_gallop;
11967db96d56Sopenharmony_ci
11977db96d56Sopenharmony_ci    Py_ssize_t listlen;     /* len(input_list) - read only */
11987db96d56Sopenharmony_ci    PyObject **basekeys;    /* base address of keys array - read only */
11997db96d56Sopenharmony_ci
12007db96d56Sopenharmony_ci    /* 'a' is temp storage to help with merges.  It contains room for
12017db96d56Sopenharmony_ci     * alloced entries.
12027db96d56Sopenharmony_ci     */
12037db96d56Sopenharmony_ci    sortslice a;        /* may point to temparray below */
12047db96d56Sopenharmony_ci    Py_ssize_t alloced;
12057db96d56Sopenharmony_ci
12067db96d56Sopenharmony_ci    /* A stack of n pending runs yet to be merged.  Run #i starts at
12077db96d56Sopenharmony_ci     * address base[i] and extends for len[i] elements.  It's always
12087db96d56Sopenharmony_ci     * true (so long as the indices are in bounds) that
12097db96d56Sopenharmony_ci     *
12107db96d56Sopenharmony_ci     *     pending[i].base + pending[i].len == pending[i+1].base
12117db96d56Sopenharmony_ci     *
12127db96d56Sopenharmony_ci     * so we could cut the storage for this, but it's a minor amount,
12137db96d56Sopenharmony_ci     * and keeping all the info explicit simplifies the code.
12147db96d56Sopenharmony_ci     */
12157db96d56Sopenharmony_ci    int n;
12167db96d56Sopenharmony_ci    struct s_slice pending[MAX_MERGE_PENDING];
12177db96d56Sopenharmony_ci
12187db96d56Sopenharmony_ci    /* 'a' points to this when possible, rather than muck with malloc. */
12197db96d56Sopenharmony_ci    PyObject *temparray[MERGESTATE_TEMP_SIZE];
12207db96d56Sopenharmony_ci
12217db96d56Sopenharmony_ci    /* This is the function we will use to compare two keys,
12227db96d56Sopenharmony_ci     * even when none of our special cases apply and we have to use
12237db96d56Sopenharmony_ci     * safe_object_compare. */
12247db96d56Sopenharmony_ci    int (*key_compare)(PyObject *, PyObject *, MergeState *);
12257db96d56Sopenharmony_ci
12267db96d56Sopenharmony_ci    /* This function is used by unsafe_object_compare to optimize comparisons
12277db96d56Sopenharmony_ci     * when we know our list is type-homogeneous but we can't assume anything else.
12287db96d56Sopenharmony_ci     * In the pre-sort check it is set equal to Py_TYPE(key)->tp_richcompare */
12297db96d56Sopenharmony_ci    PyObject *(*key_richcompare)(PyObject *, PyObject *, int);
12307db96d56Sopenharmony_ci
12317db96d56Sopenharmony_ci    /* This function is used by unsafe_tuple_compare to compare the first elements
12327db96d56Sopenharmony_ci     * of tuples. It may be set to safe_object_compare, but the idea is that hopefully
12337db96d56Sopenharmony_ci     * we can assume more, and use one of the special-case compares. */
12347db96d56Sopenharmony_ci    int (*tuple_elem_compare)(PyObject *, PyObject *, MergeState *);
12357db96d56Sopenharmony_ci};
12367db96d56Sopenharmony_ci
12377db96d56Sopenharmony_ci/* binarysort is the best method for sorting small arrays: it does
12387db96d56Sopenharmony_ci   few compares, but can do data movement quadratic in the number of
12397db96d56Sopenharmony_ci   elements.
12407db96d56Sopenharmony_ci   [lo, hi) is a contiguous slice of a list, and is sorted via
12417db96d56Sopenharmony_ci   binary insertion.  This sort is stable.
12427db96d56Sopenharmony_ci   On entry, must have lo <= start <= hi, and that [lo, start) is already
12437db96d56Sopenharmony_ci   sorted (pass start == lo if you don't know!).
12447db96d56Sopenharmony_ci   If islt() complains return -1, else 0.
12457db96d56Sopenharmony_ci   Even in case of error, the output slice will be some permutation of
12467db96d56Sopenharmony_ci   the input (nothing is lost or duplicated).
12477db96d56Sopenharmony_ci*/
12487db96d56Sopenharmony_cistatic int
12497db96d56Sopenharmony_cibinarysort(MergeState *ms, sortslice lo, PyObject **hi, PyObject **start)
12507db96d56Sopenharmony_ci{
12517db96d56Sopenharmony_ci    Py_ssize_t k;
12527db96d56Sopenharmony_ci    PyObject **l, **p, **r;
12537db96d56Sopenharmony_ci    PyObject *pivot;
12547db96d56Sopenharmony_ci
12557db96d56Sopenharmony_ci    assert(lo.keys <= start && start <= hi);
12567db96d56Sopenharmony_ci    /* assert [lo, start) is sorted */
12577db96d56Sopenharmony_ci    if (lo.keys == start)
12587db96d56Sopenharmony_ci        ++start;
12597db96d56Sopenharmony_ci    for (; start < hi; ++start) {
12607db96d56Sopenharmony_ci        /* set l to where *start belongs */
12617db96d56Sopenharmony_ci        l = lo.keys;
12627db96d56Sopenharmony_ci        r = start;
12637db96d56Sopenharmony_ci        pivot = *r;
12647db96d56Sopenharmony_ci        /* Invariants:
12657db96d56Sopenharmony_ci         * pivot >= all in [lo, l).
12667db96d56Sopenharmony_ci         * pivot  < all in [r, start).
12677db96d56Sopenharmony_ci         * The second is vacuously true at the start.
12687db96d56Sopenharmony_ci         */
12697db96d56Sopenharmony_ci        assert(l < r);
12707db96d56Sopenharmony_ci        do {
12717db96d56Sopenharmony_ci            p = l + ((r - l) >> 1);
12727db96d56Sopenharmony_ci            IFLT(pivot, *p)
12737db96d56Sopenharmony_ci                r = p;
12747db96d56Sopenharmony_ci            else
12757db96d56Sopenharmony_ci                l = p+1;
12767db96d56Sopenharmony_ci        } while (l < r);
12777db96d56Sopenharmony_ci        assert(l == r);
12787db96d56Sopenharmony_ci        /* The invariants still hold, so pivot >= all in [lo, l) and
12797db96d56Sopenharmony_ci           pivot < all in [l, start), so pivot belongs at l.  Note
12807db96d56Sopenharmony_ci           that if there are elements equal to pivot, l points to the
12817db96d56Sopenharmony_ci           first slot after them -- that's why this sort is stable.
12827db96d56Sopenharmony_ci           Slide over to make room.
12837db96d56Sopenharmony_ci           Caution: using memmove is much slower under MSVC 5;
12847db96d56Sopenharmony_ci           we're not usually moving many slots. */
12857db96d56Sopenharmony_ci        for (p = start; p > l; --p)
12867db96d56Sopenharmony_ci            *p = *(p-1);
12877db96d56Sopenharmony_ci        *l = pivot;
12887db96d56Sopenharmony_ci        if (lo.values != NULL) {
12897db96d56Sopenharmony_ci            Py_ssize_t offset = lo.values - lo.keys;
12907db96d56Sopenharmony_ci            p = start + offset;
12917db96d56Sopenharmony_ci            pivot = *p;
12927db96d56Sopenharmony_ci            l += offset;
12937db96d56Sopenharmony_ci            for (p = start + offset; p > l; --p)
12947db96d56Sopenharmony_ci                *p = *(p-1);
12957db96d56Sopenharmony_ci            *l = pivot;
12967db96d56Sopenharmony_ci        }
12977db96d56Sopenharmony_ci    }
12987db96d56Sopenharmony_ci    return 0;
12997db96d56Sopenharmony_ci
13007db96d56Sopenharmony_ci fail:
13017db96d56Sopenharmony_ci    return -1;
13027db96d56Sopenharmony_ci}
13037db96d56Sopenharmony_ci
13047db96d56Sopenharmony_ci/*
13057db96d56Sopenharmony_ciReturn the length of the run beginning at lo, in the slice [lo, hi).  lo < hi
13067db96d56Sopenharmony_ciis required on entry.  "A run" is the longest ascending sequence, with
13077db96d56Sopenharmony_ci
13087db96d56Sopenharmony_ci    lo[0] <= lo[1] <= lo[2] <= ...
13097db96d56Sopenharmony_ci
13107db96d56Sopenharmony_cior the longest descending sequence, with
13117db96d56Sopenharmony_ci
13127db96d56Sopenharmony_ci    lo[0] > lo[1] > lo[2] > ...
13137db96d56Sopenharmony_ci
13147db96d56Sopenharmony_ciBoolean *descending is set to 0 in the former case, or to 1 in the latter.
13157db96d56Sopenharmony_ciFor its intended use in a stable mergesort, the strictness of the defn of
13167db96d56Sopenharmony_ci"descending" is needed so that the caller can safely reverse a descending
13177db96d56Sopenharmony_cisequence without violating stability (strict > ensures there are no equal
13187db96d56Sopenharmony_cielements to get out of order).
13197db96d56Sopenharmony_ci
13207db96d56Sopenharmony_ciReturns -1 in case of error.
13217db96d56Sopenharmony_ci*/
13227db96d56Sopenharmony_cistatic Py_ssize_t
13237db96d56Sopenharmony_cicount_run(MergeState *ms, PyObject **lo, PyObject **hi, int *descending)
13247db96d56Sopenharmony_ci{
13257db96d56Sopenharmony_ci    Py_ssize_t k;
13267db96d56Sopenharmony_ci    Py_ssize_t n;
13277db96d56Sopenharmony_ci
13287db96d56Sopenharmony_ci    assert(lo < hi);
13297db96d56Sopenharmony_ci    *descending = 0;
13307db96d56Sopenharmony_ci    ++lo;
13317db96d56Sopenharmony_ci    if (lo == hi)
13327db96d56Sopenharmony_ci        return 1;
13337db96d56Sopenharmony_ci
13347db96d56Sopenharmony_ci    n = 2;
13357db96d56Sopenharmony_ci    IFLT(*lo, *(lo-1)) {
13367db96d56Sopenharmony_ci        *descending = 1;
13377db96d56Sopenharmony_ci        for (lo = lo+1; lo < hi; ++lo, ++n) {
13387db96d56Sopenharmony_ci            IFLT(*lo, *(lo-1))
13397db96d56Sopenharmony_ci                ;
13407db96d56Sopenharmony_ci            else
13417db96d56Sopenharmony_ci                break;
13427db96d56Sopenharmony_ci        }
13437db96d56Sopenharmony_ci    }
13447db96d56Sopenharmony_ci    else {
13457db96d56Sopenharmony_ci        for (lo = lo+1; lo < hi; ++lo, ++n) {
13467db96d56Sopenharmony_ci            IFLT(*lo, *(lo-1))
13477db96d56Sopenharmony_ci                break;
13487db96d56Sopenharmony_ci        }
13497db96d56Sopenharmony_ci    }
13507db96d56Sopenharmony_ci
13517db96d56Sopenharmony_ci    return n;
13527db96d56Sopenharmony_cifail:
13537db96d56Sopenharmony_ci    return -1;
13547db96d56Sopenharmony_ci}
13557db96d56Sopenharmony_ci
13567db96d56Sopenharmony_ci/*
13577db96d56Sopenharmony_ciLocate the proper position of key in a sorted vector; if the vector contains
13587db96d56Sopenharmony_cian element equal to key, return the position immediately to the left of
13597db96d56Sopenharmony_cithe leftmost equal element.  [gallop_right() does the same except returns
13607db96d56Sopenharmony_cithe position to the right of the rightmost equal element (if any).]
13617db96d56Sopenharmony_ci
13627db96d56Sopenharmony_ci"a" is a sorted vector with n elements, starting at a[0].  n must be > 0.
13637db96d56Sopenharmony_ci
13647db96d56Sopenharmony_ci"hint" is an index at which to begin the search, 0 <= hint < n.  The closer
13657db96d56Sopenharmony_cihint is to the final result, the faster this runs.
13667db96d56Sopenharmony_ci
13677db96d56Sopenharmony_ciThe return value is the int k in 0..n such that
13687db96d56Sopenharmony_ci
13697db96d56Sopenharmony_ci    a[k-1] < key <= a[k]
13707db96d56Sopenharmony_ci
13717db96d56Sopenharmony_cipretending that *(a-1) is minus infinity and a[n] is plus infinity.  IOW,
13727db96d56Sopenharmony_cikey belongs at index k; or, IOW, the first k elements of a should precede
13737db96d56Sopenharmony_cikey, and the last n-k should follow key.
13747db96d56Sopenharmony_ci
13757db96d56Sopenharmony_ciReturns -1 on error.  See listsort.txt for info on the method.
13767db96d56Sopenharmony_ci*/
13777db96d56Sopenharmony_cistatic Py_ssize_t
13787db96d56Sopenharmony_cigallop_left(MergeState *ms, PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint)
13797db96d56Sopenharmony_ci{
13807db96d56Sopenharmony_ci    Py_ssize_t ofs;
13817db96d56Sopenharmony_ci    Py_ssize_t lastofs;
13827db96d56Sopenharmony_ci    Py_ssize_t k;
13837db96d56Sopenharmony_ci
13847db96d56Sopenharmony_ci    assert(key && a && n > 0 && hint >= 0 && hint < n);
13857db96d56Sopenharmony_ci
13867db96d56Sopenharmony_ci    a += hint;
13877db96d56Sopenharmony_ci    lastofs = 0;
13887db96d56Sopenharmony_ci    ofs = 1;
13897db96d56Sopenharmony_ci    IFLT(*a, key) {
13907db96d56Sopenharmony_ci        /* a[hint] < key -- gallop right, until
13917db96d56Sopenharmony_ci         * a[hint + lastofs] < key <= a[hint + ofs]
13927db96d56Sopenharmony_ci         */
13937db96d56Sopenharmony_ci        const Py_ssize_t maxofs = n - hint;             /* &a[n-1] is highest */
13947db96d56Sopenharmony_ci        while (ofs < maxofs) {
13957db96d56Sopenharmony_ci            IFLT(a[ofs], key) {
13967db96d56Sopenharmony_ci                lastofs = ofs;
13977db96d56Sopenharmony_ci                assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2);
13987db96d56Sopenharmony_ci                ofs = (ofs << 1) + 1;
13997db96d56Sopenharmony_ci            }
14007db96d56Sopenharmony_ci            else                /* key <= a[hint + ofs] */
14017db96d56Sopenharmony_ci                break;
14027db96d56Sopenharmony_ci        }
14037db96d56Sopenharmony_ci        if (ofs > maxofs)
14047db96d56Sopenharmony_ci            ofs = maxofs;
14057db96d56Sopenharmony_ci        /* Translate back to offsets relative to &a[0]. */
14067db96d56Sopenharmony_ci        lastofs += hint;
14077db96d56Sopenharmony_ci        ofs += hint;
14087db96d56Sopenharmony_ci    }
14097db96d56Sopenharmony_ci    else {
14107db96d56Sopenharmony_ci        /* key <= a[hint] -- gallop left, until
14117db96d56Sopenharmony_ci         * a[hint - ofs] < key <= a[hint - lastofs]
14127db96d56Sopenharmony_ci         */
14137db96d56Sopenharmony_ci        const Py_ssize_t maxofs = hint + 1;             /* &a[0] is lowest */
14147db96d56Sopenharmony_ci        while (ofs < maxofs) {
14157db96d56Sopenharmony_ci            IFLT(*(a-ofs), key)
14167db96d56Sopenharmony_ci                break;
14177db96d56Sopenharmony_ci            /* key <= a[hint - ofs] */
14187db96d56Sopenharmony_ci            lastofs = ofs;
14197db96d56Sopenharmony_ci            assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2);
14207db96d56Sopenharmony_ci            ofs = (ofs << 1) + 1;
14217db96d56Sopenharmony_ci        }
14227db96d56Sopenharmony_ci        if (ofs > maxofs)
14237db96d56Sopenharmony_ci            ofs = maxofs;
14247db96d56Sopenharmony_ci        /* Translate back to positive offsets relative to &a[0]. */
14257db96d56Sopenharmony_ci        k = lastofs;
14267db96d56Sopenharmony_ci        lastofs = hint - ofs;
14277db96d56Sopenharmony_ci        ofs = hint - k;
14287db96d56Sopenharmony_ci    }
14297db96d56Sopenharmony_ci    a -= hint;
14307db96d56Sopenharmony_ci
14317db96d56Sopenharmony_ci    assert(-1 <= lastofs && lastofs < ofs && ofs <= n);
14327db96d56Sopenharmony_ci    /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the
14337db96d56Sopenharmony_ci     * right of lastofs but no farther right than ofs.  Do a binary
14347db96d56Sopenharmony_ci     * search, with invariant a[lastofs-1] < key <= a[ofs].
14357db96d56Sopenharmony_ci     */
14367db96d56Sopenharmony_ci    ++lastofs;
14377db96d56Sopenharmony_ci    while (lastofs < ofs) {
14387db96d56Sopenharmony_ci        Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);
14397db96d56Sopenharmony_ci
14407db96d56Sopenharmony_ci        IFLT(a[m], key)
14417db96d56Sopenharmony_ci            lastofs = m+1;              /* a[m] < key */
14427db96d56Sopenharmony_ci        else
14437db96d56Sopenharmony_ci            ofs = m;                    /* key <= a[m] */
14447db96d56Sopenharmony_ci    }
14457db96d56Sopenharmony_ci    assert(lastofs == ofs);             /* so a[ofs-1] < key <= a[ofs] */
14467db96d56Sopenharmony_ci    return ofs;
14477db96d56Sopenharmony_ci
14487db96d56Sopenharmony_cifail:
14497db96d56Sopenharmony_ci    return -1;
14507db96d56Sopenharmony_ci}
14517db96d56Sopenharmony_ci
14527db96d56Sopenharmony_ci/*
14537db96d56Sopenharmony_ciExactly like gallop_left(), except that if key already exists in a[0:n],
14547db96d56Sopenharmony_cifinds the position immediately to the right of the rightmost equal value.
14557db96d56Sopenharmony_ci
14567db96d56Sopenharmony_ciThe return value is the int k in 0..n such that
14577db96d56Sopenharmony_ci
14587db96d56Sopenharmony_ci    a[k-1] <= key < a[k]
14597db96d56Sopenharmony_ci
14607db96d56Sopenharmony_cior -1 if error.
14617db96d56Sopenharmony_ci
14627db96d56Sopenharmony_ciThe code duplication is massive, but this is enough different given that
14637db96d56Sopenharmony_ciwe're sticking to "<" comparisons that it's much harder to follow if
14647db96d56Sopenharmony_ciwritten as one routine with yet another "left or right?" flag.
14657db96d56Sopenharmony_ci*/
14667db96d56Sopenharmony_cistatic Py_ssize_t
14677db96d56Sopenharmony_cigallop_right(MergeState *ms, PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint)
14687db96d56Sopenharmony_ci{
14697db96d56Sopenharmony_ci    Py_ssize_t ofs;
14707db96d56Sopenharmony_ci    Py_ssize_t lastofs;
14717db96d56Sopenharmony_ci    Py_ssize_t k;
14727db96d56Sopenharmony_ci
14737db96d56Sopenharmony_ci    assert(key && a && n > 0 && hint >= 0 && hint < n);
14747db96d56Sopenharmony_ci
14757db96d56Sopenharmony_ci    a += hint;
14767db96d56Sopenharmony_ci    lastofs = 0;
14777db96d56Sopenharmony_ci    ofs = 1;
14787db96d56Sopenharmony_ci    IFLT(key, *a) {
14797db96d56Sopenharmony_ci        /* key < a[hint] -- gallop left, until
14807db96d56Sopenharmony_ci         * a[hint - ofs] <= key < a[hint - lastofs]
14817db96d56Sopenharmony_ci         */
14827db96d56Sopenharmony_ci        const Py_ssize_t maxofs = hint + 1;             /* &a[0] is lowest */
14837db96d56Sopenharmony_ci        while (ofs < maxofs) {
14847db96d56Sopenharmony_ci            IFLT(key, *(a-ofs)) {
14857db96d56Sopenharmony_ci                lastofs = ofs;
14867db96d56Sopenharmony_ci                assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2);
14877db96d56Sopenharmony_ci                ofs = (ofs << 1) + 1;
14887db96d56Sopenharmony_ci            }
14897db96d56Sopenharmony_ci            else                /* a[hint - ofs] <= key */
14907db96d56Sopenharmony_ci                break;
14917db96d56Sopenharmony_ci        }
14927db96d56Sopenharmony_ci        if (ofs > maxofs)
14937db96d56Sopenharmony_ci            ofs = maxofs;
14947db96d56Sopenharmony_ci        /* Translate back to positive offsets relative to &a[0]. */
14957db96d56Sopenharmony_ci        k = lastofs;
14967db96d56Sopenharmony_ci        lastofs = hint - ofs;
14977db96d56Sopenharmony_ci        ofs = hint - k;
14987db96d56Sopenharmony_ci    }
14997db96d56Sopenharmony_ci    else {
15007db96d56Sopenharmony_ci        /* a[hint] <= key -- gallop right, until
15017db96d56Sopenharmony_ci         * a[hint + lastofs] <= key < a[hint + ofs]
15027db96d56Sopenharmony_ci        */
15037db96d56Sopenharmony_ci        const Py_ssize_t maxofs = n - hint;             /* &a[n-1] is highest */
15047db96d56Sopenharmony_ci        while (ofs < maxofs) {
15057db96d56Sopenharmony_ci            IFLT(key, a[ofs])
15067db96d56Sopenharmony_ci                break;
15077db96d56Sopenharmony_ci            /* a[hint + ofs] <= key */
15087db96d56Sopenharmony_ci            lastofs = ofs;
15097db96d56Sopenharmony_ci            assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2);
15107db96d56Sopenharmony_ci            ofs = (ofs << 1) + 1;
15117db96d56Sopenharmony_ci        }
15127db96d56Sopenharmony_ci        if (ofs > maxofs)
15137db96d56Sopenharmony_ci            ofs = maxofs;
15147db96d56Sopenharmony_ci        /* Translate back to offsets relative to &a[0]. */
15157db96d56Sopenharmony_ci        lastofs += hint;
15167db96d56Sopenharmony_ci        ofs += hint;
15177db96d56Sopenharmony_ci    }
15187db96d56Sopenharmony_ci    a -= hint;
15197db96d56Sopenharmony_ci
15207db96d56Sopenharmony_ci    assert(-1 <= lastofs && lastofs < ofs && ofs <= n);
15217db96d56Sopenharmony_ci    /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the
15227db96d56Sopenharmony_ci     * right of lastofs but no farther right than ofs.  Do a binary
15237db96d56Sopenharmony_ci     * search, with invariant a[lastofs-1] <= key < a[ofs].
15247db96d56Sopenharmony_ci     */
15257db96d56Sopenharmony_ci    ++lastofs;
15267db96d56Sopenharmony_ci    while (lastofs < ofs) {
15277db96d56Sopenharmony_ci        Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);
15287db96d56Sopenharmony_ci
15297db96d56Sopenharmony_ci        IFLT(key, a[m])
15307db96d56Sopenharmony_ci            ofs = m;                    /* key < a[m] */
15317db96d56Sopenharmony_ci        else
15327db96d56Sopenharmony_ci            lastofs = m+1;              /* a[m] <= key */
15337db96d56Sopenharmony_ci    }
15347db96d56Sopenharmony_ci    assert(lastofs == ofs);             /* so a[ofs-1] <= key < a[ofs] */
15357db96d56Sopenharmony_ci    return ofs;
15367db96d56Sopenharmony_ci
15377db96d56Sopenharmony_cifail:
15387db96d56Sopenharmony_ci    return -1;
15397db96d56Sopenharmony_ci}
15407db96d56Sopenharmony_ci
15417db96d56Sopenharmony_ci/* Conceptually a MergeState's constructor. */
15427db96d56Sopenharmony_cistatic void
15437db96d56Sopenharmony_cimerge_init(MergeState *ms, Py_ssize_t list_size, int has_keyfunc,
15447db96d56Sopenharmony_ci           sortslice *lo)
15457db96d56Sopenharmony_ci{
15467db96d56Sopenharmony_ci    assert(ms != NULL);
15477db96d56Sopenharmony_ci    if (has_keyfunc) {
15487db96d56Sopenharmony_ci        /* The temporary space for merging will need at most half the list
15497db96d56Sopenharmony_ci         * size rounded up.  Use the minimum possible space so we can use the
15507db96d56Sopenharmony_ci         * rest of temparray for other things.  In particular, if there is
15517db96d56Sopenharmony_ci         * enough extra space, listsort() will use it to store the keys.
15527db96d56Sopenharmony_ci         */
15537db96d56Sopenharmony_ci        ms->alloced = (list_size + 1) / 2;
15547db96d56Sopenharmony_ci
15557db96d56Sopenharmony_ci        /* ms->alloced describes how many keys will be stored at
15567db96d56Sopenharmony_ci           ms->temparray, but we also need to store the values.  Hence,
15577db96d56Sopenharmony_ci           ms->alloced is capped at half of MERGESTATE_TEMP_SIZE. */
15587db96d56Sopenharmony_ci        if (MERGESTATE_TEMP_SIZE / 2 < ms->alloced)
15597db96d56Sopenharmony_ci            ms->alloced = MERGESTATE_TEMP_SIZE / 2;
15607db96d56Sopenharmony_ci        ms->a.values = &ms->temparray[ms->alloced];
15617db96d56Sopenharmony_ci    }
15627db96d56Sopenharmony_ci    else {
15637db96d56Sopenharmony_ci        ms->alloced = MERGESTATE_TEMP_SIZE;
15647db96d56Sopenharmony_ci        ms->a.values = NULL;
15657db96d56Sopenharmony_ci    }
15667db96d56Sopenharmony_ci    ms->a.keys = ms->temparray;
15677db96d56Sopenharmony_ci    ms->n = 0;
15687db96d56Sopenharmony_ci    ms->min_gallop = MIN_GALLOP;
15697db96d56Sopenharmony_ci    ms->listlen = list_size;
15707db96d56Sopenharmony_ci    ms->basekeys = lo->keys;
15717db96d56Sopenharmony_ci}
15727db96d56Sopenharmony_ci
15737db96d56Sopenharmony_ci/* Free all the temp memory owned by the MergeState.  This must be called
15747db96d56Sopenharmony_ci * when you're done with a MergeState, and may be called before then if
15757db96d56Sopenharmony_ci * you want to free the temp memory early.
15767db96d56Sopenharmony_ci */
15777db96d56Sopenharmony_cistatic void
15787db96d56Sopenharmony_cimerge_freemem(MergeState *ms)
15797db96d56Sopenharmony_ci{
15807db96d56Sopenharmony_ci    assert(ms != NULL);
15817db96d56Sopenharmony_ci    if (ms->a.keys != ms->temparray) {
15827db96d56Sopenharmony_ci        PyMem_Free(ms->a.keys);
15837db96d56Sopenharmony_ci        ms->a.keys = NULL;
15847db96d56Sopenharmony_ci    }
15857db96d56Sopenharmony_ci}
15867db96d56Sopenharmony_ci
15877db96d56Sopenharmony_ci/* Ensure enough temp memory for 'need' array slots is available.
15887db96d56Sopenharmony_ci * Returns 0 on success and -1 if the memory can't be gotten.
15897db96d56Sopenharmony_ci */
15907db96d56Sopenharmony_cistatic int
15917db96d56Sopenharmony_cimerge_getmem(MergeState *ms, Py_ssize_t need)
15927db96d56Sopenharmony_ci{
15937db96d56Sopenharmony_ci    int multiplier;
15947db96d56Sopenharmony_ci
15957db96d56Sopenharmony_ci    assert(ms != NULL);
15967db96d56Sopenharmony_ci    if (need <= ms->alloced)
15977db96d56Sopenharmony_ci        return 0;
15987db96d56Sopenharmony_ci
15997db96d56Sopenharmony_ci    multiplier = ms->a.values != NULL ? 2 : 1;
16007db96d56Sopenharmony_ci
16017db96d56Sopenharmony_ci    /* Don't realloc!  That can cost cycles to copy the old data, but
16027db96d56Sopenharmony_ci     * we don't care what's in the block.
16037db96d56Sopenharmony_ci     */
16047db96d56Sopenharmony_ci    merge_freemem(ms);
16057db96d56Sopenharmony_ci    if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject *) / multiplier) {
16067db96d56Sopenharmony_ci        PyErr_NoMemory();
16077db96d56Sopenharmony_ci        return -1;
16087db96d56Sopenharmony_ci    }
16097db96d56Sopenharmony_ci    ms->a.keys = (PyObject **)PyMem_Malloc(multiplier * need
16107db96d56Sopenharmony_ci                                          * sizeof(PyObject *));
16117db96d56Sopenharmony_ci    if (ms->a.keys != NULL) {
16127db96d56Sopenharmony_ci        ms->alloced = need;
16137db96d56Sopenharmony_ci        if (ms->a.values != NULL)
16147db96d56Sopenharmony_ci            ms->a.values = &ms->a.keys[need];
16157db96d56Sopenharmony_ci        return 0;
16167db96d56Sopenharmony_ci    }
16177db96d56Sopenharmony_ci    PyErr_NoMemory();
16187db96d56Sopenharmony_ci    return -1;
16197db96d56Sopenharmony_ci}
16207db96d56Sopenharmony_ci#define MERGE_GETMEM(MS, NEED) ((NEED) <= (MS)->alloced ? 0 :   \
16217db96d56Sopenharmony_ci                                merge_getmem(MS, NEED))
16227db96d56Sopenharmony_ci
16237db96d56Sopenharmony_ci/* Merge the na elements starting at ssa with the nb elements starting at
16247db96d56Sopenharmony_ci * ssb.keys = ssa.keys + na in a stable way, in-place.  na and nb must be > 0.
16257db96d56Sopenharmony_ci * Must also have that ssa.keys[na-1] belongs at the end of the merge, and
16267db96d56Sopenharmony_ci * should have na <= nb.  See listsort.txt for more info.  Return 0 if
16277db96d56Sopenharmony_ci * successful, -1 if error.
16287db96d56Sopenharmony_ci */
16297db96d56Sopenharmony_cistatic Py_ssize_t
16307db96d56Sopenharmony_cimerge_lo(MergeState *ms, sortslice ssa, Py_ssize_t na,
16317db96d56Sopenharmony_ci         sortslice ssb, Py_ssize_t nb)
16327db96d56Sopenharmony_ci{
16337db96d56Sopenharmony_ci    Py_ssize_t k;
16347db96d56Sopenharmony_ci    sortslice dest;
16357db96d56Sopenharmony_ci    int result = -1;            /* guilty until proved innocent */
16367db96d56Sopenharmony_ci    Py_ssize_t min_gallop;
16377db96d56Sopenharmony_ci
16387db96d56Sopenharmony_ci    assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0);
16397db96d56Sopenharmony_ci    assert(ssa.keys + na == ssb.keys);
16407db96d56Sopenharmony_ci    if (MERGE_GETMEM(ms, na) < 0)
16417db96d56Sopenharmony_ci        return -1;
16427db96d56Sopenharmony_ci    sortslice_memcpy(&ms->a, 0, &ssa, 0, na);
16437db96d56Sopenharmony_ci    dest = ssa;
16447db96d56Sopenharmony_ci    ssa = ms->a;
16457db96d56Sopenharmony_ci
16467db96d56Sopenharmony_ci    sortslice_copy_incr(&dest, &ssb);
16477db96d56Sopenharmony_ci    --nb;
16487db96d56Sopenharmony_ci    if (nb == 0)
16497db96d56Sopenharmony_ci        goto Succeed;
16507db96d56Sopenharmony_ci    if (na == 1)
16517db96d56Sopenharmony_ci        goto CopyB;
16527db96d56Sopenharmony_ci
16537db96d56Sopenharmony_ci    min_gallop = ms->min_gallop;
16547db96d56Sopenharmony_ci    for (;;) {
16557db96d56Sopenharmony_ci        Py_ssize_t acount = 0;          /* # of times A won in a row */
16567db96d56Sopenharmony_ci        Py_ssize_t bcount = 0;          /* # of times B won in a row */
16577db96d56Sopenharmony_ci
16587db96d56Sopenharmony_ci        /* Do the straightforward thing until (if ever) one run
16597db96d56Sopenharmony_ci         * appears to win consistently.
16607db96d56Sopenharmony_ci         */
16617db96d56Sopenharmony_ci        for (;;) {
16627db96d56Sopenharmony_ci            assert(na > 1 && nb > 0);
16637db96d56Sopenharmony_ci            k = ISLT(ssb.keys[0], ssa.keys[0]);
16647db96d56Sopenharmony_ci            if (k) {
16657db96d56Sopenharmony_ci                if (k < 0)
16667db96d56Sopenharmony_ci                    goto Fail;
16677db96d56Sopenharmony_ci                sortslice_copy_incr(&dest, &ssb);
16687db96d56Sopenharmony_ci                ++bcount;
16697db96d56Sopenharmony_ci                acount = 0;
16707db96d56Sopenharmony_ci                --nb;
16717db96d56Sopenharmony_ci                if (nb == 0)
16727db96d56Sopenharmony_ci                    goto Succeed;
16737db96d56Sopenharmony_ci                if (bcount >= min_gallop)
16747db96d56Sopenharmony_ci                    break;
16757db96d56Sopenharmony_ci            }
16767db96d56Sopenharmony_ci            else {
16777db96d56Sopenharmony_ci                sortslice_copy_incr(&dest, &ssa);
16787db96d56Sopenharmony_ci                ++acount;
16797db96d56Sopenharmony_ci                bcount = 0;
16807db96d56Sopenharmony_ci                --na;
16817db96d56Sopenharmony_ci                if (na == 1)
16827db96d56Sopenharmony_ci                    goto CopyB;
16837db96d56Sopenharmony_ci                if (acount >= min_gallop)
16847db96d56Sopenharmony_ci                    break;
16857db96d56Sopenharmony_ci            }
16867db96d56Sopenharmony_ci        }
16877db96d56Sopenharmony_ci
16887db96d56Sopenharmony_ci        /* One run is winning so consistently that galloping may
16897db96d56Sopenharmony_ci         * be a huge win.  So try that, and continue galloping until
16907db96d56Sopenharmony_ci         * (if ever) neither run appears to be winning consistently
16917db96d56Sopenharmony_ci         * anymore.
16927db96d56Sopenharmony_ci         */
16937db96d56Sopenharmony_ci        ++min_gallop;
16947db96d56Sopenharmony_ci        do {
16957db96d56Sopenharmony_ci            assert(na > 1 && nb > 0);
16967db96d56Sopenharmony_ci            min_gallop -= min_gallop > 1;
16977db96d56Sopenharmony_ci            ms->min_gallop = min_gallop;
16987db96d56Sopenharmony_ci            k = gallop_right(ms, ssb.keys[0], ssa.keys, na, 0);
16997db96d56Sopenharmony_ci            acount = k;
17007db96d56Sopenharmony_ci            if (k) {
17017db96d56Sopenharmony_ci                if (k < 0)
17027db96d56Sopenharmony_ci                    goto Fail;
17037db96d56Sopenharmony_ci                sortslice_memcpy(&dest, 0, &ssa, 0, k);
17047db96d56Sopenharmony_ci                sortslice_advance(&dest, k);
17057db96d56Sopenharmony_ci                sortslice_advance(&ssa, k);
17067db96d56Sopenharmony_ci                na -= k;
17077db96d56Sopenharmony_ci                if (na == 1)
17087db96d56Sopenharmony_ci                    goto CopyB;
17097db96d56Sopenharmony_ci                /* na==0 is impossible now if the comparison
17107db96d56Sopenharmony_ci                 * function is consistent, but we can't assume
17117db96d56Sopenharmony_ci                 * that it is.
17127db96d56Sopenharmony_ci                 */
17137db96d56Sopenharmony_ci                if (na == 0)
17147db96d56Sopenharmony_ci                    goto Succeed;
17157db96d56Sopenharmony_ci            }
17167db96d56Sopenharmony_ci            sortslice_copy_incr(&dest, &ssb);
17177db96d56Sopenharmony_ci            --nb;
17187db96d56Sopenharmony_ci            if (nb == 0)
17197db96d56Sopenharmony_ci                goto Succeed;
17207db96d56Sopenharmony_ci
17217db96d56Sopenharmony_ci            k = gallop_left(ms, ssa.keys[0], ssb.keys, nb, 0);
17227db96d56Sopenharmony_ci            bcount = k;
17237db96d56Sopenharmony_ci            if (k) {
17247db96d56Sopenharmony_ci                if (k < 0)
17257db96d56Sopenharmony_ci                    goto Fail;
17267db96d56Sopenharmony_ci                sortslice_memmove(&dest, 0, &ssb, 0, k);
17277db96d56Sopenharmony_ci                sortslice_advance(&dest, k);
17287db96d56Sopenharmony_ci                sortslice_advance(&ssb, k);
17297db96d56Sopenharmony_ci                nb -= k;
17307db96d56Sopenharmony_ci                if (nb == 0)
17317db96d56Sopenharmony_ci                    goto Succeed;
17327db96d56Sopenharmony_ci            }
17337db96d56Sopenharmony_ci            sortslice_copy_incr(&dest, &ssa);
17347db96d56Sopenharmony_ci            --na;
17357db96d56Sopenharmony_ci            if (na == 1)
17367db96d56Sopenharmony_ci                goto CopyB;
17377db96d56Sopenharmony_ci        } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
17387db96d56Sopenharmony_ci        ++min_gallop;           /* penalize it for leaving galloping mode */
17397db96d56Sopenharmony_ci        ms->min_gallop = min_gallop;
17407db96d56Sopenharmony_ci    }
17417db96d56Sopenharmony_ciSucceed:
17427db96d56Sopenharmony_ci    result = 0;
17437db96d56Sopenharmony_ciFail:
17447db96d56Sopenharmony_ci    if (na)
17457db96d56Sopenharmony_ci        sortslice_memcpy(&dest, 0, &ssa, 0, na);
17467db96d56Sopenharmony_ci    return result;
17477db96d56Sopenharmony_ciCopyB:
17487db96d56Sopenharmony_ci    assert(na == 1 && nb > 0);
17497db96d56Sopenharmony_ci    /* The last element of ssa belongs at the end of the merge. */
17507db96d56Sopenharmony_ci    sortslice_memmove(&dest, 0, &ssb, 0, nb);
17517db96d56Sopenharmony_ci    sortslice_copy(&dest, nb, &ssa, 0);
17527db96d56Sopenharmony_ci    return 0;
17537db96d56Sopenharmony_ci}
17547db96d56Sopenharmony_ci
17557db96d56Sopenharmony_ci/* Merge the na elements starting at pa with the nb elements starting at
17567db96d56Sopenharmony_ci * ssb.keys = ssa.keys + na in a stable way, in-place.  na and nb must be > 0.
17577db96d56Sopenharmony_ci * Must also have that ssa.keys[na-1] belongs at the end of the merge, and
17587db96d56Sopenharmony_ci * should have na >= nb.  See listsort.txt for more info.  Return 0 if
17597db96d56Sopenharmony_ci * successful, -1 if error.
17607db96d56Sopenharmony_ci */
17617db96d56Sopenharmony_cistatic Py_ssize_t
17627db96d56Sopenharmony_cimerge_hi(MergeState *ms, sortslice ssa, Py_ssize_t na,
17637db96d56Sopenharmony_ci         sortslice ssb, Py_ssize_t nb)
17647db96d56Sopenharmony_ci{
17657db96d56Sopenharmony_ci    Py_ssize_t k;
17667db96d56Sopenharmony_ci    sortslice dest, basea, baseb;
17677db96d56Sopenharmony_ci    int result = -1;            /* guilty until proved innocent */
17687db96d56Sopenharmony_ci    Py_ssize_t min_gallop;
17697db96d56Sopenharmony_ci
17707db96d56Sopenharmony_ci    assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0);
17717db96d56Sopenharmony_ci    assert(ssa.keys + na == ssb.keys);
17727db96d56Sopenharmony_ci    if (MERGE_GETMEM(ms, nb) < 0)
17737db96d56Sopenharmony_ci        return -1;
17747db96d56Sopenharmony_ci    dest = ssb;
17757db96d56Sopenharmony_ci    sortslice_advance(&dest, nb-1);
17767db96d56Sopenharmony_ci    sortslice_memcpy(&ms->a, 0, &ssb, 0, nb);
17777db96d56Sopenharmony_ci    basea = ssa;
17787db96d56Sopenharmony_ci    baseb = ms->a;
17797db96d56Sopenharmony_ci    ssb.keys = ms->a.keys + nb - 1;
17807db96d56Sopenharmony_ci    if (ssb.values != NULL)
17817db96d56Sopenharmony_ci        ssb.values = ms->a.values + nb - 1;
17827db96d56Sopenharmony_ci    sortslice_advance(&ssa, na - 1);
17837db96d56Sopenharmony_ci
17847db96d56Sopenharmony_ci    sortslice_copy_decr(&dest, &ssa);
17857db96d56Sopenharmony_ci    --na;
17867db96d56Sopenharmony_ci    if (na == 0)
17877db96d56Sopenharmony_ci        goto Succeed;
17887db96d56Sopenharmony_ci    if (nb == 1)
17897db96d56Sopenharmony_ci        goto CopyA;
17907db96d56Sopenharmony_ci
17917db96d56Sopenharmony_ci    min_gallop = ms->min_gallop;
17927db96d56Sopenharmony_ci    for (;;) {
17937db96d56Sopenharmony_ci        Py_ssize_t acount = 0;          /* # of times A won in a row */
17947db96d56Sopenharmony_ci        Py_ssize_t bcount = 0;          /* # of times B won in a row */
17957db96d56Sopenharmony_ci
17967db96d56Sopenharmony_ci        /* Do the straightforward thing until (if ever) one run
17977db96d56Sopenharmony_ci         * appears to win consistently.
17987db96d56Sopenharmony_ci         */
17997db96d56Sopenharmony_ci        for (;;) {
18007db96d56Sopenharmony_ci            assert(na > 0 && nb > 1);
18017db96d56Sopenharmony_ci            k = ISLT(ssb.keys[0], ssa.keys[0]);
18027db96d56Sopenharmony_ci            if (k) {
18037db96d56Sopenharmony_ci                if (k < 0)
18047db96d56Sopenharmony_ci                    goto Fail;
18057db96d56Sopenharmony_ci                sortslice_copy_decr(&dest, &ssa);
18067db96d56Sopenharmony_ci                ++acount;
18077db96d56Sopenharmony_ci                bcount = 0;
18087db96d56Sopenharmony_ci                --na;
18097db96d56Sopenharmony_ci                if (na == 0)
18107db96d56Sopenharmony_ci                    goto Succeed;
18117db96d56Sopenharmony_ci                if (acount >= min_gallop)
18127db96d56Sopenharmony_ci                    break;
18137db96d56Sopenharmony_ci            }
18147db96d56Sopenharmony_ci            else {
18157db96d56Sopenharmony_ci                sortslice_copy_decr(&dest, &ssb);
18167db96d56Sopenharmony_ci                ++bcount;
18177db96d56Sopenharmony_ci                acount = 0;
18187db96d56Sopenharmony_ci                --nb;
18197db96d56Sopenharmony_ci                if (nb == 1)
18207db96d56Sopenharmony_ci                    goto CopyA;
18217db96d56Sopenharmony_ci                if (bcount >= min_gallop)
18227db96d56Sopenharmony_ci                    break;
18237db96d56Sopenharmony_ci            }
18247db96d56Sopenharmony_ci        }
18257db96d56Sopenharmony_ci
18267db96d56Sopenharmony_ci        /* One run is winning so consistently that galloping may
18277db96d56Sopenharmony_ci         * be a huge win.  So try that, and continue galloping until
18287db96d56Sopenharmony_ci         * (if ever) neither run appears to be winning consistently
18297db96d56Sopenharmony_ci         * anymore.
18307db96d56Sopenharmony_ci         */
18317db96d56Sopenharmony_ci        ++min_gallop;
18327db96d56Sopenharmony_ci        do {
18337db96d56Sopenharmony_ci            assert(na > 0 && nb > 1);
18347db96d56Sopenharmony_ci            min_gallop -= min_gallop > 1;
18357db96d56Sopenharmony_ci            ms->min_gallop = min_gallop;
18367db96d56Sopenharmony_ci            k = gallop_right(ms, ssb.keys[0], basea.keys, na, na-1);
18377db96d56Sopenharmony_ci            if (k < 0)
18387db96d56Sopenharmony_ci                goto Fail;
18397db96d56Sopenharmony_ci            k = na - k;
18407db96d56Sopenharmony_ci            acount = k;
18417db96d56Sopenharmony_ci            if (k) {
18427db96d56Sopenharmony_ci                sortslice_advance(&dest, -k);
18437db96d56Sopenharmony_ci                sortslice_advance(&ssa, -k);
18447db96d56Sopenharmony_ci                sortslice_memmove(&dest, 1, &ssa, 1, k);
18457db96d56Sopenharmony_ci                na -= k;
18467db96d56Sopenharmony_ci                if (na == 0)
18477db96d56Sopenharmony_ci                    goto Succeed;
18487db96d56Sopenharmony_ci            }
18497db96d56Sopenharmony_ci            sortslice_copy_decr(&dest, &ssb);
18507db96d56Sopenharmony_ci            --nb;
18517db96d56Sopenharmony_ci            if (nb == 1)
18527db96d56Sopenharmony_ci                goto CopyA;
18537db96d56Sopenharmony_ci
18547db96d56Sopenharmony_ci            k = gallop_left(ms, ssa.keys[0], baseb.keys, nb, nb-1);
18557db96d56Sopenharmony_ci            if (k < 0)
18567db96d56Sopenharmony_ci                goto Fail;
18577db96d56Sopenharmony_ci            k = nb - k;
18587db96d56Sopenharmony_ci            bcount = k;
18597db96d56Sopenharmony_ci            if (k) {
18607db96d56Sopenharmony_ci                sortslice_advance(&dest, -k);
18617db96d56Sopenharmony_ci                sortslice_advance(&ssb, -k);
18627db96d56Sopenharmony_ci                sortslice_memcpy(&dest, 1, &ssb, 1, k);
18637db96d56Sopenharmony_ci                nb -= k;
18647db96d56Sopenharmony_ci                if (nb == 1)
18657db96d56Sopenharmony_ci                    goto CopyA;
18667db96d56Sopenharmony_ci                /* nb==0 is impossible now if the comparison
18677db96d56Sopenharmony_ci                 * function is consistent, but we can't assume
18687db96d56Sopenharmony_ci                 * that it is.
18697db96d56Sopenharmony_ci                 */
18707db96d56Sopenharmony_ci                if (nb == 0)
18717db96d56Sopenharmony_ci                    goto Succeed;
18727db96d56Sopenharmony_ci            }
18737db96d56Sopenharmony_ci            sortslice_copy_decr(&dest, &ssa);
18747db96d56Sopenharmony_ci            --na;
18757db96d56Sopenharmony_ci            if (na == 0)
18767db96d56Sopenharmony_ci                goto Succeed;
18777db96d56Sopenharmony_ci        } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
18787db96d56Sopenharmony_ci        ++min_gallop;           /* penalize it for leaving galloping mode */
18797db96d56Sopenharmony_ci        ms->min_gallop = min_gallop;
18807db96d56Sopenharmony_ci    }
18817db96d56Sopenharmony_ciSucceed:
18827db96d56Sopenharmony_ci    result = 0;
18837db96d56Sopenharmony_ciFail:
18847db96d56Sopenharmony_ci    if (nb)
18857db96d56Sopenharmony_ci        sortslice_memcpy(&dest, -(nb-1), &baseb, 0, nb);
18867db96d56Sopenharmony_ci    return result;
18877db96d56Sopenharmony_ciCopyA:
18887db96d56Sopenharmony_ci    assert(nb == 1 && na > 0);
18897db96d56Sopenharmony_ci    /* The first element of ssb belongs at the front of the merge. */
18907db96d56Sopenharmony_ci    sortslice_memmove(&dest, 1-na, &ssa, 1-na, na);
18917db96d56Sopenharmony_ci    sortslice_advance(&dest, -na);
18927db96d56Sopenharmony_ci    sortslice_advance(&ssa, -na);
18937db96d56Sopenharmony_ci    sortslice_copy(&dest, 0, &ssb, 0);
18947db96d56Sopenharmony_ci    return 0;
18957db96d56Sopenharmony_ci}
18967db96d56Sopenharmony_ci
18977db96d56Sopenharmony_ci/* Merge the two runs at stack indices i and i+1.
18987db96d56Sopenharmony_ci * Returns 0 on success, -1 on error.
18997db96d56Sopenharmony_ci */
19007db96d56Sopenharmony_cistatic Py_ssize_t
19017db96d56Sopenharmony_cimerge_at(MergeState *ms, Py_ssize_t i)
19027db96d56Sopenharmony_ci{
19037db96d56Sopenharmony_ci    sortslice ssa, ssb;
19047db96d56Sopenharmony_ci    Py_ssize_t na, nb;
19057db96d56Sopenharmony_ci    Py_ssize_t k;
19067db96d56Sopenharmony_ci
19077db96d56Sopenharmony_ci    assert(ms != NULL);
19087db96d56Sopenharmony_ci    assert(ms->n >= 2);
19097db96d56Sopenharmony_ci    assert(i >= 0);
19107db96d56Sopenharmony_ci    assert(i == ms->n - 2 || i == ms->n - 3);
19117db96d56Sopenharmony_ci
19127db96d56Sopenharmony_ci    ssa = ms->pending[i].base;
19137db96d56Sopenharmony_ci    na = ms->pending[i].len;
19147db96d56Sopenharmony_ci    ssb = ms->pending[i+1].base;
19157db96d56Sopenharmony_ci    nb = ms->pending[i+1].len;
19167db96d56Sopenharmony_ci    assert(na > 0 && nb > 0);
19177db96d56Sopenharmony_ci    assert(ssa.keys + na == ssb.keys);
19187db96d56Sopenharmony_ci
19197db96d56Sopenharmony_ci    /* Record the length of the combined runs; if i is the 3rd-last
19207db96d56Sopenharmony_ci     * run now, also slide over the last run (which isn't involved
19217db96d56Sopenharmony_ci     * in this merge).  The current run i+1 goes away in any case.
19227db96d56Sopenharmony_ci     */
19237db96d56Sopenharmony_ci    ms->pending[i].len = na + nb;
19247db96d56Sopenharmony_ci    if (i == ms->n - 3)
19257db96d56Sopenharmony_ci        ms->pending[i+1] = ms->pending[i+2];
19267db96d56Sopenharmony_ci    --ms->n;
19277db96d56Sopenharmony_ci
19287db96d56Sopenharmony_ci    /* Where does b start in a?  Elements in a before that can be
19297db96d56Sopenharmony_ci     * ignored (already in place).
19307db96d56Sopenharmony_ci     */
19317db96d56Sopenharmony_ci    k = gallop_right(ms, *ssb.keys, ssa.keys, na, 0);
19327db96d56Sopenharmony_ci    if (k < 0)
19337db96d56Sopenharmony_ci        return -1;
19347db96d56Sopenharmony_ci    sortslice_advance(&ssa, k);
19357db96d56Sopenharmony_ci    na -= k;
19367db96d56Sopenharmony_ci    if (na == 0)
19377db96d56Sopenharmony_ci        return 0;
19387db96d56Sopenharmony_ci
19397db96d56Sopenharmony_ci    /* Where does a end in b?  Elements in b after that can be
19407db96d56Sopenharmony_ci     * ignored (already in place).
19417db96d56Sopenharmony_ci     */
19427db96d56Sopenharmony_ci    nb = gallop_left(ms, ssa.keys[na-1], ssb.keys, nb, nb-1);
19437db96d56Sopenharmony_ci    if (nb <= 0)
19447db96d56Sopenharmony_ci        return nb;
19457db96d56Sopenharmony_ci
19467db96d56Sopenharmony_ci    /* Merge what remains of the runs, using a temp array with
19477db96d56Sopenharmony_ci     * min(na, nb) elements.
19487db96d56Sopenharmony_ci     */
19497db96d56Sopenharmony_ci    if (na <= nb)
19507db96d56Sopenharmony_ci        return merge_lo(ms, ssa, na, ssb, nb);
19517db96d56Sopenharmony_ci    else
19527db96d56Sopenharmony_ci        return merge_hi(ms, ssa, na, ssb, nb);
19537db96d56Sopenharmony_ci}
19547db96d56Sopenharmony_ci
19557db96d56Sopenharmony_ci/* Two adjacent runs begin at index s1. The first run has length n1, and
19567db96d56Sopenharmony_ci * the second run (starting at index s1+n1) has length n2. The list has total
19577db96d56Sopenharmony_ci * length n.
19587db96d56Sopenharmony_ci * Compute the "power" of the first run. See listsort.txt for details.
19597db96d56Sopenharmony_ci */
19607db96d56Sopenharmony_cistatic int
19617db96d56Sopenharmony_cipowerloop(Py_ssize_t s1, Py_ssize_t n1, Py_ssize_t n2, Py_ssize_t n)
19627db96d56Sopenharmony_ci{
19637db96d56Sopenharmony_ci    int result = 0;
19647db96d56Sopenharmony_ci    assert(s1 >= 0);
19657db96d56Sopenharmony_ci    assert(n1 > 0 && n2 > 0);
19667db96d56Sopenharmony_ci    assert(s1 + n1 + n2 <= n);
19677db96d56Sopenharmony_ci    /* midpoints a and b:
19687db96d56Sopenharmony_ci     * a = s1 + n1/2
19697db96d56Sopenharmony_ci     * b = s1 + n1 + n2/2 = a + (n1 + n2)/2
19707db96d56Sopenharmony_ci     *
19717db96d56Sopenharmony_ci     * Those may not be integers, though, because of the "/2". So we work with
19727db96d56Sopenharmony_ci     * 2*a and 2*b instead, which are necessarily integers. It makes no
19737db96d56Sopenharmony_ci     * difference to the outcome, since the bits in the expansion of (2*i)/n
19747db96d56Sopenharmony_ci     * are merely shifted one position from those of i/n.
19757db96d56Sopenharmony_ci     */
19767db96d56Sopenharmony_ci    Py_ssize_t a = 2 * s1 + n1;  /* 2*a */
19777db96d56Sopenharmony_ci    Py_ssize_t b = a + n1 + n2;  /* 2*b */
19787db96d56Sopenharmony_ci    /* Emulate a/n and b/n one bit a time, until bits differ. */
19797db96d56Sopenharmony_ci    for (;;) {
19807db96d56Sopenharmony_ci        ++result;
19817db96d56Sopenharmony_ci        if (a >= n) {  /* both quotient bits are 1 */
19827db96d56Sopenharmony_ci            assert(b >= a);
19837db96d56Sopenharmony_ci            a -= n;
19847db96d56Sopenharmony_ci            b -= n;
19857db96d56Sopenharmony_ci        }
19867db96d56Sopenharmony_ci        else if (b >= n) {  /* a/n bit is 0, b/n bit is 1 */
19877db96d56Sopenharmony_ci            break;
19887db96d56Sopenharmony_ci        } /* else both quotient bits are 0 */
19897db96d56Sopenharmony_ci        assert(a < b && b < n);
19907db96d56Sopenharmony_ci        a <<= 1;
19917db96d56Sopenharmony_ci        b <<= 1;
19927db96d56Sopenharmony_ci    }
19937db96d56Sopenharmony_ci    return result;
19947db96d56Sopenharmony_ci}
19957db96d56Sopenharmony_ci
19967db96d56Sopenharmony_ci/* The next run has been identified, of length n2.
19977db96d56Sopenharmony_ci * If there's already a run on the stack, apply the "powersort" merge strategy:
19987db96d56Sopenharmony_ci * compute the topmost run's "power" (depth in a conceptual binary merge tree)
19997db96d56Sopenharmony_ci * and merge adjacent runs on the stack with greater power. See listsort.txt
20007db96d56Sopenharmony_ci * for more info.
20017db96d56Sopenharmony_ci *
20027db96d56Sopenharmony_ci * It's the caller's responsibility to push the new run on the stack when this
20037db96d56Sopenharmony_ci * returns.
20047db96d56Sopenharmony_ci *
20057db96d56Sopenharmony_ci * Returns 0 on success, -1 on error.
20067db96d56Sopenharmony_ci */
20077db96d56Sopenharmony_cistatic int
20087db96d56Sopenharmony_cifound_new_run(MergeState *ms, Py_ssize_t n2)
20097db96d56Sopenharmony_ci{
20107db96d56Sopenharmony_ci    assert(ms);
20117db96d56Sopenharmony_ci    if (ms->n) {
20127db96d56Sopenharmony_ci        assert(ms->n > 0);
20137db96d56Sopenharmony_ci        struct s_slice *p = ms->pending;
20147db96d56Sopenharmony_ci        Py_ssize_t s1 = p[ms->n - 1].base.keys - ms->basekeys; /* start index */
20157db96d56Sopenharmony_ci        Py_ssize_t n1 = p[ms->n - 1].len;
20167db96d56Sopenharmony_ci        int power = powerloop(s1, n1, n2, ms->listlen);
20177db96d56Sopenharmony_ci        while (ms->n > 1 && p[ms->n - 2].power > power) {
20187db96d56Sopenharmony_ci            if (merge_at(ms, ms->n - 2) < 0)
20197db96d56Sopenharmony_ci                return -1;
20207db96d56Sopenharmony_ci        }
20217db96d56Sopenharmony_ci        assert(ms->n < 2 || p[ms->n - 2].power < power);
20227db96d56Sopenharmony_ci        p[ms->n - 1].power = power;
20237db96d56Sopenharmony_ci    }
20247db96d56Sopenharmony_ci    return 0;
20257db96d56Sopenharmony_ci}
20267db96d56Sopenharmony_ci
20277db96d56Sopenharmony_ci/* Regardless of invariants, merge all runs on the stack until only one
20287db96d56Sopenharmony_ci * remains.  This is used at the end of the mergesort.
20297db96d56Sopenharmony_ci *
20307db96d56Sopenharmony_ci * Returns 0 on success, -1 on error.
20317db96d56Sopenharmony_ci */
20327db96d56Sopenharmony_cistatic int
20337db96d56Sopenharmony_cimerge_force_collapse(MergeState *ms)
20347db96d56Sopenharmony_ci{
20357db96d56Sopenharmony_ci    struct s_slice *p = ms->pending;
20367db96d56Sopenharmony_ci
20377db96d56Sopenharmony_ci    assert(ms);
20387db96d56Sopenharmony_ci    while (ms->n > 1) {
20397db96d56Sopenharmony_ci        Py_ssize_t n = ms->n - 2;
20407db96d56Sopenharmony_ci        if (n > 0 && p[n-1].len < p[n+1].len)
20417db96d56Sopenharmony_ci            --n;
20427db96d56Sopenharmony_ci        if (merge_at(ms, n) < 0)
20437db96d56Sopenharmony_ci            return -1;
20447db96d56Sopenharmony_ci    }
20457db96d56Sopenharmony_ci    return 0;
20467db96d56Sopenharmony_ci}
20477db96d56Sopenharmony_ci
20487db96d56Sopenharmony_ci/* Compute a good value for the minimum run length; natural runs shorter
20497db96d56Sopenharmony_ci * than this are boosted artificially via binary insertion.
20507db96d56Sopenharmony_ci *
20517db96d56Sopenharmony_ci * If n < 64, return n (it's too small to bother with fancy stuff).
20527db96d56Sopenharmony_ci * Else if n is an exact power of 2, return 32.
20537db96d56Sopenharmony_ci * Else return an int k, 32 <= k <= 64, such that n/k is close to, but
20547db96d56Sopenharmony_ci * strictly less than, an exact power of 2.
20557db96d56Sopenharmony_ci *
20567db96d56Sopenharmony_ci * See listsort.txt for more info.
20577db96d56Sopenharmony_ci */
20587db96d56Sopenharmony_cistatic Py_ssize_t
20597db96d56Sopenharmony_cimerge_compute_minrun(Py_ssize_t n)
20607db96d56Sopenharmony_ci{
20617db96d56Sopenharmony_ci    Py_ssize_t r = 0;           /* becomes 1 if any 1 bits are shifted off */
20627db96d56Sopenharmony_ci
20637db96d56Sopenharmony_ci    assert(n >= 0);
20647db96d56Sopenharmony_ci    while (n >= 64) {
20657db96d56Sopenharmony_ci        r |= n & 1;
20667db96d56Sopenharmony_ci        n >>= 1;
20677db96d56Sopenharmony_ci    }
20687db96d56Sopenharmony_ci    return n + r;
20697db96d56Sopenharmony_ci}
20707db96d56Sopenharmony_ci
20717db96d56Sopenharmony_cistatic void
20727db96d56Sopenharmony_cireverse_sortslice(sortslice *s, Py_ssize_t n)
20737db96d56Sopenharmony_ci{
20747db96d56Sopenharmony_ci    reverse_slice(s->keys, &s->keys[n]);
20757db96d56Sopenharmony_ci    if (s->values != NULL)
20767db96d56Sopenharmony_ci        reverse_slice(s->values, &s->values[n]);
20777db96d56Sopenharmony_ci}
20787db96d56Sopenharmony_ci
20797db96d56Sopenharmony_ci/* Here we define custom comparison functions to optimize for the cases one commonly
20807db96d56Sopenharmony_ci * encounters in practice: homogeneous lists, often of one of the basic types. */
20817db96d56Sopenharmony_ci
20827db96d56Sopenharmony_ci/* This struct holds the comparison function and helper functions
20837db96d56Sopenharmony_ci * selected in the pre-sort check. */
20847db96d56Sopenharmony_ci
20857db96d56Sopenharmony_ci/* These are the special case compare functions.
20867db96d56Sopenharmony_ci * ms->key_compare will always point to one of these: */
20877db96d56Sopenharmony_ci
20887db96d56Sopenharmony_ci/* Heterogeneous compare: default, always safe to fall back on. */
20897db96d56Sopenharmony_cistatic int
20907db96d56Sopenharmony_cisafe_object_compare(PyObject *v, PyObject *w, MergeState *ms)
20917db96d56Sopenharmony_ci{
20927db96d56Sopenharmony_ci    /* No assumptions necessary! */
20937db96d56Sopenharmony_ci    return PyObject_RichCompareBool(v, w, Py_LT);
20947db96d56Sopenharmony_ci}
20957db96d56Sopenharmony_ci
20967db96d56Sopenharmony_ci/* Homogeneous compare: safe for any two comparable objects of the same type.
20977db96d56Sopenharmony_ci * (ms->key_richcompare is set to ob_type->tp_richcompare in the
20987db96d56Sopenharmony_ci *  pre-sort check.)
20997db96d56Sopenharmony_ci */
21007db96d56Sopenharmony_cistatic int
21017db96d56Sopenharmony_ciunsafe_object_compare(PyObject *v, PyObject *w, MergeState *ms)
21027db96d56Sopenharmony_ci{
21037db96d56Sopenharmony_ci    PyObject *res_obj; int res;
21047db96d56Sopenharmony_ci
21057db96d56Sopenharmony_ci    /* No assumptions, because we check first: */
21067db96d56Sopenharmony_ci    if (Py_TYPE(v)->tp_richcompare != ms->key_richcompare)
21077db96d56Sopenharmony_ci        return PyObject_RichCompareBool(v, w, Py_LT);
21087db96d56Sopenharmony_ci
21097db96d56Sopenharmony_ci    assert(ms->key_richcompare != NULL);
21107db96d56Sopenharmony_ci    res_obj = (*(ms->key_richcompare))(v, w, Py_LT);
21117db96d56Sopenharmony_ci
21127db96d56Sopenharmony_ci    if (res_obj == Py_NotImplemented) {
21137db96d56Sopenharmony_ci        Py_DECREF(res_obj);
21147db96d56Sopenharmony_ci        return PyObject_RichCompareBool(v, w, Py_LT);
21157db96d56Sopenharmony_ci    }
21167db96d56Sopenharmony_ci    if (res_obj == NULL)
21177db96d56Sopenharmony_ci        return -1;
21187db96d56Sopenharmony_ci
21197db96d56Sopenharmony_ci    if (PyBool_Check(res_obj)) {
21207db96d56Sopenharmony_ci        res = (res_obj == Py_True);
21217db96d56Sopenharmony_ci    }
21227db96d56Sopenharmony_ci    else {
21237db96d56Sopenharmony_ci        res = PyObject_IsTrue(res_obj);
21247db96d56Sopenharmony_ci    }
21257db96d56Sopenharmony_ci    Py_DECREF(res_obj);
21267db96d56Sopenharmony_ci
21277db96d56Sopenharmony_ci    /* Note that we can't assert
21287db96d56Sopenharmony_ci     *     res == PyObject_RichCompareBool(v, w, Py_LT);
21297db96d56Sopenharmony_ci     * because of evil compare functions like this:
21307db96d56Sopenharmony_ci     *     lambda a, b:  int(random.random() * 3) - 1)
21317db96d56Sopenharmony_ci     * (which is actually in test_sort.py) */
21327db96d56Sopenharmony_ci    return res;
21337db96d56Sopenharmony_ci}
21347db96d56Sopenharmony_ci
21357db96d56Sopenharmony_ci/* Latin string compare: safe for any two latin (one byte per char) strings. */
21367db96d56Sopenharmony_cistatic int
21377db96d56Sopenharmony_ciunsafe_latin_compare(PyObject *v, PyObject *w, MergeState *ms)
21387db96d56Sopenharmony_ci{
21397db96d56Sopenharmony_ci    Py_ssize_t len;
21407db96d56Sopenharmony_ci    int res;
21417db96d56Sopenharmony_ci
21427db96d56Sopenharmony_ci    /* Modified from Objects/unicodeobject.c:unicode_compare, assuming: */
21437db96d56Sopenharmony_ci    assert(Py_IS_TYPE(v, &PyUnicode_Type));
21447db96d56Sopenharmony_ci    assert(Py_IS_TYPE(w, &PyUnicode_Type));
21457db96d56Sopenharmony_ci    assert(PyUnicode_KIND(v) == PyUnicode_KIND(w));
21467db96d56Sopenharmony_ci    assert(PyUnicode_KIND(v) == PyUnicode_1BYTE_KIND);
21477db96d56Sopenharmony_ci
21487db96d56Sopenharmony_ci    len = Py_MIN(PyUnicode_GET_LENGTH(v), PyUnicode_GET_LENGTH(w));
21497db96d56Sopenharmony_ci    res = memcmp(PyUnicode_DATA(v), PyUnicode_DATA(w), len);
21507db96d56Sopenharmony_ci
21517db96d56Sopenharmony_ci    res = (res != 0 ?
21527db96d56Sopenharmony_ci           res < 0 :
21537db96d56Sopenharmony_ci           PyUnicode_GET_LENGTH(v) < PyUnicode_GET_LENGTH(w));
21547db96d56Sopenharmony_ci
21557db96d56Sopenharmony_ci    assert(res == PyObject_RichCompareBool(v, w, Py_LT));;
21567db96d56Sopenharmony_ci    return res;
21577db96d56Sopenharmony_ci}
21587db96d56Sopenharmony_ci
21597db96d56Sopenharmony_ci/* Bounded int compare: compare any two longs that fit in a single machine word. */
21607db96d56Sopenharmony_cistatic int
21617db96d56Sopenharmony_ciunsafe_long_compare(PyObject *v, PyObject *w, MergeState *ms)
21627db96d56Sopenharmony_ci{
21637db96d56Sopenharmony_ci    PyLongObject *vl, *wl; sdigit v0, w0; int res;
21647db96d56Sopenharmony_ci
21657db96d56Sopenharmony_ci    /* Modified from Objects/longobject.c:long_compare, assuming: */
21667db96d56Sopenharmony_ci    assert(Py_IS_TYPE(v, &PyLong_Type));
21677db96d56Sopenharmony_ci    assert(Py_IS_TYPE(w, &PyLong_Type));
21687db96d56Sopenharmony_ci    assert(Py_ABS(Py_SIZE(v)) <= 1);
21697db96d56Sopenharmony_ci    assert(Py_ABS(Py_SIZE(w)) <= 1);
21707db96d56Sopenharmony_ci
21717db96d56Sopenharmony_ci    vl = (PyLongObject*)v;
21727db96d56Sopenharmony_ci    wl = (PyLongObject*)w;
21737db96d56Sopenharmony_ci
21747db96d56Sopenharmony_ci    v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->ob_digit[0];
21757db96d56Sopenharmony_ci    w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->ob_digit[0];
21767db96d56Sopenharmony_ci
21777db96d56Sopenharmony_ci    if (Py_SIZE(vl) < 0)
21787db96d56Sopenharmony_ci        v0 = -v0;
21797db96d56Sopenharmony_ci    if (Py_SIZE(wl) < 0)
21807db96d56Sopenharmony_ci        w0 = -w0;
21817db96d56Sopenharmony_ci
21827db96d56Sopenharmony_ci    res = v0 < w0;
21837db96d56Sopenharmony_ci    assert(res == PyObject_RichCompareBool(v, w, Py_LT));
21847db96d56Sopenharmony_ci    return res;
21857db96d56Sopenharmony_ci}
21867db96d56Sopenharmony_ci
21877db96d56Sopenharmony_ci/* Float compare: compare any two floats. */
21887db96d56Sopenharmony_cistatic int
21897db96d56Sopenharmony_ciunsafe_float_compare(PyObject *v, PyObject *w, MergeState *ms)
21907db96d56Sopenharmony_ci{
21917db96d56Sopenharmony_ci    int res;
21927db96d56Sopenharmony_ci
21937db96d56Sopenharmony_ci    /* Modified from Objects/floatobject.c:float_richcompare, assuming: */
21947db96d56Sopenharmony_ci    assert(Py_IS_TYPE(v, &PyFloat_Type));
21957db96d56Sopenharmony_ci    assert(Py_IS_TYPE(w, &PyFloat_Type));
21967db96d56Sopenharmony_ci
21977db96d56Sopenharmony_ci    res = PyFloat_AS_DOUBLE(v) < PyFloat_AS_DOUBLE(w);
21987db96d56Sopenharmony_ci    assert(res == PyObject_RichCompareBool(v, w, Py_LT));
21997db96d56Sopenharmony_ci    return res;
22007db96d56Sopenharmony_ci}
22017db96d56Sopenharmony_ci
22027db96d56Sopenharmony_ci/* Tuple compare: compare *any* two tuples, using
22037db96d56Sopenharmony_ci * ms->tuple_elem_compare to compare the first elements, which is set
22047db96d56Sopenharmony_ci * using the same pre-sort check as we use for ms->key_compare,
22057db96d56Sopenharmony_ci * but run on the list [x[0] for x in L]. This allows us to optimize compares
22067db96d56Sopenharmony_ci * on two levels (as long as [x[0] for x in L] is type-homogeneous.) The idea is
22077db96d56Sopenharmony_ci * that most tuple compares don't involve x[1:]. */
22087db96d56Sopenharmony_cistatic int
22097db96d56Sopenharmony_ciunsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms)
22107db96d56Sopenharmony_ci{
22117db96d56Sopenharmony_ci    PyTupleObject *vt, *wt;
22127db96d56Sopenharmony_ci    Py_ssize_t i, vlen, wlen;
22137db96d56Sopenharmony_ci    int k;
22147db96d56Sopenharmony_ci
22157db96d56Sopenharmony_ci    /* Modified from Objects/tupleobject.c:tuplerichcompare, assuming: */
22167db96d56Sopenharmony_ci    assert(Py_IS_TYPE(v, &PyTuple_Type));
22177db96d56Sopenharmony_ci    assert(Py_IS_TYPE(w, &PyTuple_Type));
22187db96d56Sopenharmony_ci    assert(Py_SIZE(v) > 0);
22197db96d56Sopenharmony_ci    assert(Py_SIZE(w) > 0);
22207db96d56Sopenharmony_ci
22217db96d56Sopenharmony_ci    vt = (PyTupleObject *)v;
22227db96d56Sopenharmony_ci    wt = (PyTupleObject *)w;
22237db96d56Sopenharmony_ci
22247db96d56Sopenharmony_ci    vlen = Py_SIZE(vt);
22257db96d56Sopenharmony_ci    wlen = Py_SIZE(wt);
22267db96d56Sopenharmony_ci
22277db96d56Sopenharmony_ci    for (i = 0; i < vlen && i < wlen; i++) {
22287db96d56Sopenharmony_ci        k = PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_EQ);
22297db96d56Sopenharmony_ci        if (k < 0)
22307db96d56Sopenharmony_ci            return -1;
22317db96d56Sopenharmony_ci        if (!k)
22327db96d56Sopenharmony_ci            break;
22337db96d56Sopenharmony_ci    }
22347db96d56Sopenharmony_ci
22357db96d56Sopenharmony_ci    if (i >= vlen || i >= wlen)
22367db96d56Sopenharmony_ci        return vlen < wlen;
22377db96d56Sopenharmony_ci
22387db96d56Sopenharmony_ci    if (i == 0)
22397db96d56Sopenharmony_ci        return ms->tuple_elem_compare(vt->ob_item[i], wt->ob_item[i], ms);
22407db96d56Sopenharmony_ci    else
22417db96d56Sopenharmony_ci        return PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_LT);
22427db96d56Sopenharmony_ci}
22437db96d56Sopenharmony_ci
22447db96d56Sopenharmony_ci/* An adaptive, stable, natural mergesort.  See listsort.txt.
22457db96d56Sopenharmony_ci * Returns Py_None on success, NULL on error.  Even in case of error, the
22467db96d56Sopenharmony_ci * list will be some permutation of its input state (nothing is lost or
22477db96d56Sopenharmony_ci * duplicated).
22487db96d56Sopenharmony_ci */
22497db96d56Sopenharmony_ci/*[clinic input]
22507db96d56Sopenharmony_cilist.sort
22517db96d56Sopenharmony_ci
22527db96d56Sopenharmony_ci    *
22537db96d56Sopenharmony_ci    key as keyfunc: object = None
22547db96d56Sopenharmony_ci    reverse: bool(accept={int}) = False
22557db96d56Sopenharmony_ci
22567db96d56Sopenharmony_ciSort the list in ascending order and return None.
22577db96d56Sopenharmony_ci
22587db96d56Sopenharmony_ciThe sort is in-place (i.e. the list itself is modified) and stable (i.e. the
22597db96d56Sopenharmony_ciorder of two equal elements is maintained).
22607db96d56Sopenharmony_ci
22617db96d56Sopenharmony_ciIf a key function is given, apply it once to each list item and sort them,
22627db96d56Sopenharmony_ciascending or descending, according to their function values.
22637db96d56Sopenharmony_ci
22647db96d56Sopenharmony_ciThe reverse flag can be set to sort in descending order.
22657db96d56Sopenharmony_ci[clinic start generated code]*/
22667db96d56Sopenharmony_ci
22677db96d56Sopenharmony_cistatic PyObject *
22687db96d56Sopenharmony_cilist_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
22697db96d56Sopenharmony_ci/*[clinic end generated code: output=57b9f9c5e23fbe42 input=cb56cd179a713060]*/
22707db96d56Sopenharmony_ci{
22717db96d56Sopenharmony_ci    MergeState ms;
22727db96d56Sopenharmony_ci    Py_ssize_t nremaining;
22737db96d56Sopenharmony_ci    Py_ssize_t minrun;
22747db96d56Sopenharmony_ci    sortslice lo;
22757db96d56Sopenharmony_ci    Py_ssize_t saved_ob_size, saved_allocated;
22767db96d56Sopenharmony_ci    PyObject **saved_ob_item;
22777db96d56Sopenharmony_ci    PyObject **final_ob_item;
22787db96d56Sopenharmony_ci    PyObject *result = NULL;            /* guilty until proved innocent */
22797db96d56Sopenharmony_ci    Py_ssize_t i;
22807db96d56Sopenharmony_ci    PyObject **keys;
22817db96d56Sopenharmony_ci
22827db96d56Sopenharmony_ci    assert(self != NULL);
22837db96d56Sopenharmony_ci    assert(PyList_Check(self));
22847db96d56Sopenharmony_ci    if (keyfunc == Py_None)
22857db96d56Sopenharmony_ci        keyfunc = NULL;
22867db96d56Sopenharmony_ci
22877db96d56Sopenharmony_ci    /* The list is temporarily made empty, so that mutations performed
22887db96d56Sopenharmony_ci     * by comparison functions can't affect the slice of memory we're
22897db96d56Sopenharmony_ci     * sorting (allowing mutations during sorting is a core-dump
22907db96d56Sopenharmony_ci     * factory, since ob_item may change).
22917db96d56Sopenharmony_ci     */
22927db96d56Sopenharmony_ci    saved_ob_size = Py_SIZE(self);
22937db96d56Sopenharmony_ci    saved_ob_item = self->ob_item;
22947db96d56Sopenharmony_ci    saved_allocated = self->allocated;
22957db96d56Sopenharmony_ci    Py_SET_SIZE(self, 0);
22967db96d56Sopenharmony_ci    self->ob_item = NULL;
22977db96d56Sopenharmony_ci    self->allocated = -1; /* any operation will reset it to >= 0 */
22987db96d56Sopenharmony_ci
22997db96d56Sopenharmony_ci    if (keyfunc == NULL) {
23007db96d56Sopenharmony_ci        keys = NULL;
23017db96d56Sopenharmony_ci        lo.keys = saved_ob_item;
23027db96d56Sopenharmony_ci        lo.values = NULL;
23037db96d56Sopenharmony_ci    }
23047db96d56Sopenharmony_ci    else {
23057db96d56Sopenharmony_ci        if (saved_ob_size < MERGESTATE_TEMP_SIZE/2)
23067db96d56Sopenharmony_ci            /* Leverage stack space we allocated but won't otherwise use */
23077db96d56Sopenharmony_ci            keys = &ms.temparray[saved_ob_size+1];
23087db96d56Sopenharmony_ci        else {
23097db96d56Sopenharmony_ci            keys = PyMem_Malloc(sizeof(PyObject *) * saved_ob_size);
23107db96d56Sopenharmony_ci            if (keys == NULL) {
23117db96d56Sopenharmony_ci                PyErr_NoMemory();
23127db96d56Sopenharmony_ci                goto keyfunc_fail;
23137db96d56Sopenharmony_ci            }
23147db96d56Sopenharmony_ci        }
23157db96d56Sopenharmony_ci
23167db96d56Sopenharmony_ci        for (i = 0; i < saved_ob_size ; i++) {
23177db96d56Sopenharmony_ci            keys[i] = PyObject_CallOneArg(keyfunc, saved_ob_item[i]);
23187db96d56Sopenharmony_ci            if (keys[i] == NULL) {
23197db96d56Sopenharmony_ci                for (i=i-1 ; i>=0 ; i--)
23207db96d56Sopenharmony_ci                    Py_DECREF(keys[i]);
23217db96d56Sopenharmony_ci                if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2)
23227db96d56Sopenharmony_ci                    PyMem_Free(keys);
23237db96d56Sopenharmony_ci                goto keyfunc_fail;
23247db96d56Sopenharmony_ci            }
23257db96d56Sopenharmony_ci        }
23267db96d56Sopenharmony_ci
23277db96d56Sopenharmony_ci        lo.keys = keys;
23287db96d56Sopenharmony_ci        lo.values = saved_ob_item;
23297db96d56Sopenharmony_ci    }
23307db96d56Sopenharmony_ci
23317db96d56Sopenharmony_ci
23327db96d56Sopenharmony_ci    /* The pre-sort check: here's where we decide which compare function to use.
23337db96d56Sopenharmony_ci     * How much optimization is safe? We test for homogeneity with respect to
23347db96d56Sopenharmony_ci     * several properties that are expensive to check at compare-time, and
23357db96d56Sopenharmony_ci     * set ms appropriately. */
23367db96d56Sopenharmony_ci    if (saved_ob_size > 1) {
23377db96d56Sopenharmony_ci        /* Assume the first element is representative of the whole list. */
23387db96d56Sopenharmony_ci        int keys_are_in_tuples = (Py_IS_TYPE(lo.keys[0], &PyTuple_Type) &&
23397db96d56Sopenharmony_ci                                  Py_SIZE(lo.keys[0]) > 0);
23407db96d56Sopenharmony_ci
23417db96d56Sopenharmony_ci        PyTypeObject* key_type = (keys_are_in_tuples ?
23427db96d56Sopenharmony_ci                                  Py_TYPE(PyTuple_GET_ITEM(lo.keys[0], 0)) :
23437db96d56Sopenharmony_ci                                  Py_TYPE(lo.keys[0]));
23447db96d56Sopenharmony_ci
23457db96d56Sopenharmony_ci        int keys_are_all_same_type = 1;
23467db96d56Sopenharmony_ci        int strings_are_latin = 1;
23477db96d56Sopenharmony_ci        int ints_are_bounded = 1;
23487db96d56Sopenharmony_ci
23497db96d56Sopenharmony_ci        /* Prove that assumption by checking every key. */
23507db96d56Sopenharmony_ci        for (i=0; i < saved_ob_size; i++) {
23517db96d56Sopenharmony_ci
23527db96d56Sopenharmony_ci            if (keys_are_in_tuples &&
23537db96d56Sopenharmony_ci                !(Py_IS_TYPE(lo.keys[i], &PyTuple_Type) && Py_SIZE(lo.keys[i]) != 0)) {
23547db96d56Sopenharmony_ci                keys_are_in_tuples = 0;
23557db96d56Sopenharmony_ci                keys_are_all_same_type = 0;
23567db96d56Sopenharmony_ci                break;
23577db96d56Sopenharmony_ci            }
23587db96d56Sopenharmony_ci
23597db96d56Sopenharmony_ci            /* Note: for lists of tuples, key is the first element of the tuple
23607db96d56Sopenharmony_ci             * lo.keys[i], not lo.keys[i] itself! We verify type-homogeneity
23617db96d56Sopenharmony_ci             * for lists of tuples in the if-statement directly above. */
23627db96d56Sopenharmony_ci            PyObject *key = (keys_are_in_tuples ?
23637db96d56Sopenharmony_ci                             PyTuple_GET_ITEM(lo.keys[i], 0) :
23647db96d56Sopenharmony_ci                             lo.keys[i]);
23657db96d56Sopenharmony_ci
23667db96d56Sopenharmony_ci            if (!Py_IS_TYPE(key, key_type)) {
23677db96d56Sopenharmony_ci                keys_are_all_same_type = 0;
23687db96d56Sopenharmony_ci                /* If keys are in tuple we must loop over the whole list to make
23697db96d56Sopenharmony_ci                   sure all items are tuples */
23707db96d56Sopenharmony_ci                if (!keys_are_in_tuples) {
23717db96d56Sopenharmony_ci                    break;
23727db96d56Sopenharmony_ci                }
23737db96d56Sopenharmony_ci            }
23747db96d56Sopenharmony_ci
23757db96d56Sopenharmony_ci            if (keys_are_all_same_type) {
23767db96d56Sopenharmony_ci                if (key_type == &PyLong_Type &&
23777db96d56Sopenharmony_ci                    ints_are_bounded &&
23787db96d56Sopenharmony_ci                    Py_ABS(Py_SIZE(key)) > 1) {
23797db96d56Sopenharmony_ci
23807db96d56Sopenharmony_ci                    ints_are_bounded = 0;
23817db96d56Sopenharmony_ci                }
23827db96d56Sopenharmony_ci                else if (key_type == &PyUnicode_Type &&
23837db96d56Sopenharmony_ci                         strings_are_latin &&
23847db96d56Sopenharmony_ci                         PyUnicode_KIND(key) != PyUnicode_1BYTE_KIND) {
23857db96d56Sopenharmony_ci
23867db96d56Sopenharmony_ci                        strings_are_latin = 0;
23877db96d56Sopenharmony_ci                    }
23887db96d56Sopenharmony_ci                }
23897db96d56Sopenharmony_ci            }
23907db96d56Sopenharmony_ci
23917db96d56Sopenharmony_ci        /* Choose the best compare, given what we now know about the keys. */
23927db96d56Sopenharmony_ci        if (keys_are_all_same_type) {
23937db96d56Sopenharmony_ci
23947db96d56Sopenharmony_ci            if (key_type == &PyUnicode_Type && strings_are_latin) {
23957db96d56Sopenharmony_ci                ms.key_compare = unsafe_latin_compare;
23967db96d56Sopenharmony_ci            }
23977db96d56Sopenharmony_ci            else if (key_type == &PyLong_Type && ints_are_bounded) {
23987db96d56Sopenharmony_ci                ms.key_compare = unsafe_long_compare;
23997db96d56Sopenharmony_ci            }
24007db96d56Sopenharmony_ci            else if (key_type == &PyFloat_Type) {
24017db96d56Sopenharmony_ci                ms.key_compare = unsafe_float_compare;
24027db96d56Sopenharmony_ci            }
24037db96d56Sopenharmony_ci            else if ((ms.key_richcompare = key_type->tp_richcompare) != NULL) {
24047db96d56Sopenharmony_ci                ms.key_compare = unsafe_object_compare;
24057db96d56Sopenharmony_ci            }
24067db96d56Sopenharmony_ci            else {
24077db96d56Sopenharmony_ci                ms.key_compare = safe_object_compare;
24087db96d56Sopenharmony_ci            }
24097db96d56Sopenharmony_ci        }
24107db96d56Sopenharmony_ci        else {
24117db96d56Sopenharmony_ci            ms.key_compare = safe_object_compare;
24127db96d56Sopenharmony_ci        }
24137db96d56Sopenharmony_ci
24147db96d56Sopenharmony_ci        if (keys_are_in_tuples) {
24157db96d56Sopenharmony_ci            /* Make sure we're not dealing with tuples of tuples
24167db96d56Sopenharmony_ci             * (remember: here, key_type refers list [key[0] for key in keys]) */
24177db96d56Sopenharmony_ci            if (key_type == &PyTuple_Type) {
24187db96d56Sopenharmony_ci                ms.tuple_elem_compare = safe_object_compare;
24197db96d56Sopenharmony_ci            }
24207db96d56Sopenharmony_ci            else {
24217db96d56Sopenharmony_ci                ms.tuple_elem_compare = ms.key_compare;
24227db96d56Sopenharmony_ci            }
24237db96d56Sopenharmony_ci
24247db96d56Sopenharmony_ci            ms.key_compare = unsafe_tuple_compare;
24257db96d56Sopenharmony_ci        }
24267db96d56Sopenharmony_ci    }
24277db96d56Sopenharmony_ci    /* End of pre-sort check: ms is now set properly! */
24287db96d56Sopenharmony_ci
24297db96d56Sopenharmony_ci    merge_init(&ms, saved_ob_size, keys != NULL, &lo);
24307db96d56Sopenharmony_ci
24317db96d56Sopenharmony_ci    nremaining = saved_ob_size;
24327db96d56Sopenharmony_ci    if (nremaining < 2)
24337db96d56Sopenharmony_ci        goto succeed;
24347db96d56Sopenharmony_ci
24357db96d56Sopenharmony_ci    /* Reverse sort stability achieved by initially reversing the list,
24367db96d56Sopenharmony_ci    applying a stable forward sort, then reversing the final result. */
24377db96d56Sopenharmony_ci    if (reverse) {
24387db96d56Sopenharmony_ci        if (keys != NULL)
24397db96d56Sopenharmony_ci            reverse_slice(&keys[0], &keys[saved_ob_size]);
24407db96d56Sopenharmony_ci        reverse_slice(&saved_ob_item[0], &saved_ob_item[saved_ob_size]);
24417db96d56Sopenharmony_ci    }
24427db96d56Sopenharmony_ci
24437db96d56Sopenharmony_ci    /* March over the array once, left to right, finding natural runs,
24447db96d56Sopenharmony_ci     * and extending short natural runs to minrun elements.
24457db96d56Sopenharmony_ci     */
24467db96d56Sopenharmony_ci    minrun = merge_compute_minrun(nremaining);
24477db96d56Sopenharmony_ci    do {
24487db96d56Sopenharmony_ci        int descending;
24497db96d56Sopenharmony_ci        Py_ssize_t n;
24507db96d56Sopenharmony_ci
24517db96d56Sopenharmony_ci        /* Identify next run. */
24527db96d56Sopenharmony_ci        n = count_run(&ms, lo.keys, lo.keys + nremaining, &descending);
24537db96d56Sopenharmony_ci        if (n < 0)
24547db96d56Sopenharmony_ci            goto fail;
24557db96d56Sopenharmony_ci        if (descending)
24567db96d56Sopenharmony_ci            reverse_sortslice(&lo, n);
24577db96d56Sopenharmony_ci        /* If short, extend to min(minrun, nremaining). */
24587db96d56Sopenharmony_ci        if (n < minrun) {
24597db96d56Sopenharmony_ci            const Py_ssize_t force = nremaining <= minrun ?
24607db96d56Sopenharmony_ci                              nremaining : minrun;
24617db96d56Sopenharmony_ci            if (binarysort(&ms, lo, lo.keys + force, lo.keys + n) < 0)
24627db96d56Sopenharmony_ci                goto fail;
24637db96d56Sopenharmony_ci            n = force;
24647db96d56Sopenharmony_ci        }
24657db96d56Sopenharmony_ci        /* Maybe merge pending runs. */
24667db96d56Sopenharmony_ci        assert(ms.n == 0 || ms.pending[ms.n -1].base.keys +
24677db96d56Sopenharmony_ci                            ms.pending[ms.n-1].len == lo.keys);
24687db96d56Sopenharmony_ci        if (found_new_run(&ms, n) < 0)
24697db96d56Sopenharmony_ci            goto fail;
24707db96d56Sopenharmony_ci        /* Push new run on stack. */
24717db96d56Sopenharmony_ci        assert(ms.n < MAX_MERGE_PENDING);
24727db96d56Sopenharmony_ci        ms.pending[ms.n].base = lo;
24737db96d56Sopenharmony_ci        ms.pending[ms.n].len = n;
24747db96d56Sopenharmony_ci        ++ms.n;
24757db96d56Sopenharmony_ci        /* Advance to find next run. */
24767db96d56Sopenharmony_ci        sortslice_advance(&lo, n);
24777db96d56Sopenharmony_ci        nremaining -= n;
24787db96d56Sopenharmony_ci    } while (nremaining);
24797db96d56Sopenharmony_ci
24807db96d56Sopenharmony_ci    if (merge_force_collapse(&ms) < 0)
24817db96d56Sopenharmony_ci        goto fail;
24827db96d56Sopenharmony_ci    assert(ms.n == 1);
24837db96d56Sopenharmony_ci    assert(keys == NULL
24847db96d56Sopenharmony_ci           ? ms.pending[0].base.keys == saved_ob_item
24857db96d56Sopenharmony_ci           : ms.pending[0].base.keys == &keys[0]);
24867db96d56Sopenharmony_ci    assert(ms.pending[0].len == saved_ob_size);
24877db96d56Sopenharmony_ci    lo = ms.pending[0].base;
24887db96d56Sopenharmony_ci
24897db96d56Sopenharmony_cisucceed:
24907db96d56Sopenharmony_ci    result = Py_None;
24917db96d56Sopenharmony_cifail:
24927db96d56Sopenharmony_ci    if (keys != NULL) {
24937db96d56Sopenharmony_ci        for (i = 0; i < saved_ob_size; i++)
24947db96d56Sopenharmony_ci            Py_DECREF(keys[i]);
24957db96d56Sopenharmony_ci        if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2)
24967db96d56Sopenharmony_ci            PyMem_Free(keys);
24977db96d56Sopenharmony_ci    }
24987db96d56Sopenharmony_ci
24997db96d56Sopenharmony_ci    if (self->allocated != -1 && result != NULL) {
25007db96d56Sopenharmony_ci        /* The user mucked with the list during the sort,
25017db96d56Sopenharmony_ci         * and we don't already have another error to report.
25027db96d56Sopenharmony_ci         */
25037db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "list modified during sort");
25047db96d56Sopenharmony_ci        result = NULL;
25057db96d56Sopenharmony_ci    }
25067db96d56Sopenharmony_ci
25077db96d56Sopenharmony_ci    if (reverse && saved_ob_size > 1)
25087db96d56Sopenharmony_ci        reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
25097db96d56Sopenharmony_ci
25107db96d56Sopenharmony_ci    merge_freemem(&ms);
25117db96d56Sopenharmony_ci
25127db96d56Sopenharmony_cikeyfunc_fail:
25137db96d56Sopenharmony_ci    final_ob_item = self->ob_item;
25147db96d56Sopenharmony_ci    i = Py_SIZE(self);
25157db96d56Sopenharmony_ci    Py_SET_SIZE(self, saved_ob_size);
25167db96d56Sopenharmony_ci    self->ob_item = saved_ob_item;
25177db96d56Sopenharmony_ci    self->allocated = saved_allocated;
25187db96d56Sopenharmony_ci    if (final_ob_item != NULL) {
25197db96d56Sopenharmony_ci        /* we cannot use _list_clear() for this because it does not
25207db96d56Sopenharmony_ci           guarantee that the list is really empty when it returns */
25217db96d56Sopenharmony_ci        while (--i >= 0) {
25227db96d56Sopenharmony_ci            Py_XDECREF(final_ob_item[i]);
25237db96d56Sopenharmony_ci        }
25247db96d56Sopenharmony_ci        PyMem_Free(final_ob_item);
25257db96d56Sopenharmony_ci    }
25267db96d56Sopenharmony_ci    Py_XINCREF(result);
25277db96d56Sopenharmony_ci    return result;
25287db96d56Sopenharmony_ci}
25297db96d56Sopenharmony_ci#undef IFLT
25307db96d56Sopenharmony_ci#undef ISLT
25317db96d56Sopenharmony_ci
25327db96d56Sopenharmony_ciint
25337db96d56Sopenharmony_ciPyList_Sort(PyObject *v)
25347db96d56Sopenharmony_ci{
25357db96d56Sopenharmony_ci    if (v == NULL || !PyList_Check(v)) {
25367db96d56Sopenharmony_ci        PyErr_BadInternalCall();
25377db96d56Sopenharmony_ci        return -1;
25387db96d56Sopenharmony_ci    }
25397db96d56Sopenharmony_ci    v = list_sort_impl((PyListObject *)v, NULL, 0);
25407db96d56Sopenharmony_ci    if (v == NULL)
25417db96d56Sopenharmony_ci        return -1;
25427db96d56Sopenharmony_ci    Py_DECREF(v);
25437db96d56Sopenharmony_ci    return 0;
25447db96d56Sopenharmony_ci}
25457db96d56Sopenharmony_ci
25467db96d56Sopenharmony_ci/*[clinic input]
25477db96d56Sopenharmony_cilist.reverse
25487db96d56Sopenharmony_ci
25497db96d56Sopenharmony_ciReverse *IN PLACE*.
25507db96d56Sopenharmony_ci[clinic start generated code]*/
25517db96d56Sopenharmony_ci
25527db96d56Sopenharmony_cistatic PyObject *
25537db96d56Sopenharmony_cilist_reverse_impl(PyListObject *self)
25547db96d56Sopenharmony_ci/*[clinic end generated code: output=482544fc451abea9 input=eefd4c3ae1bc9887]*/
25557db96d56Sopenharmony_ci{
25567db96d56Sopenharmony_ci    if (Py_SIZE(self) > 1)
25577db96d56Sopenharmony_ci        reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
25587db96d56Sopenharmony_ci    Py_RETURN_NONE;
25597db96d56Sopenharmony_ci}
25607db96d56Sopenharmony_ci
25617db96d56Sopenharmony_ciint
25627db96d56Sopenharmony_ciPyList_Reverse(PyObject *v)
25637db96d56Sopenharmony_ci{
25647db96d56Sopenharmony_ci    PyListObject *self = (PyListObject *)v;
25657db96d56Sopenharmony_ci
25667db96d56Sopenharmony_ci    if (v == NULL || !PyList_Check(v)) {
25677db96d56Sopenharmony_ci        PyErr_BadInternalCall();
25687db96d56Sopenharmony_ci        return -1;
25697db96d56Sopenharmony_ci    }
25707db96d56Sopenharmony_ci    if (Py_SIZE(self) > 1)
25717db96d56Sopenharmony_ci        reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
25727db96d56Sopenharmony_ci    return 0;
25737db96d56Sopenharmony_ci}
25747db96d56Sopenharmony_ci
25757db96d56Sopenharmony_ciPyObject *
25767db96d56Sopenharmony_ciPyList_AsTuple(PyObject *v)
25777db96d56Sopenharmony_ci{
25787db96d56Sopenharmony_ci    if (v == NULL || !PyList_Check(v)) {
25797db96d56Sopenharmony_ci        PyErr_BadInternalCall();
25807db96d56Sopenharmony_ci        return NULL;
25817db96d56Sopenharmony_ci    }
25827db96d56Sopenharmony_ci    return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
25837db96d56Sopenharmony_ci}
25847db96d56Sopenharmony_ci
25857db96d56Sopenharmony_ci/*[clinic input]
25867db96d56Sopenharmony_cilist.index
25877db96d56Sopenharmony_ci
25887db96d56Sopenharmony_ci    value: object
25897db96d56Sopenharmony_ci    start: slice_index(accept={int}) = 0
25907db96d56Sopenharmony_ci    stop: slice_index(accept={int}, c_default="PY_SSIZE_T_MAX") = sys.maxsize
25917db96d56Sopenharmony_ci    /
25927db96d56Sopenharmony_ci
25937db96d56Sopenharmony_ciReturn first index of value.
25947db96d56Sopenharmony_ci
25957db96d56Sopenharmony_ciRaises ValueError if the value is not present.
25967db96d56Sopenharmony_ci[clinic start generated code]*/
25977db96d56Sopenharmony_ci
25987db96d56Sopenharmony_cistatic PyObject *
25997db96d56Sopenharmony_cilist_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start,
26007db96d56Sopenharmony_ci                Py_ssize_t stop)
26017db96d56Sopenharmony_ci/*[clinic end generated code: output=ec51b88787e4e481 input=40ec5826303a0eb1]*/
26027db96d56Sopenharmony_ci{
26037db96d56Sopenharmony_ci    Py_ssize_t i;
26047db96d56Sopenharmony_ci
26057db96d56Sopenharmony_ci    if (start < 0) {
26067db96d56Sopenharmony_ci        start += Py_SIZE(self);
26077db96d56Sopenharmony_ci        if (start < 0)
26087db96d56Sopenharmony_ci            start = 0;
26097db96d56Sopenharmony_ci    }
26107db96d56Sopenharmony_ci    if (stop < 0) {
26117db96d56Sopenharmony_ci        stop += Py_SIZE(self);
26127db96d56Sopenharmony_ci        if (stop < 0)
26137db96d56Sopenharmony_ci            stop = 0;
26147db96d56Sopenharmony_ci    }
26157db96d56Sopenharmony_ci    for (i = start; i < stop && i < Py_SIZE(self); i++) {
26167db96d56Sopenharmony_ci        PyObject *obj = self->ob_item[i];
26177db96d56Sopenharmony_ci        Py_INCREF(obj);
26187db96d56Sopenharmony_ci        int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
26197db96d56Sopenharmony_ci        Py_DECREF(obj);
26207db96d56Sopenharmony_ci        if (cmp > 0)
26217db96d56Sopenharmony_ci            return PyLong_FromSsize_t(i);
26227db96d56Sopenharmony_ci        else if (cmp < 0)
26237db96d56Sopenharmony_ci            return NULL;
26247db96d56Sopenharmony_ci    }
26257db96d56Sopenharmony_ci    PyErr_Format(PyExc_ValueError, "%R is not in list", value);
26267db96d56Sopenharmony_ci    return NULL;
26277db96d56Sopenharmony_ci}
26287db96d56Sopenharmony_ci
26297db96d56Sopenharmony_ci/*[clinic input]
26307db96d56Sopenharmony_cilist.count
26317db96d56Sopenharmony_ci
26327db96d56Sopenharmony_ci     value: object
26337db96d56Sopenharmony_ci     /
26347db96d56Sopenharmony_ci
26357db96d56Sopenharmony_ciReturn number of occurrences of value.
26367db96d56Sopenharmony_ci[clinic start generated code]*/
26377db96d56Sopenharmony_ci
26387db96d56Sopenharmony_cistatic PyObject *
26397db96d56Sopenharmony_cilist_count(PyListObject *self, PyObject *value)
26407db96d56Sopenharmony_ci/*[clinic end generated code: output=b1f5d284205ae714 input=3bdc3a5e6f749565]*/
26417db96d56Sopenharmony_ci{
26427db96d56Sopenharmony_ci    Py_ssize_t count = 0;
26437db96d56Sopenharmony_ci    Py_ssize_t i;
26447db96d56Sopenharmony_ci
26457db96d56Sopenharmony_ci    for (i = 0; i < Py_SIZE(self); i++) {
26467db96d56Sopenharmony_ci        PyObject *obj = self->ob_item[i];
26477db96d56Sopenharmony_ci        if (obj == value) {
26487db96d56Sopenharmony_ci           count++;
26497db96d56Sopenharmony_ci           continue;
26507db96d56Sopenharmony_ci        }
26517db96d56Sopenharmony_ci        Py_INCREF(obj);
26527db96d56Sopenharmony_ci        int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
26537db96d56Sopenharmony_ci        Py_DECREF(obj);
26547db96d56Sopenharmony_ci        if (cmp > 0)
26557db96d56Sopenharmony_ci            count++;
26567db96d56Sopenharmony_ci        else if (cmp < 0)
26577db96d56Sopenharmony_ci            return NULL;
26587db96d56Sopenharmony_ci    }
26597db96d56Sopenharmony_ci    return PyLong_FromSsize_t(count);
26607db96d56Sopenharmony_ci}
26617db96d56Sopenharmony_ci
26627db96d56Sopenharmony_ci/*[clinic input]
26637db96d56Sopenharmony_cilist.remove
26647db96d56Sopenharmony_ci
26657db96d56Sopenharmony_ci     value: object
26667db96d56Sopenharmony_ci     /
26677db96d56Sopenharmony_ci
26687db96d56Sopenharmony_ciRemove first occurrence of value.
26697db96d56Sopenharmony_ci
26707db96d56Sopenharmony_ciRaises ValueError if the value is not present.
26717db96d56Sopenharmony_ci[clinic start generated code]*/
26727db96d56Sopenharmony_ci
26737db96d56Sopenharmony_cistatic PyObject *
26747db96d56Sopenharmony_cilist_remove(PyListObject *self, PyObject *value)
26757db96d56Sopenharmony_ci/*[clinic end generated code: output=f087e1951a5e30d1 input=2dc2ba5bb2fb1f82]*/
26767db96d56Sopenharmony_ci{
26777db96d56Sopenharmony_ci    Py_ssize_t i;
26787db96d56Sopenharmony_ci
26797db96d56Sopenharmony_ci    for (i = 0; i < Py_SIZE(self); i++) {
26807db96d56Sopenharmony_ci        PyObject *obj = self->ob_item[i];
26817db96d56Sopenharmony_ci        Py_INCREF(obj);
26827db96d56Sopenharmony_ci        int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
26837db96d56Sopenharmony_ci        Py_DECREF(obj);
26847db96d56Sopenharmony_ci        if (cmp > 0) {
26857db96d56Sopenharmony_ci            if (list_ass_slice(self, i, i+1,
26867db96d56Sopenharmony_ci                               (PyObject *)NULL) == 0)
26877db96d56Sopenharmony_ci                Py_RETURN_NONE;
26887db96d56Sopenharmony_ci            return NULL;
26897db96d56Sopenharmony_ci        }
26907db96d56Sopenharmony_ci        else if (cmp < 0)
26917db96d56Sopenharmony_ci            return NULL;
26927db96d56Sopenharmony_ci    }
26937db96d56Sopenharmony_ci    PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list");
26947db96d56Sopenharmony_ci    return NULL;
26957db96d56Sopenharmony_ci}
26967db96d56Sopenharmony_ci
26977db96d56Sopenharmony_cistatic int
26987db96d56Sopenharmony_cilist_traverse(PyListObject *o, visitproc visit, void *arg)
26997db96d56Sopenharmony_ci{
27007db96d56Sopenharmony_ci    Py_ssize_t i;
27017db96d56Sopenharmony_ci
27027db96d56Sopenharmony_ci    for (i = Py_SIZE(o); --i >= 0; )
27037db96d56Sopenharmony_ci        Py_VISIT(o->ob_item[i]);
27047db96d56Sopenharmony_ci    return 0;
27057db96d56Sopenharmony_ci}
27067db96d56Sopenharmony_ci
27077db96d56Sopenharmony_cistatic PyObject *
27087db96d56Sopenharmony_cilist_richcompare(PyObject *v, PyObject *w, int op)
27097db96d56Sopenharmony_ci{
27107db96d56Sopenharmony_ci    PyListObject *vl, *wl;
27117db96d56Sopenharmony_ci    Py_ssize_t i;
27127db96d56Sopenharmony_ci
27137db96d56Sopenharmony_ci    if (!PyList_Check(v) || !PyList_Check(w))
27147db96d56Sopenharmony_ci        Py_RETURN_NOTIMPLEMENTED;
27157db96d56Sopenharmony_ci
27167db96d56Sopenharmony_ci    vl = (PyListObject *)v;
27177db96d56Sopenharmony_ci    wl = (PyListObject *)w;
27187db96d56Sopenharmony_ci
27197db96d56Sopenharmony_ci    if (Py_SIZE(vl) != Py_SIZE(wl) && (op == Py_EQ || op == Py_NE)) {
27207db96d56Sopenharmony_ci        /* Shortcut: if the lengths differ, the lists differ */
27217db96d56Sopenharmony_ci        if (op == Py_EQ)
27227db96d56Sopenharmony_ci            Py_RETURN_FALSE;
27237db96d56Sopenharmony_ci        else
27247db96d56Sopenharmony_ci            Py_RETURN_TRUE;
27257db96d56Sopenharmony_ci    }
27267db96d56Sopenharmony_ci
27277db96d56Sopenharmony_ci    /* Search for the first index where items are different */
27287db96d56Sopenharmony_ci    for (i = 0; i < Py_SIZE(vl) && i < Py_SIZE(wl); i++) {
27297db96d56Sopenharmony_ci        PyObject *vitem = vl->ob_item[i];
27307db96d56Sopenharmony_ci        PyObject *witem = wl->ob_item[i];
27317db96d56Sopenharmony_ci        if (vitem == witem) {
27327db96d56Sopenharmony_ci            continue;
27337db96d56Sopenharmony_ci        }
27347db96d56Sopenharmony_ci
27357db96d56Sopenharmony_ci        Py_INCREF(vitem);
27367db96d56Sopenharmony_ci        Py_INCREF(witem);
27377db96d56Sopenharmony_ci        int k = PyObject_RichCompareBool(vitem, witem, Py_EQ);
27387db96d56Sopenharmony_ci        Py_DECREF(vitem);
27397db96d56Sopenharmony_ci        Py_DECREF(witem);
27407db96d56Sopenharmony_ci        if (k < 0)
27417db96d56Sopenharmony_ci            return NULL;
27427db96d56Sopenharmony_ci        if (!k)
27437db96d56Sopenharmony_ci            break;
27447db96d56Sopenharmony_ci    }
27457db96d56Sopenharmony_ci
27467db96d56Sopenharmony_ci    if (i >= Py_SIZE(vl) || i >= Py_SIZE(wl)) {
27477db96d56Sopenharmony_ci        /* No more items to compare -- compare sizes */
27487db96d56Sopenharmony_ci        Py_RETURN_RICHCOMPARE(Py_SIZE(vl), Py_SIZE(wl), op);
27497db96d56Sopenharmony_ci    }
27507db96d56Sopenharmony_ci
27517db96d56Sopenharmony_ci    /* We have an item that differs -- shortcuts for EQ/NE */
27527db96d56Sopenharmony_ci    if (op == Py_EQ) {
27537db96d56Sopenharmony_ci        Py_RETURN_FALSE;
27547db96d56Sopenharmony_ci    }
27557db96d56Sopenharmony_ci    if (op == Py_NE) {
27567db96d56Sopenharmony_ci        Py_RETURN_TRUE;
27577db96d56Sopenharmony_ci    }
27587db96d56Sopenharmony_ci
27597db96d56Sopenharmony_ci    /* Compare the final item again using the proper operator */
27607db96d56Sopenharmony_ci    return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
27617db96d56Sopenharmony_ci}
27627db96d56Sopenharmony_ci
27637db96d56Sopenharmony_ci/*[clinic input]
27647db96d56Sopenharmony_cilist.__init__
27657db96d56Sopenharmony_ci
27667db96d56Sopenharmony_ci    iterable: object(c_default="NULL") = ()
27677db96d56Sopenharmony_ci    /
27687db96d56Sopenharmony_ci
27697db96d56Sopenharmony_ciBuilt-in mutable sequence.
27707db96d56Sopenharmony_ci
27717db96d56Sopenharmony_ciIf no argument is given, the constructor creates a new empty list.
27727db96d56Sopenharmony_ciThe argument must be an iterable if specified.
27737db96d56Sopenharmony_ci[clinic start generated code]*/
27747db96d56Sopenharmony_ci
27757db96d56Sopenharmony_cistatic int
27767db96d56Sopenharmony_cilist___init___impl(PyListObject *self, PyObject *iterable)
27777db96d56Sopenharmony_ci/*[clinic end generated code: output=0f3c21379d01de48 input=b3f3fe7206af8f6b]*/
27787db96d56Sopenharmony_ci{
27797db96d56Sopenharmony_ci    /* Verify list invariants established by PyType_GenericAlloc() */
27807db96d56Sopenharmony_ci    assert(0 <= Py_SIZE(self));
27817db96d56Sopenharmony_ci    assert(Py_SIZE(self) <= self->allocated || self->allocated == -1);
27827db96d56Sopenharmony_ci    assert(self->ob_item != NULL ||
27837db96d56Sopenharmony_ci           self->allocated == 0 || self->allocated == -1);
27847db96d56Sopenharmony_ci
27857db96d56Sopenharmony_ci    /* Empty previous contents */
27867db96d56Sopenharmony_ci    if (self->ob_item != NULL) {
27877db96d56Sopenharmony_ci        (void)_list_clear(self);
27887db96d56Sopenharmony_ci    }
27897db96d56Sopenharmony_ci    if (iterable != NULL) {
27907db96d56Sopenharmony_ci        PyObject *rv = list_extend(self, iterable);
27917db96d56Sopenharmony_ci        if (rv == NULL)
27927db96d56Sopenharmony_ci            return -1;
27937db96d56Sopenharmony_ci        Py_DECREF(rv);
27947db96d56Sopenharmony_ci    }
27957db96d56Sopenharmony_ci    return 0;
27967db96d56Sopenharmony_ci}
27977db96d56Sopenharmony_ci
27987db96d56Sopenharmony_cistatic PyObject *
27997db96d56Sopenharmony_cilist_vectorcall(PyObject *type, PyObject * const*args,
28007db96d56Sopenharmony_ci                size_t nargsf, PyObject *kwnames)
28017db96d56Sopenharmony_ci{
28027db96d56Sopenharmony_ci    if (!_PyArg_NoKwnames("list", kwnames)) {
28037db96d56Sopenharmony_ci        return NULL;
28047db96d56Sopenharmony_ci    }
28057db96d56Sopenharmony_ci    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
28067db96d56Sopenharmony_ci    if (!_PyArg_CheckPositional("list", nargs, 0, 1)) {
28077db96d56Sopenharmony_ci        return NULL;
28087db96d56Sopenharmony_ci    }
28097db96d56Sopenharmony_ci
28107db96d56Sopenharmony_ci    PyObject *list = PyType_GenericAlloc(_PyType_CAST(type), 0);
28117db96d56Sopenharmony_ci    if (list == NULL) {
28127db96d56Sopenharmony_ci        return NULL;
28137db96d56Sopenharmony_ci    }
28147db96d56Sopenharmony_ci    if (nargs) {
28157db96d56Sopenharmony_ci        if (list___init___impl((PyListObject *)list, args[0])) {
28167db96d56Sopenharmony_ci            Py_DECREF(list);
28177db96d56Sopenharmony_ci            return NULL;
28187db96d56Sopenharmony_ci        }
28197db96d56Sopenharmony_ci    }
28207db96d56Sopenharmony_ci    return list;
28217db96d56Sopenharmony_ci}
28227db96d56Sopenharmony_ci
28237db96d56Sopenharmony_ci
28247db96d56Sopenharmony_ci/*[clinic input]
28257db96d56Sopenharmony_cilist.__sizeof__
28267db96d56Sopenharmony_ci
28277db96d56Sopenharmony_ciReturn the size of the list in memory, in bytes.
28287db96d56Sopenharmony_ci[clinic start generated code]*/
28297db96d56Sopenharmony_ci
28307db96d56Sopenharmony_cistatic PyObject *
28317db96d56Sopenharmony_cilist___sizeof___impl(PyListObject *self)
28327db96d56Sopenharmony_ci/*[clinic end generated code: output=3417541f95f9a53e input=b8030a5d5ce8a187]*/
28337db96d56Sopenharmony_ci{
28347db96d56Sopenharmony_ci    Py_ssize_t res;
28357db96d56Sopenharmony_ci
28367db96d56Sopenharmony_ci    res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * sizeof(void*);
28377db96d56Sopenharmony_ci    return PyLong_FromSsize_t(res);
28387db96d56Sopenharmony_ci}
28397db96d56Sopenharmony_ci
28407db96d56Sopenharmony_cistatic PyObject *list_iter(PyObject *seq);
28417db96d56Sopenharmony_cistatic PyObject *list_subscript(PyListObject*, PyObject*);
28427db96d56Sopenharmony_ci
28437db96d56Sopenharmony_cistatic PyMethodDef list_methods[] = {
28447db96d56Sopenharmony_ci    {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, "x.__getitem__(y) <==> x[y]"},
28457db96d56Sopenharmony_ci    LIST___REVERSED___METHODDEF
28467db96d56Sopenharmony_ci    LIST___SIZEOF___METHODDEF
28477db96d56Sopenharmony_ci    LIST_CLEAR_METHODDEF
28487db96d56Sopenharmony_ci    LIST_COPY_METHODDEF
28497db96d56Sopenharmony_ci    LIST_APPEND_METHODDEF
28507db96d56Sopenharmony_ci    LIST_INSERT_METHODDEF
28517db96d56Sopenharmony_ci    LIST_EXTEND_METHODDEF
28527db96d56Sopenharmony_ci    LIST_POP_METHODDEF
28537db96d56Sopenharmony_ci    LIST_REMOVE_METHODDEF
28547db96d56Sopenharmony_ci    LIST_INDEX_METHODDEF
28557db96d56Sopenharmony_ci    LIST_COUNT_METHODDEF
28567db96d56Sopenharmony_ci    LIST_REVERSE_METHODDEF
28577db96d56Sopenharmony_ci    LIST_SORT_METHODDEF
28587db96d56Sopenharmony_ci    {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
28597db96d56Sopenharmony_ci    {NULL,              NULL}           /* sentinel */
28607db96d56Sopenharmony_ci};
28617db96d56Sopenharmony_ci
28627db96d56Sopenharmony_cistatic PySequenceMethods list_as_sequence = {
28637db96d56Sopenharmony_ci    (lenfunc)list_length,                       /* sq_length */
28647db96d56Sopenharmony_ci    (binaryfunc)list_concat,                    /* sq_concat */
28657db96d56Sopenharmony_ci    (ssizeargfunc)list_repeat,                  /* sq_repeat */
28667db96d56Sopenharmony_ci    (ssizeargfunc)list_item,                    /* sq_item */
28677db96d56Sopenharmony_ci    0,                                          /* sq_slice */
28687db96d56Sopenharmony_ci    (ssizeobjargproc)list_ass_item,             /* sq_ass_item */
28697db96d56Sopenharmony_ci    0,                                          /* sq_ass_slice */
28707db96d56Sopenharmony_ci    (objobjproc)list_contains,                  /* sq_contains */
28717db96d56Sopenharmony_ci    (binaryfunc)list_inplace_concat,            /* sq_inplace_concat */
28727db96d56Sopenharmony_ci    (ssizeargfunc)list_inplace_repeat,          /* sq_inplace_repeat */
28737db96d56Sopenharmony_ci};
28747db96d56Sopenharmony_ci
28757db96d56Sopenharmony_cistatic PyObject *
28767db96d56Sopenharmony_cilist_subscript(PyListObject* self, PyObject* item)
28777db96d56Sopenharmony_ci{
28787db96d56Sopenharmony_ci    if (_PyIndex_Check(item)) {
28797db96d56Sopenharmony_ci        Py_ssize_t i;
28807db96d56Sopenharmony_ci        i = PyNumber_AsSsize_t(item, PyExc_IndexError);
28817db96d56Sopenharmony_ci        if (i == -1 && PyErr_Occurred())
28827db96d56Sopenharmony_ci            return NULL;
28837db96d56Sopenharmony_ci        if (i < 0)
28847db96d56Sopenharmony_ci            i += PyList_GET_SIZE(self);
28857db96d56Sopenharmony_ci        return list_item(self, i);
28867db96d56Sopenharmony_ci    }
28877db96d56Sopenharmony_ci    else if (PySlice_Check(item)) {
28887db96d56Sopenharmony_ci        Py_ssize_t start, stop, step, slicelength, i;
28897db96d56Sopenharmony_ci        size_t cur;
28907db96d56Sopenharmony_ci        PyObject* result;
28917db96d56Sopenharmony_ci        PyObject* it;
28927db96d56Sopenharmony_ci        PyObject **src, **dest;
28937db96d56Sopenharmony_ci
28947db96d56Sopenharmony_ci        if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
28957db96d56Sopenharmony_ci            return NULL;
28967db96d56Sopenharmony_ci        }
28977db96d56Sopenharmony_ci        slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop,
28987db96d56Sopenharmony_ci                                            step);
28997db96d56Sopenharmony_ci
29007db96d56Sopenharmony_ci        if (slicelength <= 0) {
29017db96d56Sopenharmony_ci            return PyList_New(0);
29027db96d56Sopenharmony_ci        }
29037db96d56Sopenharmony_ci        else if (step == 1) {
29047db96d56Sopenharmony_ci            return list_slice(self, start, stop);
29057db96d56Sopenharmony_ci        }
29067db96d56Sopenharmony_ci        else {
29077db96d56Sopenharmony_ci            result = list_new_prealloc(slicelength);
29087db96d56Sopenharmony_ci            if (!result) return NULL;
29097db96d56Sopenharmony_ci
29107db96d56Sopenharmony_ci            src = self->ob_item;
29117db96d56Sopenharmony_ci            dest = ((PyListObject *)result)->ob_item;
29127db96d56Sopenharmony_ci            for (cur = start, i = 0; i < slicelength;
29137db96d56Sopenharmony_ci                 cur += (size_t)step, i++) {
29147db96d56Sopenharmony_ci                it = src[cur];
29157db96d56Sopenharmony_ci                Py_INCREF(it);
29167db96d56Sopenharmony_ci                dest[i] = it;
29177db96d56Sopenharmony_ci            }
29187db96d56Sopenharmony_ci            Py_SET_SIZE(result, slicelength);
29197db96d56Sopenharmony_ci            return result;
29207db96d56Sopenharmony_ci        }
29217db96d56Sopenharmony_ci    }
29227db96d56Sopenharmony_ci    else {
29237db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
29247db96d56Sopenharmony_ci                     "list indices must be integers or slices, not %.200s",
29257db96d56Sopenharmony_ci                     Py_TYPE(item)->tp_name);
29267db96d56Sopenharmony_ci        return NULL;
29277db96d56Sopenharmony_ci    }
29287db96d56Sopenharmony_ci}
29297db96d56Sopenharmony_ci
29307db96d56Sopenharmony_cistatic int
29317db96d56Sopenharmony_cilist_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
29327db96d56Sopenharmony_ci{
29337db96d56Sopenharmony_ci    if (_PyIndex_Check(item)) {
29347db96d56Sopenharmony_ci        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
29357db96d56Sopenharmony_ci        if (i == -1 && PyErr_Occurred())
29367db96d56Sopenharmony_ci            return -1;
29377db96d56Sopenharmony_ci        if (i < 0)
29387db96d56Sopenharmony_ci            i += PyList_GET_SIZE(self);
29397db96d56Sopenharmony_ci        return list_ass_item(self, i, value);
29407db96d56Sopenharmony_ci    }
29417db96d56Sopenharmony_ci    else if (PySlice_Check(item)) {
29427db96d56Sopenharmony_ci        Py_ssize_t start, stop, step, slicelength;
29437db96d56Sopenharmony_ci
29447db96d56Sopenharmony_ci        if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
29457db96d56Sopenharmony_ci            return -1;
29467db96d56Sopenharmony_ci        }
29477db96d56Sopenharmony_ci        slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop,
29487db96d56Sopenharmony_ci                                            step);
29497db96d56Sopenharmony_ci
29507db96d56Sopenharmony_ci        if (step == 1)
29517db96d56Sopenharmony_ci            return list_ass_slice(self, start, stop, value);
29527db96d56Sopenharmony_ci
29537db96d56Sopenharmony_ci        /* Make sure s[5:2] = [..] inserts at the right place:
29547db96d56Sopenharmony_ci           before 5, not before 2. */
29557db96d56Sopenharmony_ci        if ((step < 0 && start < stop) ||
29567db96d56Sopenharmony_ci            (step > 0 && start > stop))
29577db96d56Sopenharmony_ci            stop = start;
29587db96d56Sopenharmony_ci
29597db96d56Sopenharmony_ci        if (value == NULL) {
29607db96d56Sopenharmony_ci            /* delete slice */
29617db96d56Sopenharmony_ci            PyObject **garbage;
29627db96d56Sopenharmony_ci            size_t cur;
29637db96d56Sopenharmony_ci            Py_ssize_t i;
29647db96d56Sopenharmony_ci            int res;
29657db96d56Sopenharmony_ci
29667db96d56Sopenharmony_ci            if (slicelength <= 0)
29677db96d56Sopenharmony_ci                return 0;
29687db96d56Sopenharmony_ci
29697db96d56Sopenharmony_ci            if (step < 0) {
29707db96d56Sopenharmony_ci                stop = start + 1;
29717db96d56Sopenharmony_ci                start = stop + step*(slicelength - 1) - 1;
29727db96d56Sopenharmony_ci                step = -step;
29737db96d56Sopenharmony_ci            }
29747db96d56Sopenharmony_ci
29757db96d56Sopenharmony_ci            garbage = (PyObject**)
29767db96d56Sopenharmony_ci                PyMem_Malloc(slicelength*sizeof(PyObject*));
29777db96d56Sopenharmony_ci            if (!garbage) {
29787db96d56Sopenharmony_ci                PyErr_NoMemory();
29797db96d56Sopenharmony_ci                return -1;
29807db96d56Sopenharmony_ci            }
29817db96d56Sopenharmony_ci
29827db96d56Sopenharmony_ci            /* drawing pictures might help understand these for
29837db96d56Sopenharmony_ci               loops. Basically, we memmove the parts of the
29847db96d56Sopenharmony_ci               list that are *not* part of the slice: step-1
29857db96d56Sopenharmony_ci               items for each item that is part of the slice,
29867db96d56Sopenharmony_ci               and then tail end of the list that was not
29877db96d56Sopenharmony_ci               covered by the slice */
29887db96d56Sopenharmony_ci            for (cur = start, i = 0;
29897db96d56Sopenharmony_ci                 cur < (size_t)stop;
29907db96d56Sopenharmony_ci                 cur += step, i++) {
29917db96d56Sopenharmony_ci                Py_ssize_t lim = step - 1;
29927db96d56Sopenharmony_ci
29937db96d56Sopenharmony_ci                garbage[i] = PyList_GET_ITEM(self, cur);
29947db96d56Sopenharmony_ci
29957db96d56Sopenharmony_ci                if (cur + step >= (size_t)Py_SIZE(self)) {
29967db96d56Sopenharmony_ci                    lim = Py_SIZE(self) - cur - 1;
29977db96d56Sopenharmony_ci                }
29987db96d56Sopenharmony_ci
29997db96d56Sopenharmony_ci                memmove(self->ob_item + cur - i,
30007db96d56Sopenharmony_ci                    self->ob_item + cur + 1,
30017db96d56Sopenharmony_ci                    lim * sizeof(PyObject *));
30027db96d56Sopenharmony_ci            }
30037db96d56Sopenharmony_ci            cur = start + (size_t)slicelength * step;
30047db96d56Sopenharmony_ci            if (cur < (size_t)Py_SIZE(self)) {
30057db96d56Sopenharmony_ci                memmove(self->ob_item + cur - slicelength,
30067db96d56Sopenharmony_ci                    self->ob_item + cur,
30077db96d56Sopenharmony_ci                    (Py_SIZE(self) - cur) *
30087db96d56Sopenharmony_ci                     sizeof(PyObject *));
30097db96d56Sopenharmony_ci            }
30107db96d56Sopenharmony_ci
30117db96d56Sopenharmony_ci            Py_SET_SIZE(self, Py_SIZE(self) - slicelength);
30127db96d56Sopenharmony_ci            res = list_resize(self, Py_SIZE(self));
30137db96d56Sopenharmony_ci
30147db96d56Sopenharmony_ci            for (i = 0; i < slicelength; i++) {
30157db96d56Sopenharmony_ci                Py_DECREF(garbage[i]);
30167db96d56Sopenharmony_ci            }
30177db96d56Sopenharmony_ci            PyMem_Free(garbage);
30187db96d56Sopenharmony_ci
30197db96d56Sopenharmony_ci            return res;
30207db96d56Sopenharmony_ci        }
30217db96d56Sopenharmony_ci        else {
30227db96d56Sopenharmony_ci            /* assign slice */
30237db96d56Sopenharmony_ci            PyObject *ins, *seq;
30247db96d56Sopenharmony_ci            PyObject **garbage, **seqitems, **selfitems;
30257db96d56Sopenharmony_ci            Py_ssize_t i;
30267db96d56Sopenharmony_ci            size_t cur;
30277db96d56Sopenharmony_ci
30287db96d56Sopenharmony_ci            /* protect against a[::-1] = a */
30297db96d56Sopenharmony_ci            if (self == (PyListObject*)value) {
30307db96d56Sopenharmony_ci                seq = list_slice((PyListObject*)value, 0,
30317db96d56Sopenharmony_ci                                   PyList_GET_SIZE(value));
30327db96d56Sopenharmony_ci            }
30337db96d56Sopenharmony_ci            else {
30347db96d56Sopenharmony_ci                seq = PySequence_Fast(value,
30357db96d56Sopenharmony_ci                                      "must assign iterable "
30367db96d56Sopenharmony_ci                                      "to extended slice");
30377db96d56Sopenharmony_ci            }
30387db96d56Sopenharmony_ci            if (!seq)
30397db96d56Sopenharmony_ci                return -1;
30407db96d56Sopenharmony_ci
30417db96d56Sopenharmony_ci            if (PySequence_Fast_GET_SIZE(seq) != slicelength) {
30427db96d56Sopenharmony_ci                PyErr_Format(PyExc_ValueError,
30437db96d56Sopenharmony_ci                    "attempt to assign sequence of "
30447db96d56Sopenharmony_ci                    "size %zd to extended slice of "
30457db96d56Sopenharmony_ci                    "size %zd",
30467db96d56Sopenharmony_ci                         PySequence_Fast_GET_SIZE(seq),
30477db96d56Sopenharmony_ci                         slicelength);
30487db96d56Sopenharmony_ci                Py_DECREF(seq);
30497db96d56Sopenharmony_ci                return -1;
30507db96d56Sopenharmony_ci            }
30517db96d56Sopenharmony_ci
30527db96d56Sopenharmony_ci            if (!slicelength) {
30537db96d56Sopenharmony_ci                Py_DECREF(seq);
30547db96d56Sopenharmony_ci                return 0;
30557db96d56Sopenharmony_ci            }
30567db96d56Sopenharmony_ci
30577db96d56Sopenharmony_ci            garbage = (PyObject**)
30587db96d56Sopenharmony_ci                PyMem_Malloc(slicelength*sizeof(PyObject*));
30597db96d56Sopenharmony_ci            if (!garbage) {
30607db96d56Sopenharmony_ci                Py_DECREF(seq);
30617db96d56Sopenharmony_ci                PyErr_NoMemory();
30627db96d56Sopenharmony_ci                return -1;
30637db96d56Sopenharmony_ci            }
30647db96d56Sopenharmony_ci
30657db96d56Sopenharmony_ci            selfitems = self->ob_item;
30667db96d56Sopenharmony_ci            seqitems = PySequence_Fast_ITEMS(seq);
30677db96d56Sopenharmony_ci            for (cur = start, i = 0; i < slicelength;
30687db96d56Sopenharmony_ci                 cur += (size_t)step, i++) {
30697db96d56Sopenharmony_ci                garbage[i] = selfitems[cur];
30707db96d56Sopenharmony_ci                ins = seqitems[i];
30717db96d56Sopenharmony_ci                Py_INCREF(ins);
30727db96d56Sopenharmony_ci                selfitems[cur] = ins;
30737db96d56Sopenharmony_ci            }
30747db96d56Sopenharmony_ci
30757db96d56Sopenharmony_ci            for (i = 0; i < slicelength; i++) {
30767db96d56Sopenharmony_ci                Py_DECREF(garbage[i]);
30777db96d56Sopenharmony_ci            }
30787db96d56Sopenharmony_ci
30797db96d56Sopenharmony_ci            PyMem_Free(garbage);
30807db96d56Sopenharmony_ci            Py_DECREF(seq);
30817db96d56Sopenharmony_ci
30827db96d56Sopenharmony_ci            return 0;
30837db96d56Sopenharmony_ci        }
30847db96d56Sopenharmony_ci    }
30857db96d56Sopenharmony_ci    else {
30867db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
30877db96d56Sopenharmony_ci                     "list indices must be integers or slices, not %.200s",
30887db96d56Sopenharmony_ci                     Py_TYPE(item)->tp_name);
30897db96d56Sopenharmony_ci        return -1;
30907db96d56Sopenharmony_ci    }
30917db96d56Sopenharmony_ci}
30927db96d56Sopenharmony_ci
30937db96d56Sopenharmony_cistatic PyMappingMethods list_as_mapping = {
30947db96d56Sopenharmony_ci    (lenfunc)list_length,
30957db96d56Sopenharmony_ci    (binaryfunc)list_subscript,
30967db96d56Sopenharmony_ci    (objobjargproc)list_ass_subscript
30977db96d56Sopenharmony_ci};
30987db96d56Sopenharmony_ci
30997db96d56Sopenharmony_ciPyTypeObject PyList_Type = {
31007db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
31017db96d56Sopenharmony_ci    "list",
31027db96d56Sopenharmony_ci    sizeof(PyListObject),
31037db96d56Sopenharmony_ci    0,
31047db96d56Sopenharmony_ci    (destructor)list_dealloc,                   /* tp_dealloc */
31057db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
31067db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
31077db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
31087db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
31097db96d56Sopenharmony_ci    (reprfunc)list_repr,                        /* tp_repr */
31107db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
31117db96d56Sopenharmony_ci    &list_as_sequence,                          /* tp_as_sequence */
31127db96d56Sopenharmony_ci    &list_as_mapping,                           /* tp_as_mapping */
31137db96d56Sopenharmony_ci    PyObject_HashNotImplemented,                /* tp_hash */
31147db96d56Sopenharmony_ci    0,                                          /* tp_call */
31157db96d56Sopenharmony_ci    0,                                          /* tp_str */
31167db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
31177db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
31187db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
31197db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
31207db96d56Sopenharmony_ci        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS |
31217db96d56Sopenharmony_ci        _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_SEQUENCE,  /* tp_flags */
31227db96d56Sopenharmony_ci    list___init____doc__,                       /* tp_doc */
31237db96d56Sopenharmony_ci    (traverseproc)list_traverse,                /* tp_traverse */
31247db96d56Sopenharmony_ci    (inquiry)_list_clear,                       /* tp_clear */
31257db96d56Sopenharmony_ci    list_richcompare,                           /* tp_richcompare */
31267db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
31277db96d56Sopenharmony_ci    list_iter,                                  /* tp_iter */
31287db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
31297db96d56Sopenharmony_ci    list_methods,                               /* tp_methods */
31307db96d56Sopenharmony_ci    0,                                          /* tp_members */
31317db96d56Sopenharmony_ci    0,                                          /* tp_getset */
31327db96d56Sopenharmony_ci    0,                                          /* tp_base */
31337db96d56Sopenharmony_ci    0,                                          /* tp_dict */
31347db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
31357db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
31367db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
31377db96d56Sopenharmony_ci    (initproc)list___init__,                    /* tp_init */
31387db96d56Sopenharmony_ci    PyType_GenericAlloc,                        /* tp_alloc */
31397db96d56Sopenharmony_ci    PyType_GenericNew,                          /* tp_new */
31407db96d56Sopenharmony_ci    PyObject_GC_Del,                            /* tp_free */
31417db96d56Sopenharmony_ci    .tp_vectorcall = list_vectorcall,
31427db96d56Sopenharmony_ci};
31437db96d56Sopenharmony_ci
31447db96d56Sopenharmony_ci/*********************** List Iterator **************************/
31457db96d56Sopenharmony_ci
31467db96d56Sopenharmony_citypedef struct {
31477db96d56Sopenharmony_ci    PyObject_HEAD
31487db96d56Sopenharmony_ci    Py_ssize_t it_index;
31497db96d56Sopenharmony_ci    PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
31507db96d56Sopenharmony_ci} listiterobject;
31517db96d56Sopenharmony_ci
31527db96d56Sopenharmony_cistatic void listiter_dealloc(listiterobject *);
31537db96d56Sopenharmony_cistatic int listiter_traverse(listiterobject *, visitproc, void *);
31547db96d56Sopenharmony_cistatic PyObject *listiter_next(listiterobject *);
31557db96d56Sopenharmony_cistatic PyObject *listiter_len(listiterobject *, PyObject *);
31567db96d56Sopenharmony_cistatic PyObject *listiter_reduce_general(void *_it, int forward);
31577db96d56Sopenharmony_cistatic PyObject *listiter_reduce(listiterobject *, PyObject *);
31587db96d56Sopenharmony_cistatic PyObject *listiter_setstate(listiterobject *, PyObject *state);
31597db96d56Sopenharmony_ci
31607db96d56Sopenharmony_ciPyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
31617db96d56Sopenharmony_ciPyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
31627db96d56Sopenharmony_ciPyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
31637db96d56Sopenharmony_ci
31647db96d56Sopenharmony_cistatic PyMethodDef listiter_methods[] = {
31657db96d56Sopenharmony_ci    {"__length_hint__", (PyCFunction)listiter_len, METH_NOARGS, length_hint_doc},
31667db96d56Sopenharmony_ci    {"__reduce__", (PyCFunction)listiter_reduce, METH_NOARGS, reduce_doc},
31677db96d56Sopenharmony_ci    {"__setstate__", (PyCFunction)listiter_setstate, METH_O, setstate_doc},
31687db96d56Sopenharmony_ci    {NULL,              NULL}           /* sentinel */
31697db96d56Sopenharmony_ci};
31707db96d56Sopenharmony_ci
31717db96d56Sopenharmony_ciPyTypeObject PyListIter_Type = {
31727db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
31737db96d56Sopenharmony_ci    "list_iterator",                            /* tp_name */
31747db96d56Sopenharmony_ci    sizeof(listiterobject),                     /* tp_basicsize */
31757db96d56Sopenharmony_ci    0,                                          /* tp_itemsize */
31767db96d56Sopenharmony_ci    /* methods */
31777db96d56Sopenharmony_ci    (destructor)listiter_dealloc,               /* tp_dealloc */
31787db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
31797db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
31807db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
31817db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
31827db96d56Sopenharmony_ci    0,                                          /* tp_repr */
31837db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
31847db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
31857db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
31867db96d56Sopenharmony_ci    0,                                          /* tp_hash */
31877db96d56Sopenharmony_ci    0,                                          /* tp_call */
31887db96d56Sopenharmony_ci    0,                                          /* tp_str */
31897db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
31907db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
31917db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
31927db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
31937db96d56Sopenharmony_ci    0,                                          /* tp_doc */
31947db96d56Sopenharmony_ci    (traverseproc)listiter_traverse,            /* tp_traverse */
31957db96d56Sopenharmony_ci    0,                                          /* tp_clear */
31967db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
31977db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
31987db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* tp_iter */
31997db96d56Sopenharmony_ci    (iternextfunc)listiter_next,                /* tp_iternext */
32007db96d56Sopenharmony_ci    listiter_methods,                           /* tp_methods */
32017db96d56Sopenharmony_ci    0,                                          /* tp_members */
32027db96d56Sopenharmony_ci};
32037db96d56Sopenharmony_ci
32047db96d56Sopenharmony_ci
32057db96d56Sopenharmony_cistatic PyObject *
32067db96d56Sopenharmony_cilist_iter(PyObject *seq)
32077db96d56Sopenharmony_ci{
32087db96d56Sopenharmony_ci    listiterobject *it;
32097db96d56Sopenharmony_ci
32107db96d56Sopenharmony_ci    if (!PyList_Check(seq)) {
32117db96d56Sopenharmony_ci        PyErr_BadInternalCall();
32127db96d56Sopenharmony_ci        return NULL;
32137db96d56Sopenharmony_ci    }
32147db96d56Sopenharmony_ci    it = PyObject_GC_New(listiterobject, &PyListIter_Type);
32157db96d56Sopenharmony_ci    if (it == NULL)
32167db96d56Sopenharmony_ci        return NULL;
32177db96d56Sopenharmony_ci    it->it_index = 0;
32187db96d56Sopenharmony_ci    Py_INCREF(seq);
32197db96d56Sopenharmony_ci    it->it_seq = (PyListObject *)seq;
32207db96d56Sopenharmony_ci    _PyObject_GC_TRACK(it);
32217db96d56Sopenharmony_ci    return (PyObject *)it;
32227db96d56Sopenharmony_ci}
32237db96d56Sopenharmony_ci
32247db96d56Sopenharmony_cistatic void
32257db96d56Sopenharmony_cilistiter_dealloc(listiterobject *it)
32267db96d56Sopenharmony_ci{
32277db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK(it);
32287db96d56Sopenharmony_ci    Py_XDECREF(it->it_seq);
32297db96d56Sopenharmony_ci    PyObject_GC_Del(it);
32307db96d56Sopenharmony_ci}
32317db96d56Sopenharmony_ci
32327db96d56Sopenharmony_cistatic int
32337db96d56Sopenharmony_cilistiter_traverse(listiterobject *it, visitproc visit, void *arg)
32347db96d56Sopenharmony_ci{
32357db96d56Sopenharmony_ci    Py_VISIT(it->it_seq);
32367db96d56Sopenharmony_ci    return 0;
32377db96d56Sopenharmony_ci}
32387db96d56Sopenharmony_ci
32397db96d56Sopenharmony_cistatic PyObject *
32407db96d56Sopenharmony_cilistiter_next(listiterobject *it)
32417db96d56Sopenharmony_ci{
32427db96d56Sopenharmony_ci    PyListObject *seq;
32437db96d56Sopenharmony_ci    PyObject *item;
32447db96d56Sopenharmony_ci
32457db96d56Sopenharmony_ci    assert(it != NULL);
32467db96d56Sopenharmony_ci    seq = it->it_seq;
32477db96d56Sopenharmony_ci    if (seq == NULL)
32487db96d56Sopenharmony_ci        return NULL;
32497db96d56Sopenharmony_ci    assert(PyList_Check(seq));
32507db96d56Sopenharmony_ci
32517db96d56Sopenharmony_ci    if (it->it_index < PyList_GET_SIZE(seq)) {
32527db96d56Sopenharmony_ci        item = PyList_GET_ITEM(seq, it->it_index);
32537db96d56Sopenharmony_ci        ++it->it_index;
32547db96d56Sopenharmony_ci        Py_INCREF(item);
32557db96d56Sopenharmony_ci        return item;
32567db96d56Sopenharmony_ci    }
32577db96d56Sopenharmony_ci
32587db96d56Sopenharmony_ci    it->it_seq = NULL;
32597db96d56Sopenharmony_ci    Py_DECREF(seq);
32607db96d56Sopenharmony_ci    return NULL;
32617db96d56Sopenharmony_ci}
32627db96d56Sopenharmony_ci
32637db96d56Sopenharmony_cistatic PyObject *
32647db96d56Sopenharmony_cilistiter_len(listiterobject *it, PyObject *Py_UNUSED(ignored))
32657db96d56Sopenharmony_ci{
32667db96d56Sopenharmony_ci    Py_ssize_t len;
32677db96d56Sopenharmony_ci    if (it->it_seq) {
32687db96d56Sopenharmony_ci        len = PyList_GET_SIZE(it->it_seq) - it->it_index;
32697db96d56Sopenharmony_ci        if (len >= 0)
32707db96d56Sopenharmony_ci            return PyLong_FromSsize_t(len);
32717db96d56Sopenharmony_ci    }
32727db96d56Sopenharmony_ci    return PyLong_FromLong(0);
32737db96d56Sopenharmony_ci}
32747db96d56Sopenharmony_ci
32757db96d56Sopenharmony_cistatic PyObject *
32767db96d56Sopenharmony_cilistiter_reduce(listiterobject *it, PyObject *Py_UNUSED(ignored))
32777db96d56Sopenharmony_ci{
32787db96d56Sopenharmony_ci    return listiter_reduce_general(it, 1);
32797db96d56Sopenharmony_ci}
32807db96d56Sopenharmony_ci
32817db96d56Sopenharmony_cistatic PyObject *
32827db96d56Sopenharmony_cilistiter_setstate(listiterobject *it, PyObject *state)
32837db96d56Sopenharmony_ci{
32847db96d56Sopenharmony_ci    Py_ssize_t index = PyLong_AsSsize_t(state);
32857db96d56Sopenharmony_ci    if (index == -1 && PyErr_Occurred())
32867db96d56Sopenharmony_ci        return NULL;
32877db96d56Sopenharmony_ci    if (it->it_seq != NULL) {
32887db96d56Sopenharmony_ci        if (index < 0)
32897db96d56Sopenharmony_ci            index = 0;
32907db96d56Sopenharmony_ci        else if (index > PyList_GET_SIZE(it->it_seq))
32917db96d56Sopenharmony_ci            index = PyList_GET_SIZE(it->it_seq); /* iterator exhausted */
32927db96d56Sopenharmony_ci        it->it_index = index;
32937db96d56Sopenharmony_ci    }
32947db96d56Sopenharmony_ci    Py_RETURN_NONE;
32957db96d56Sopenharmony_ci}
32967db96d56Sopenharmony_ci
32977db96d56Sopenharmony_ci/*********************** List Reverse Iterator **************************/
32987db96d56Sopenharmony_ci
32997db96d56Sopenharmony_citypedef struct {
33007db96d56Sopenharmony_ci    PyObject_HEAD
33017db96d56Sopenharmony_ci    Py_ssize_t it_index;
33027db96d56Sopenharmony_ci    PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
33037db96d56Sopenharmony_ci} listreviterobject;
33047db96d56Sopenharmony_ci
33057db96d56Sopenharmony_cistatic void listreviter_dealloc(listreviterobject *);
33067db96d56Sopenharmony_cistatic int listreviter_traverse(listreviterobject *, visitproc, void *);
33077db96d56Sopenharmony_cistatic PyObject *listreviter_next(listreviterobject *);
33087db96d56Sopenharmony_cistatic PyObject *listreviter_len(listreviterobject *, PyObject *);
33097db96d56Sopenharmony_cistatic PyObject *listreviter_reduce(listreviterobject *, PyObject *);
33107db96d56Sopenharmony_cistatic PyObject *listreviter_setstate(listreviterobject *, PyObject *);
33117db96d56Sopenharmony_ci
33127db96d56Sopenharmony_cistatic PyMethodDef listreviter_methods[] = {
33137db96d56Sopenharmony_ci    {"__length_hint__", (PyCFunction)listreviter_len, METH_NOARGS, length_hint_doc},
33147db96d56Sopenharmony_ci    {"__reduce__", (PyCFunction)listreviter_reduce, METH_NOARGS, reduce_doc},
33157db96d56Sopenharmony_ci    {"__setstate__", (PyCFunction)listreviter_setstate, METH_O, setstate_doc},
33167db96d56Sopenharmony_ci    {NULL,              NULL}           /* sentinel */
33177db96d56Sopenharmony_ci};
33187db96d56Sopenharmony_ci
33197db96d56Sopenharmony_ciPyTypeObject PyListRevIter_Type = {
33207db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
33217db96d56Sopenharmony_ci    "list_reverseiterator",                     /* tp_name */
33227db96d56Sopenharmony_ci    sizeof(listreviterobject),                  /* tp_basicsize */
33237db96d56Sopenharmony_ci    0,                                          /* tp_itemsize */
33247db96d56Sopenharmony_ci    /* methods */
33257db96d56Sopenharmony_ci    (destructor)listreviter_dealloc,            /* tp_dealloc */
33267db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
33277db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
33287db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
33297db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
33307db96d56Sopenharmony_ci    0,                                          /* tp_repr */
33317db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
33327db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
33337db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
33347db96d56Sopenharmony_ci    0,                                          /* tp_hash */
33357db96d56Sopenharmony_ci    0,                                          /* tp_call */
33367db96d56Sopenharmony_ci    0,                                          /* tp_str */
33377db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
33387db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
33397db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
33407db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
33417db96d56Sopenharmony_ci    0,                                          /* tp_doc */
33427db96d56Sopenharmony_ci    (traverseproc)listreviter_traverse,         /* tp_traverse */
33437db96d56Sopenharmony_ci    0,                                          /* tp_clear */
33447db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
33457db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
33467db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* tp_iter */
33477db96d56Sopenharmony_ci    (iternextfunc)listreviter_next,             /* tp_iternext */
33487db96d56Sopenharmony_ci    listreviter_methods,                /* tp_methods */
33497db96d56Sopenharmony_ci    0,
33507db96d56Sopenharmony_ci};
33517db96d56Sopenharmony_ci
33527db96d56Sopenharmony_ci/*[clinic input]
33537db96d56Sopenharmony_cilist.__reversed__
33547db96d56Sopenharmony_ci
33557db96d56Sopenharmony_ciReturn a reverse iterator over the list.
33567db96d56Sopenharmony_ci[clinic start generated code]*/
33577db96d56Sopenharmony_ci
33587db96d56Sopenharmony_cistatic PyObject *
33597db96d56Sopenharmony_cilist___reversed___impl(PyListObject *self)
33607db96d56Sopenharmony_ci/*[clinic end generated code: output=b166f073208c888c input=eadb6e17f8a6a280]*/
33617db96d56Sopenharmony_ci{
33627db96d56Sopenharmony_ci    listreviterobject *it;
33637db96d56Sopenharmony_ci
33647db96d56Sopenharmony_ci    it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type);
33657db96d56Sopenharmony_ci    if (it == NULL)
33667db96d56Sopenharmony_ci        return NULL;
33677db96d56Sopenharmony_ci    assert(PyList_Check(self));
33687db96d56Sopenharmony_ci    it->it_index = PyList_GET_SIZE(self) - 1;
33697db96d56Sopenharmony_ci    Py_INCREF(self);
33707db96d56Sopenharmony_ci    it->it_seq = self;
33717db96d56Sopenharmony_ci    PyObject_GC_Track(it);
33727db96d56Sopenharmony_ci    return (PyObject *)it;
33737db96d56Sopenharmony_ci}
33747db96d56Sopenharmony_ci
33757db96d56Sopenharmony_cistatic void
33767db96d56Sopenharmony_cilistreviter_dealloc(listreviterobject *it)
33777db96d56Sopenharmony_ci{
33787db96d56Sopenharmony_ci    PyObject_GC_UnTrack(it);
33797db96d56Sopenharmony_ci    Py_XDECREF(it->it_seq);
33807db96d56Sopenharmony_ci    PyObject_GC_Del(it);
33817db96d56Sopenharmony_ci}
33827db96d56Sopenharmony_ci
33837db96d56Sopenharmony_cistatic int
33847db96d56Sopenharmony_cilistreviter_traverse(listreviterobject *it, visitproc visit, void *arg)
33857db96d56Sopenharmony_ci{
33867db96d56Sopenharmony_ci    Py_VISIT(it->it_seq);
33877db96d56Sopenharmony_ci    return 0;
33887db96d56Sopenharmony_ci}
33897db96d56Sopenharmony_ci
33907db96d56Sopenharmony_cistatic PyObject *
33917db96d56Sopenharmony_cilistreviter_next(listreviterobject *it)
33927db96d56Sopenharmony_ci{
33937db96d56Sopenharmony_ci    PyObject *item;
33947db96d56Sopenharmony_ci    Py_ssize_t index;
33957db96d56Sopenharmony_ci    PyListObject *seq;
33967db96d56Sopenharmony_ci
33977db96d56Sopenharmony_ci    assert(it != NULL);
33987db96d56Sopenharmony_ci    seq = it->it_seq;
33997db96d56Sopenharmony_ci    if (seq == NULL) {
34007db96d56Sopenharmony_ci        return NULL;
34017db96d56Sopenharmony_ci    }
34027db96d56Sopenharmony_ci    assert(PyList_Check(seq));
34037db96d56Sopenharmony_ci
34047db96d56Sopenharmony_ci    index = it->it_index;
34057db96d56Sopenharmony_ci    if (index>=0 && index < PyList_GET_SIZE(seq)) {
34067db96d56Sopenharmony_ci        item = PyList_GET_ITEM(seq, index);
34077db96d56Sopenharmony_ci        it->it_index--;
34087db96d56Sopenharmony_ci        Py_INCREF(item);
34097db96d56Sopenharmony_ci        return item;
34107db96d56Sopenharmony_ci    }
34117db96d56Sopenharmony_ci    it->it_index = -1;
34127db96d56Sopenharmony_ci    it->it_seq = NULL;
34137db96d56Sopenharmony_ci    Py_DECREF(seq);
34147db96d56Sopenharmony_ci    return NULL;
34157db96d56Sopenharmony_ci}
34167db96d56Sopenharmony_ci
34177db96d56Sopenharmony_cistatic PyObject *
34187db96d56Sopenharmony_cilistreviter_len(listreviterobject *it, PyObject *Py_UNUSED(ignored))
34197db96d56Sopenharmony_ci{
34207db96d56Sopenharmony_ci    Py_ssize_t len = it->it_index + 1;
34217db96d56Sopenharmony_ci    if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len)
34227db96d56Sopenharmony_ci        len = 0;
34237db96d56Sopenharmony_ci    return PyLong_FromSsize_t(len);
34247db96d56Sopenharmony_ci}
34257db96d56Sopenharmony_ci
34267db96d56Sopenharmony_cistatic PyObject *
34277db96d56Sopenharmony_cilistreviter_reduce(listreviterobject *it, PyObject *Py_UNUSED(ignored))
34287db96d56Sopenharmony_ci{
34297db96d56Sopenharmony_ci    return listiter_reduce_general(it, 0);
34307db96d56Sopenharmony_ci}
34317db96d56Sopenharmony_ci
34327db96d56Sopenharmony_cistatic PyObject *
34337db96d56Sopenharmony_cilistreviter_setstate(listreviterobject *it, PyObject *state)
34347db96d56Sopenharmony_ci{
34357db96d56Sopenharmony_ci    Py_ssize_t index = PyLong_AsSsize_t(state);
34367db96d56Sopenharmony_ci    if (index == -1 && PyErr_Occurred())
34377db96d56Sopenharmony_ci        return NULL;
34387db96d56Sopenharmony_ci    if (it->it_seq != NULL) {
34397db96d56Sopenharmony_ci        if (index < -1)
34407db96d56Sopenharmony_ci            index = -1;
34417db96d56Sopenharmony_ci        else if (index > PyList_GET_SIZE(it->it_seq) - 1)
34427db96d56Sopenharmony_ci            index = PyList_GET_SIZE(it->it_seq) - 1;
34437db96d56Sopenharmony_ci        it->it_index = index;
34447db96d56Sopenharmony_ci    }
34457db96d56Sopenharmony_ci    Py_RETURN_NONE;
34467db96d56Sopenharmony_ci}
34477db96d56Sopenharmony_ci
34487db96d56Sopenharmony_ci/* common pickling support */
34497db96d56Sopenharmony_ci
34507db96d56Sopenharmony_cistatic PyObject *
34517db96d56Sopenharmony_cilistiter_reduce_general(void *_it, int forward)
34527db96d56Sopenharmony_ci{
34537db96d56Sopenharmony_ci    PyObject *list;
34547db96d56Sopenharmony_ci
34557db96d56Sopenharmony_ci    /* _PyEval_GetBuiltin can invoke arbitrary code,
34567db96d56Sopenharmony_ci     * call must be before access of iterator pointers.
34577db96d56Sopenharmony_ci     * see issue #101765 */
34587db96d56Sopenharmony_ci
34597db96d56Sopenharmony_ci    /* the objects are not the same, index is of different types! */
34607db96d56Sopenharmony_ci    if (forward) {
34617db96d56Sopenharmony_ci        PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
34627db96d56Sopenharmony_ci        if (!iter) {
34637db96d56Sopenharmony_ci            return NULL;
34647db96d56Sopenharmony_ci        }
34657db96d56Sopenharmony_ci        listiterobject *it = (listiterobject *)_it;
34667db96d56Sopenharmony_ci        if (it->it_seq) {
34677db96d56Sopenharmony_ci            return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index);
34687db96d56Sopenharmony_ci        }
34697db96d56Sopenharmony_ci        Py_DECREF(iter);
34707db96d56Sopenharmony_ci    } else {
34717db96d56Sopenharmony_ci        PyObject *reversed = _PyEval_GetBuiltin(&_Py_ID(reversed));
34727db96d56Sopenharmony_ci        if (!reversed) {
34737db96d56Sopenharmony_ci            return NULL;
34747db96d56Sopenharmony_ci        }
34757db96d56Sopenharmony_ci        listreviterobject *it = (listreviterobject *)_it;
34767db96d56Sopenharmony_ci        if (it->it_seq) {
34777db96d56Sopenharmony_ci            return Py_BuildValue("N(O)n", reversed, it->it_seq, it->it_index);
34787db96d56Sopenharmony_ci        }
34797db96d56Sopenharmony_ci        Py_DECREF(reversed);
34807db96d56Sopenharmony_ci    }
34817db96d56Sopenharmony_ci    /* empty iterator, create an empty list */
34827db96d56Sopenharmony_ci    list = PyList_New(0);
34837db96d56Sopenharmony_ci    if (list == NULL)
34847db96d56Sopenharmony_ci        return NULL;
34857db96d56Sopenharmony_ci    return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list);
34867db96d56Sopenharmony_ci}
3487