]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.10/Objects/listobject.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Objects / listobject.c
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/listobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/listobject.c
deleted file mode 100644 (file)
index 221bce2..0000000
+++ /dev/null
@@ -1,3045 +0,0 @@
-/* List object implementation */\r
-\r
-#include "Python.h"\r
-\r
-#ifdef STDC_HEADERS\r
-#include <stddef.h>\r
-#else\r
-#include <sys/types.h>          /* For size_t */\r
-#endif\r
-\r
-/* Ensure ob_item has room for at least newsize elements, and set\r
- * ob_size to newsize.  If newsize > ob_size on entry, the content\r
- * of the new slots at exit is undefined heap trash; it's the caller's\r
- * responsibility to overwrite them with sane values.\r
- * The number of allocated elements may grow, shrink, or stay the same.\r
- * Failure is impossible if newsize <= self.allocated on entry, although\r
- * that partly relies on an assumption that the system realloc() never\r
- * fails when passed a number of bytes <= the number of bytes last\r
- * allocated (the C standard doesn't guarantee this, but it's hard to\r
- * imagine a realloc implementation where it wouldn't be true).\r
- * Note that self->ob_item may change, and even if newsize is less\r
- * than ob_size on entry.\r
- */\r
-static int\r
-list_resize(PyListObject *self, Py_ssize_t newsize)\r
-{\r
-    PyObject **items;\r
-    size_t new_allocated;\r
-    Py_ssize_t allocated = self->allocated;\r
-\r
-    /* Bypass realloc() when a previous overallocation is large enough\r
-       to accommodate the newsize.  If the newsize falls lower than half\r
-       the allocated size, then proceed with the realloc() to shrink the list.\r
-    */\r
-    if (allocated >= newsize && newsize >= (allocated >> 1)) {\r
-        assert(self->ob_item != NULL || newsize == 0);\r
-        Py_SIZE(self) = newsize;\r
-        return 0;\r
-    }\r
-\r
-    /* This over-allocates proportional to the list size, making room\r
-     * for additional growth.  The over-allocation is mild, but is\r
-     * enough to give linear-time amortized behavior over a long\r
-     * sequence of appends() in the presence of a poorly-performing\r
-     * system realloc().\r
-     * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...\r
-     */\r
-    new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);\r
-\r
-    /* check for integer overflow */\r
-    if (new_allocated > PY_SIZE_MAX - newsize) {\r
-        PyErr_NoMemory();\r
-        return -1;\r
-    } else {\r
-        new_allocated += newsize;\r
-    }\r
-\r
-    if (newsize == 0)\r
-        new_allocated = 0;\r
-    items = self->ob_item;\r
-    if (new_allocated <= (PY_SIZE_MAX / sizeof(PyObject *)))\r
-        PyMem_RESIZE(items, PyObject *, new_allocated);\r
-    else\r
-        items = NULL;\r
-    if (items == NULL) {\r
-        PyErr_NoMemory();\r
-        return -1;\r
-    }\r
-    self->ob_item = items;\r
-    Py_SIZE(self) = newsize;\r
-    self->allocated = new_allocated;\r
-    return 0;\r
-}\r
-\r
-/* Debug statistic to compare allocations with reuse through the free list */\r
-#undef SHOW_ALLOC_COUNT\r
-#ifdef SHOW_ALLOC_COUNT\r
-static size_t count_alloc = 0;\r
-static size_t count_reuse = 0;\r
-\r
-static void\r
-show_alloc(void)\r
-{\r
-    fprintf(stderr, "List allocations: %" PY_FORMAT_SIZE_T "d\n",\r
-        count_alloc);\r
-    fprintf(stderr, "List reuse through freelist: %" PY_FORMAT_SIZE_T\r
-        "d\n", count_reuse);\r
-    fprintf(stderr, "%.2f%% reuse rate\n\n",\r
-        (100.0*count_reuse/(count_alloc+count_reuse)));\r
-}\r
-#endif\r
-\r
-/* Empty list reuse scheme to save calls to malloc and free */\r
-#ifndef PyList_MAXFREELIST\r
-#define PyList_MAXFREELIST 80\r
-#endif\r
-static PyListObject *free_list[PyList_MAXFREELIST];\r
-static int numfree = 0;\r
-\r
-void\r
-PyList_Fini(void)\r
-{\r
-    PyListObject *op;\r
-\r
-    while (numfree) {\r
-        op = free_list[--numfree];\r
-        assert(PyList_CheckExact(op));\r
-        PyObject_GC_Del(op);\r
-    }\r
-}\r
-\r
-PyObject *\r
-PyList_New(Py_ssize_t size)\r
-{\r
-    PyListObject *op;\r
-    size_t nbytes;\r
-#ifdef SHOW_ALLOC_COUNT\r
-    static int initialized = 0;\r
-    if (!initialized) {\r
-        Py_AtExit(show_alloc);\r
-        initialized = 1;\r
-    }\r
-#endif\r
-\r
-    if (size < 0) {\r
-        PyErr_BadInternalCall();\r
-        return NULL;\r
-    }\r
-    /* Check for overflow without an actual overflow,\r
-     *  which can cause compiler to optimise out */\r
-    if ((size_t)size > PY_SIZE_MAX / sizeof(PyObject *))\r
-        return PyErr_NoMemory();\r
-    nbytes = size * sizeof(PyObject *);\r
-    if (numfree) {\r
-        numfree--;\r
-        op = free_list[numfree];\r
-        _Py_NewReference((PyObject *)op);\r
-#ifdef SHOW_ALLOC_COUNT\r
-        count_reuse++;\r
-#endif\r
-    } else {\r
-        op = PyObject_GC_New(PyListObject, &PyList_Type);\r
-        if (op == NULL)\r
-            return NULL;\r
-#ifdef SHOW_ALLOC_COUNT\r
-        count_alloc++;\r
-#endif\r
-    }\r
-    if (size <= 0)\r
-        op->ob_item = NULL;\r
-    else {\r
-        op->ob_item = (PyObject **) PyMem_MALLOC(nbytes);\r
-        if (op->ob_item == NULL) {\r
-            Py_DECREF(op);\r
-            return PyErr_NoMemory();\r
-        }\r
-        memset(op->ob_item, 0, nbytes);\r
-    }\r
-    Py_SIZE(op) = size;\r
-    op->allocated = size;\r
-    _PyObject_GC_TRACK(op);\r
-    return (PyObject *) op;\r
-}\r
-\r
-Py_ssize_t\r
-PyList_Size(PyObject *op)\r
-{\r
-    if (!PyList_Check(op)) {\r
-        PyErr_BadInternalCall();\r
-        return -1;\r
-    }\r
-    else\r
-        return Py_SIZE(op);\r
-}\r
-\r
-static PyObject *indexerr = NULL;\r
-\r
-PyObject *\r
-PyList_GetItem(PyObject *op, Py_ssize_t i)\r
-{\r
-    if (!PyList_Check(op)) {\r
-        PyErr_BadInternalCall();\r
-        return NULL;\r
-    }\r
-    if (i < 0 || i >= Py_SIZE(op)) {\r
-        if (indexerr == NULL) {\r
-            indexerr = PyString_FromString(\r
-                "list index out of range");\r
-            if (indexerr == NULL)\r
-                return NULL;\r
-        }\r
-        PyErr_SetObject(PyExc_IndexError, indexerr);\r
-        return NULL;\r
-    }\r
-    return ((PyListObject *)op) -> ob_item[i];\r
-}\r
-\r
-int\r
-PyList_SetItem(register PyObject *op, register Py_ssize_t i,\r
-               register PyObject *newitem)\r
-{\r
-    register PyObject *olditem;\r
-    register PyObject **p;\r
-    if (!PyList_Check(op)) {\r
-        Py_XDECREF(newitem);\r
-        PyErr_BadInternalCall();\r
-        return -1;\r
-    }\r
-    if (i < 0 || i >= Py_SIZE(op)) {\r
-        Py_XDECREF(newitem);\r
-        PyErr_SetString(PyExc_IndexError,\r
-                        "list assignment index out of range");\r
-        return -1;\r
-    }\r
-    p = ((PyListObject *)op) -> ob_item + i;\r
-    olditem = *p;\r
-    *p = newitem;\r
-    Py_XDECREF(olditem);\r
-    return 0;\r
-}\r
-\r
-static int\r
-ins1(PyListObject *self, Py_ssize_t where, PyObject *v)\r
-{\r
-    Py_ssize_t i, n = Py_SIZE(self);\r
-    PyObject **items;\r
-    if (v == NULL) {\r
-        PyErr_BadInternalCall();\r
-        return -1;\r
-    }\r
-    if (n == PY_SSIZE_T_MAX) {\r
-        PyErr_SetString(PyExc_OverflowError,\r
-            "cannot add more objects to list");\r
-        return -1;\r
-    }\r
-\r
-    if (list_resize(self, n+1) == -1)\r
-        return -1;\r
-\r
-    if (where < 0) {\r
-        where += n;\r
-        if (where < 0)\r
-            where = 0;\r
-    }\r
-    if (where > n)\r
-        where = n;\r
-    items = self->ob_item;\r
-    for (i = n; --i >= where; )\r
-        items[i+1] = items[i];\r
-    Py_INCREF(v);\r
-    items[where] = v;\r
-    return 0;\r
-}\r
-\r
-int\r
-PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)\r
-{\r
-    if (!PyList_Check(op)) {\r
-        PyErr_BadInternalCall();\r
-        return -1;\r
-    }\r
-    return ins1((PyListObject *)op, where, newitem);\r
-}\r
-\r
-static int\r
-app1(PyListObject *self, PyObject *v)\r
-{\r
-    Py_ssize_t n = PyList_GET_SIZE(self);\r
-\r
-    assert (v != NULL);\r
-    if (n == PY_SSIZE_T_MAX) {\r
-        PyErr_SetString(PyExc_OverflowError,\r
-            "cannot add more objects to list");\r
-        return -1;\r
-    }\r
-\r
-    if (list_resize(self, n+1) == -1)\r
-        return -1;\r
-\r
-    Py_INCREF(v);\r
-    PyList_SET_ITEM(self, n, v);\r
-    return 0;\r
-}\r
-\r
-int\r
-PyList_Append(PyObject *op, PyObject *newitem)\r
-{\r
-    if (PyList_Check(op) && (newitem != NULL))\r
-        return app1((PyListObject *)op, newitem);\r
-    PyErr_BadInternalCall();\r
-    return -1;\r
-}\r
-\r
-/* Methods */\r
-\r
-static void\r
-list_dealloc(PyListObject *op)\r
-{\r
-    Py_ssize_t i;\r
-    PyObject_GC_UnTrack(op);\r
-    Py_TRASHCAN_SAFE_BEGIN(op)\r
-    if (op->ob_item != NULL) {\r
-        /* Do it backwards, for Christian Tismer.\r
-           There's a simple test case where somehow this reduces\r
-           thrashing when a *very* large list is created and\r
-           immediately deleted. */\r
-        i = Py_SIZE(op);\r
-        while (--i >= 0) {\r
-            Py_XDECREF(op->ob_item[i]);\r
-        }\r
-        PyMem_FREE(op->ob_item);\r
-    }\r
-    if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op))\r
-        free_list[numfree++] = op;\r
-    else\r
-        Py_TYPE(op)->tp_free((PyObject *)op);\r
-    Py_TRASHCAN_SAFE_END(op)\r
-}\r
-\r
-static int\r
-list_print(PyListObject *op, FILE *fp, int flags)\r
-{\r
-    int rc;\r
-    Py_ssize_t i;\r
-    PyObject *item;\r
-\r
-    rc = Py_ReprEnter((PyObject*)op);\r
-    if (rc != 0) {\r
-        if (rc < 0)\r
-            return rc;\r
-        Py_BEGIN_ALLOW_THREADS\r
-        fprintf(fp, "[...]");\r
-        Py_END_ALLOW_THREADS\r
-        return 0;\r
-    }\r
-    Py_BEGIN_ALLOW_THREADS\r
-    fprintf(fp, "[");\r
-    Py_END_ALLOW_THREADS\r
-    for (i = 0; i < Py_SIZE(op); i++) {\r
-        item = op->ob_item[i];\r
-        Py_INCREF(item);\r
-        if (i > 0) {\r
-            Py_BEGIN_ALLOW_THREADS\r
-            fprintf(fp, ", ");\r
-            Py_END_ALLOW_THREADS\r
-        }\r
-        if (PyObject_Print(item, fp, 0) != 0) {\r
-            Py_DECREF(item);\r
-            Py_ReprLeave((PyObject *)op);\r
-            return -1;\r
-        }\r
-        Py_DECREF(item);\r
-    }\r
-    Py_BEGIN_ALLOW_THREADS\r
-    fprintf(fp, "]");\r
-    Py_END_ALLOW_THREADS\r
-    Py_ReprLeave((PyObject *)op);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-list_repr(PyListObject *v)\r
-{\r
-    Py_ssize_t i;\r
-    PyObject *s, *temp;\r
-    PyObject *pieces = NULL, *result = NULL;\r
-\r
-    i = Py_ReprEnter((PyObject*)v);\r
-    if (i != 0) {\r
-        return i > 0 ? PyString_FromString("[...]") : NULL;\r
-    }\r
-\r
-    if (Py_SIZE(v) == 0) {\r
-        result = PyString_FromString("[]");\r
-        goto Done;\r
-    }\r
-\r
-    pieces = PyList_New(0);\r
-    if (pieces == NULL)\r
-        goto Done;\r
-\r
-    /* Do repr() on each element.  Note that this may mutate the list,\r
-       so must refetch the list size on each iteration. */\r
-    for (i = 0; i < Py_SIZE(v); ++i) {\r
-        int status;\r
-        if (Py_EnterRecursiveCall(" while getting the repr of a list"))\r
-            goto Done;\r
-        s = PyObject_Repr(v->ob_item[i]);\r
-        Py_LeaveRecursiveCall();\r
-        if (s == NULL)\r
-            goto Done;\r
-        status = PyList_Append(pieces, s);\r
-        Py_DECREF(s);  /* append created a new ref */\r
-        if (status < 0)\r
-            goto Done;\r
-    }\r
-\r
-    /* Add "[]" decorations to the first and last items. */\r
-    assert(PyList_GET_SIZE(pieces) > 0);\r
-    s = PyString_FromString("[");\r
-    if (s == NULL)\r
-        goto Done;\r
-    temp = PyList_GET_ITEM(pieces, 0);\r
-    PyString_ConcatAndDel(&s, temp);\r
-    PyList_SET_ITEM(pieces, 0, s);\r
-    if (s == NULL)\r
-        goto Done;\r
-\r
-    s = PyString_FromString("]");\r
-    if (s == NULL)\r
-        goto Done;\r
-    temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);\r
-    PyString_ConcatAndDel(&temp, s);\r
-    PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);\r
-    if (temp == NULL)\r
-        goto Done;\r
-\r
-    /* Paste them all together with ", " between. */\r
-    s = PyString_FromString(", ");\r
-    if (s == NULL)\r
-        goto Done;\r
-    result = _PyString_Join(s, pieces);\r
-    Py_DECREF(s);\r
-\r
-Done:\r
-    Py_XDECREF(pieces);\r
-    Py_ReprLeave((PyObject *)v);\r
-    return result;\r
-}\r
-\r
-static Py_ssize_t\r
-list_length(PyListObject *a)\r
-{\r
-    return Py_SIZE(a);\r
-}\r
-\r
-static int\r
-list_contains(PyListObject *a, PyObject *el)\r
-{\r
-    Py_ssize_t i;\r
-    int cmp;\r
-\r
-    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)\r
-        cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),\r
-                                           Py_EQ);\r
-    return cmp;\r
-}\r
-\r
-static PyObject *\r
-list_item(PyListObject *a, Py_ssize_t i)\r
-{\r
-    if (i < 0 || i >= Py_SIZE(a)) {\r
-        if (indexerr == NULL) {\r
-            indexerr = PyString_FromString(\r
-                "list index out of range");\r
-            if (indexerr == NULL)\r
-                return NULL;\r
-        }\r
-        PyErr_SetObject(PyExc_IndexError, indexerr);\r
-        return NULL;\r
-    }\r
-    Py_INCREF(a->ob_item[i]);\r
-    return a->ob_item[i];\r
-}\r
-\r
-static PyObject *\r
-list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)\r
-{\r
-    PyListObject *np;\r
-    PyObject **src, **dest;\r
-    Py_ssize_t i, len;\r
-    if (ilow < 0)\r
-        ilow = 0;\r
-    else if (ilow > Py_SIZE(a))\r
-        ilow = Py_SIZE(a);\r
-    if (ihigh < ilow)\r
-        ihigh = ilow;\r
-    else if (ihigh > Py_SIZE(a))\r
-        ihigh = Py_SIZE(a);\r
-    len = ihigh - ilow;\r
-    np = (PyListObject *) PyList_New(len);\r
-    if (np == NULL)\r
-        return NULL;\r
-\r
-    src = a->ob_item + ilow;\r
-    dest = np->ob_item;\r
-    for (i = 0; i < len; i++) {\r
-        PyObject *v = src[i];\r
-        Py_INCREF(v);\r
-        dest[i] = v;\r
-    }\r
-    return (PyObject *)np;\r
-}\r
-\r
-PyObject *\r
-PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)\r
-{\r
-    if (!PyList_Check(a)) {\r
-        PyErr_BadInternalCall();\r
-        return NULL;\r
-    }\r
-    return list_slice((PyListObject *)a, ilow, ihigh);\r
-}\r
-\r
-static PyObject *\r
-list_concat(PyListObject *a, PyObject *bb)\r
-{\r
-    Py_ssize_t size;\r
-    Py_ssize_t i;\r
-    PyObject **src, **dest;\r
-    PyListObject *np;\r
-    if (!PyList_Check(bb)) {\r
-        PyErr_Format(PyExc_TypeError,\r
-                  "can only concatenate list (not \"%.200s\") to list",\r
-                  bb->ob_type->tp_name);\r
-        return NULL;\r
-    }\r
-#define b ((PyListObject *)bb)\r
-    size = Py_SIZE(a) + Py_SIZE(b);\r
-    if (size < 0)\r
-        return PyErr_NoMemory();\r
-    np = (PyListObject *) PyList_New(size);\r
-    if (np == NULL) {\r
-        return NULL;\r
-    }\r
-    src = a->ob_item;\r
-    dest = np->ob_item;\r
-    for (i = 0; i < Py_SIZE(a); i++) {\r
-        PyObject *v = src[i];\r
-        Py_INCREF(v);\r
-        dest[i] = v;\r
-    }\r
-    src = b->ob_item;\r
-    dest = np->ob_item + Py_SIZE(a);\r
-    for (i = 0; i < Py_SIZE(b); i++) {\r
-        PyObject *v = src[i];\r
-        Py_INCREF(v);\r
-        dest[i] = v;\r
-    }\r
-    return (PyObject *)np;\r
-#undef b\r
-}\r
-\r
-static PyObject *\r
-list_repeat(PyListObject *a, Py_ssize_t n)\r
-{\r
-    Py_ssize_t i, j;\r
-    Py_ssize_t size;\r
-    PyListObject *np;\r
-    PyObject **p, **items;\r
-    PyObject *elem;\r
-    if (n < 0)\r
-        n = 0;\r
-    if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n)\r
-        return PyErr_NoMemory();\r
-    size = Py_SIZE(a) * n;\r
-    if (size == 0)\r
-        return PyList_New(0);\r
-    np = (PyListObject *) PyList_New(size);\r
-    if (np == NULL)\r
-        return NULL;\r
-\r
-    items = np->ob_item;\r
-    if (Py_SIZE(a) == 1) {\r
-        elem = a->ob_item[0];\r
-        for (i = 0; i < n; i++) {\r
-            items[i] = elem;\r
-            Py_INCREF(elem);\r
-        }\r
-        return (PyObject *) np;\r
-    }\r
-    p = np->ob_item;\r
-    items = a->ob_item;\r
-    for (i = 0; i < n; i++) {\r
-        for (j = 0; j < Py_SIZE(a); j++) {\r
-            *p = items[j];\r
-            Py_INCREF(*p);\r
-            p++;\r
-        }\r
-    }\r
-    return (PyObject *) np;\r
-}\r
-\r
-static int\r
-list_clear(PyListObject *a)\r
-{\r
-    Py_ssize_t i;\r
-    PyObject **item = a->ob_item;\r
-    if (item != NULL) {\r
-        /* Because XDECREF can recursively invoke operations on\r
-           this list, we make it empty first. */\r
-        i = Py_SIZE(a);\r
-        Py_SIZE(a) = 0;\r
-        a->ob_item = NULL;\r
-        a->allocated = 0;\r
-        while (--i >= 0) {\r
-            Py_XDECREF(item[i]);\r
-        }\r
-        PyMem_FREE(item);\r
-    }\r
-    /* Never fails; the return value can be ignored.\r
-       Note that there is no guarantee that the list is actually empty\r
-       at this point, because XDECREF may have populated it again! */\r
-    return 0;\r
-}\r
-\r
-/* a[ilow:ihigh] = v if v != NULL.\r
- * del a[ilow:ihigh] if v == NULL.\r
- *\r
- * Special speed gimmick:  when v is NULL and ihigh - ilow <= 8, it's\r
- * guaranteed the call cannot fail.\r
- */\r
-static int\r
-list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)\r
-{\r
-    /* Because [X]DECREF can recursively invoke list operations on\r
-       this list, we must postpone all [X]DECREF activity until\r
-       after the list is back in its canonical shape.  Therefore\r
-       we must allocate an additional array, 'recycle', into which\r
-       we temporarily copy the items that are deleted from the\r
-       list. :-( */\r
-    PyObject *recycle_on_stack[8];\r
-    PyObject **recycle = recycle_on_stack; /* will allocate more if needed */\r
-    PyObject **item;\r
-    PyObject **vitem = NULL;\r
-    PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */\r
-    Py_ssize_t n; /* # of elements in replacement list */\r
-    Py_ssize_t norig; /* # of elements in list getting replaced */\r
-    Py_ssize_t d; /* Change in size */\r
-    Py_ssize_t k;\r
-    size_t s;\r
-    int result = -1;            /* guilty until proved innocent */\r
-#define b ((PyListObject *)v)\r
-    if (v == NULL)\r
-        n = 0;\r
-    else {\r
-        if (a == b) {\r
-            /* Special case "a[i:j] = a" -- copy b first */\r
-            v = list_slice(b, 0, Py_SIZE(b));\r
-            if (v == NULL)\r
-                return result;\r
-            result = list_ass_slice(a, ilow, ihigh, v);\r
-            Py_DECREF(v);\r
-            return result;\r
-        }\r
-        v_as_SF = PySequence_Fast(v, "can only assign an iterable");\r
-        if(v_as_SF == NULL)\r
-            goto Error;\r
-        n = PySequence_Fast_GET_SIZE(v_as_SF);\r
-        vitem = PySequence_Fast_ITEMS(v_as_SF);\r
-    }\r
-    if (ilow < 0)\r
-        ilow = 0;\r
-    else if (ilow > Py_SIZE(a))\r
-        ilow = Py_SIZE(a);\r
-\r
-    if (ihigh < ilow)\r
-        ihigh = ilow;\r
-    else if (ihigh > Py_SIZE(a))\r
-        ihigh = Py_SIZE(a);\r
-\r
-    norig = ihigh - ilow;\r
-    assert(norig >= 0);\r
-    d = n - norig;\r
-    if (Py_SIZE(a) + d == 0) {\r
-        Py_XDECREF(v_as_SF);\r
-        return list_clear(a);\r
-    }\r
-    item = a->ob_item;\r
-    /* recycle the items that we are about to remove */\r
-    s = norig * sizeof(PyObject *);\r
-    if (s > sizeof(recycle_on_stack)) {\r
-        recycle = (PyObject **)PyMem_MALLOC(s);\r
-        if (recycle == NULL) {\r
-            PyErr_NoMemory();\r
-            goto Error;\r
-        }\r
-    }\r
-    memcpy(recycle, &item[ilow], s);\r
-\r
-    if (d < 0) { /* Delete -d items */\r
-        memmove(&item[ihigh+d], &item[ihigh],\r
-            (Py_SIZE(a) - ihigh)*sizeof(PyObject *));\r
-        list_resize(a, Py_SIZE(a) + d);\r
-        item = a->ob_item;\r
-    }\r
-    else if (d > 0) { /* Insert d items */\r
-        k = Py_SIZE(a);\r
-        if (list_resize(a, k+d) < 0)\r
-            goto Error;\r
-        item = a->ob_item;\r
-        memmove(&item[ihigh+d], &item[ihigh],\r
-            (k - ihigh)*sizeof(PyObject *));\r
-    }\r
-    for (k = 0; k < n; k++, ilow++) {\r
-        PyObject *w = vitem[k];\r
-        Py_XINCREF(w);\r
-        item[ilow] = w;\r
-    }\r
-    for (k = norig - 1; k >= 0; --k)\r
-        Py_XDECREF(recycle[k]);\r
-    result = 0;\r
- Error:\r
-    if (recycle != recycle_on_stack)\r
-        PyMem_FREE(recycle);\r
-    Py_XDECREF(v_as_SF);\r
-    return result;\r
-#undef b\r
-}\r
-\r
-int\r
-PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)\r
-{\r
-    if (!PyList_Check(a)) {\r
-        PyErr_BadInternalCall();\r
-        return -1;\r
-    }\r
-    return list_ass_slice((PyListObject *)a, ilow, ihigh, v);\r
-}\r
-\r
-static PyObject *\r
-list_inplace_repeat(PyListObject *self, Py_ssize_t n)\r
-{\r
-    PyObject **items;\r
-    Py_ssize_t size, i, j, p;\r
-\r
-\r
-    size = PyList_GET_SIZE(self);\r
-    if (size == 0 || n == 1) {\r
-        Py_INCREF(self);\r
-        return (PyObject *)self;\r
-    }\r
-\r
-    if (n < 1) {\r
-        (void)list_clear(self);\r
-        Py_INCREF(self);\r
-        return (PyObject *)self;\r
-    }\r
-\r
-    if (size > PY_SSIZE_T_MAX / n) {\r
-        return PyErr_NoMemory();\r
-    }\r
-\r
-    if (list_resize(self, size*n) == -1)\r
-        return NULL;\r
-\r
-    p = size;\r
-    items = self->ob_item;\r
-    for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */\r
-        for (j = 0; j < size; j++) {\r
-            PyObject *o = items[j];\r
-            Py_INCREF(o);\r
-            items[p++] = o;\r
-        }\r
-    }\r
-    Py_INCREF(self);\r
-    return (PyObject *)self;\r
-}\r
-\r
-static int\r
-list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v)\r
-{\r
-    PyObject *old_value;\r
-    if (i < 0 || i >= Py_SIZE(a)) {\r
-        PyErr_SetString(PyExc_IndexError,\r
-                        "list assignment index out of range");\r
-        return -1;\r
-    }\r
-    if (v == NULL)\r
-        return list_ass_slice(a, i, i+1, v);\r
-    Py_INCREF(v);\r
-    old_value = a->ob_item[i];\r
-    a->ob_item[i] = v;\r
-    Py_DECREF(old_value);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-listinsert(PyListObject *self, PyObject *args)\r
-{\r
-    Py_ssize_t i;\r
-    PyObject *v;\r
-    if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))\r
-        return NULL;\r
-    if (ins1(self, i, v) == 0)\r
-        Py_RETURN_NONE;\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-listappend(PyListObject *self, PyObject *v)\r
-{\r
-    if (app1(self, v) == 0)\r
-        Py_RETURN_NONE;\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-listextend(PyListObject *self, PyObject *b)\r
-{\r
-    PyObject *it;      /* iter(v) */\r
-    Py_ssize_t m;                  /* size of self */\r
-    Py_ssize_t n;                  /* guess for size of b */\r
-    Py_ssize_t mn;                 /* m + n */\r
-    Py_ssize_t i;\r
-    PyObject *(*iternext)(PyObject *);\r
-\r
-    /* Special cases:\r
-       1) lists and tuples which can use PySequence_Fast ops\r
-       2) extending self to self requires making a copy first\r
-    */\r
-    if (PyList_CheckExact(b) || PyTuple_CheckExact(b) || (PyObject *)self == b) {\r
-        PyObject **src, **dest;\r
-        b = PySequence_Fast(b, "argument must be iterable");\r
-        if (!b)\r
-            return NULL;\r
-        n = PySequence_Fast_GET_SIZE(b);\r
-        if (n == 0) {\r
-            /* short circuit when b is empty */\r
-            Py_DECREF(b);\r
-            Py_RETURN_NONE;\r
-        }\r
-        m = Py_SIZE(self);\r
-        if (list_resize(self, m + n) == -1) {\r
-            Py_DECREF(b);\r
-            return NULL;\r
-        }\r
-        /* note that we may still have self == b here for the\r
-         * situation a.extend(a), but the following code works\r
-         * in that case too.  Just make sure to resize self\r
-         * before calling PySequence_Fast_ITEMS.\r
-         */\r
-        /* populate the end of self with b's items */\r
-        src = PySequence_Fast_ITEMS(b);\r
-        dest = self->ob_item + m;\r
-        for (i = 0; i < n; i++) {\r
-            PyObject *o = src[i];\r
-            Py_INCREF(o);\r
-            dest[i] = o;\r
-        }\r
-        Py_DECREF(b);\r
-        Py_RETURN_NONE;\r
-    }\r
-\r
-    it = PyObject_GetIter(b);\r
-    if (it == NULL)\r
-        return NULL;\r
-    iternext = *it->ob_type->tp_iternext;\r
-\r
-    /* Guess a result list size. */\r
-    n = _PyObject_LengthHint(b, 8);\r
-    if (n == -1) {\r
-        Py_DECREF(it);\r
-        return NULL;\r
-    }\r
-    m = Py_SIZE(self);\r
-    mn = m + n;\r
-    if (mn >= m) {\r
-        /* Make room. */\r
-        if (list_resize(self, mn) == -1)\r
-            goto error;\r
-        /* Make the list sane again. */\r
-        Py_SIZE(self) = m;\r
-    }\r
-    /* Else m + n overflowed; on the chance that n lied, and there really\r
-     * is enough room, ignore it.  If n was telling the truth, we'll\r
-     * eventually run out of memory during the loop.\r
-     */\r
-\r
-    /* Run iterator to exhaustion. */\r
-    for (;;) {\r
-        PyObject *item = iternext(it);\r
-        if (item == NULL) {\r
-            if (PyErr_Occurred()) {\r
-                if (PyErr_ExceptionMatches(PyExc_StopIteration))\r
-                    PyErr_Clear();\r
-                else\r
-                    goto error;\r
-            }\r
-            break;\r
-        }\r
-        if (Py_SIZE(self) < self->allocated) {\r
-            /* steals ref */\r
-            PyList_SET_ITEM(self, Py_SIZE(self), item);\r
-            ++Py_SIZE(self);\r
-        }\r
-        else {\r
-            int status = app1(self, item);\r
-            Py_DECREF(item);  /* append creates a new ref */\r
-            if (status < 0)\r
-                goto error;\r
-        }\r
-    }\r
-\r
-    /* Cut back result list if initial guess was too large. */\r
-    if (Py_SIZE(self) < self->allocated)\r
-        list_resize(self, Py_SIZE(self));  /* shrinking can't fail */\r
-\r
-    Py_DECREF(it);\r
-    Py_RETURN_NONE;\r
-\r
-  error:\r
-    Py_DECREF(it);\r
-    return NULL;\r
-}\r
-\r
-PyObject *\r
-_PyList_Extend(PyListObject *self, PyObject *b)\r
-{\r
-    return listextend(self, b);\r
-}\r
-\r
-static PyObject *\r
-list_inplace_concat(PyListObject *self, PyObject *other)\r
-{\r
-    PyObject *result;\r
-\r
-    result = listextend(self, other);\r
-    if (result == NULL)\r
-        return result;\r
-    Py_DECREF(result);\r
-    Py_INCREF(self);\r
-    return (PyObject *)self;\r
-}\r
-\r
-static PyObject *\r
-listpop(PyListObject *self, PyObject *args)\r
-{\r
-    Py_ssize_t i = -1;\r
-    PyObject *v;\r
-    int status;\r
-\r
-    if (!PyArg_ParseTuple(args, "|n:pop", &i))\r
-        return NULL;\r
-\r
-    if (Py_SIZE(self) == 0) {\r
-        /* Special-case most common failure cause */\r
-        PyErr_SetString(PyExc_IndexError, "pop from empty list");\r
-        return NULL;\r
-    }\r
-    if (i < 0)\r
-        i += Py_SIZE(self);\r
-    if (i < 0 || i >= Py_SIZE(self)) {\r
-        PyErr_SetString(PyExc_IndexError, "pop index out of range");\r
-        return NULL;\r
-    }\r
-    v = self->ob_item[i];\r
-    if (i == Py_SIZE(self) - 1) {\r
-        status = list_resize(self, Py_SIZE(self) - 1);\r
-        assert(status >= 0);\r
-        return v; /* and v now owns the reference the list had */\r
-    }\r
-    Py_INCREF(v);\r
-    status = list_ass_slice(self, i, i+1, (PyObject *)NULL);\r
-    assert(status >= 0);\r
-    /* Use status, so that in a release build compilers don't\r
-     * complain about the unused name.\r
-     */\r
-    (void) status;\r
-\r
-    return v;\r
-}\r
-\r
-/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */\r
-static void\r
-reverse_slice(PyObject **lo, PyObject **hi)\r
-{\r
-    assert(lo && hi);\r
-\r
-    --hi;\r
-    while (lo < hi) {\r
-        PyObject *t = *lo;\r
-        *lo = *hi;\r
-        *hi = t;\r
-        ++lo;\r
-        --hi;\r
-    }\r
-}\r
-\r
-/* Lots of code for an adaptive, stable, natural mergesort.  There are many\r
- * pieces to this algorithm; read listsort.txt for overviews and details.\r
- */\r
-\r
-/* Comparison function.  Takes care of calling a user-supplied\r
- * comparison function (any callable Python object), which must not be\r
- * NULL (use the ISLT macro if you don't know, or call PyObject_RichCompareBool\r
- * with Py_LT if you know it's NULL).\r
- * Returns -1 on error, 1 if x < y, 0 if x >= y.\r
- */\r
-static int\r
-islt(PyObject *x, PyObject *y, PyObject *compare)\r
-{\r
-    PyObject *res;\r
-    PyObject *args;\r
-    Py_ssize_t i;\r
-\r
-    assert(compare != NULL);\r
-    /* Call the user's comparison function and translate the 3-way\r
-     * result into true or false (or error).\r
-     */\r
-    args = PyTuple_New(2);\r
-    if (args == NULL)\r
-        return -1;\r
-    Py_INCREF(x);\r
-    Py_INCREF(y);\r
-    PyTuple_SET_ITEM(args, 0, x);\r
-    PyTuple_SET_ITEM(args, 1, y);\r
-    res = PyObject_Call(compare, args, NULL);\r
-    Py_DECREF(args);\r
-    if (res == NULL)\r
-        return -1;\r
-    if (!PyInt_Check(res)) {\r
-        PyErr_Format(PyExc_TypeError,\r
-                     "comparison function must return int, not %.200s",\r
-                     res->ob_type->tp_name);\r
-        Py_DECREF(res);\r
-        return -1;\r
-    }\r
-    i = PyInt_AsLong(res);\r
-    Py_DECREF(res);\r
-    return i < 0;\r
-}\r
-\r
-/* If COMPARE is NULL, calls PyObject_RichCompareBool with Py_LT, else calls\r
- * islt.  This avoids a layer of function call in the usual case, and\r
- * sorting does many comparisons.\r
- * Returns -1 on error, 1 if x < y, 0 if x >= y.\r
- */\r
-#define ISLT(X, Y, COMPARE) ((COMPARE) == NULL ?                        \\r
-                 PyObject_RichCompareBool(X, Y, Py_LT) :                \\r
-                 islt(X, Y, COMPARE))\r
-\r
-/* Compare X to Y via "<".  Goto "fail" if the comparison raises an\r
-   error.  Else "k" is set to true iff X<Y, and an "if (k)" block is\r
-   started.  It makes more sense in context <wink>.  X and Y are PyObject*s.\r
-*/\r
-#define IFLT(X, Y) if ((k = ISLT(X, Y, compare)) < 0) goto fail;  \\r
-           if (k)\r
-\r
-/* binarysort is the best method for sorting small arrays: it does\r
-   few compares, but can do data movement quadratic in the number of\r
-   elements.\r
-   [lo, hi) is a contiguous slice of a list, and is sorted via\r
-   binary insertion.  This sort is stable.\r
-   On entry, must have lo <= start <= hi, and that [lo, start) is already\r
-   sorted (pass start == lo if you don't know!).\r
-   If islt() complains return -1, else 0.\r
-   Even in case of error, the output slice will be some permutation of\r
-   the input (nothing is lost or duplicated).\r
-*/\r
-static int\r
-binarysort(PyObject **lo, PyObject **hi, PyObject **start, PyObject *compare)\r
-     /* compare -- comparison function object, or NULL for default */\r
-{\r
-    register Py_ssize_t k;\r
-    register PyObject **l, **p, **r;\r
-    register PyObject *pivot;\r
-\r
-    assert(lo <= start && start <= hi);\r
-    /* assert [lo, start) is sorted */\r
-    if (lo == start)\r
-        ++start;\r
-    for (; start < hi; ++start) {\r
-        /* set l to where *start belongs */\r
-        l = lo;\r
-        r = start;\r
-        pivot = *r;\r
-        /* Invariants:\r
-         * pivot >= all in [lo, l).\r
-         * pivot  < all in [r, start).\r
-         * The second is vacuously true at the start.\r
-         */\r
-        assert(l < r);\r
-        do {\r
-            p = l + ((r - l) >> 1);\r
-            IFLT(pivot, *p)\r
-                r = p;\r
-            else\r
-                l = p+1;\r
-        } while (l < r);\r
-        assert(l == r);\r
-        /* The invariants still hold, so pivot >= all in [lo, l) and\r
-           pivot < all in [l, start), so pivot belongs at l.  Note\r
-           that if there are elements equal to pivot, l points to the\r
-           first slot after them -- that's why this sort is stable.\r
-           Slide over to make room.\r
-           Caution: using memmove is much slower under MSVC 5;\r
-           we're not usually moving many slots. */\r
-        for (p = start; p > l; --p)\r
-            *p = *(p-1);\r
-        *l = pivot;\r
-    }\r
-    return 0;\r
-\r
- fail:\r
-    return -1;\r
-}\r
-\r
-/*\r
-Return the length of the run beginning at lo, in the slice [lo, hi).  lo < hi\r
-is required on entry.  "A run" is the longest ascending sequence, with\r
-\r
-    lo[0] <= lo[1] <= lo[2] <= ...\r
-\r
-or the longest descending sequence, with\r
-\r
-    lo[0] > lo[1] > lo[2] > ...\r
-\r
-Boolean *descending is set to 0 in the former case, or to 1 in the latter.\r
-For its intended use in a stable mergesort, the strictness of the defn of\r
-"descending" is needed so that the caller can safely reverse a descending\r
-sequence without violating stability (strict > ensures there are no equal\r
-elements to get out of order).\r
-\r
-Returns -1 in case of error.\r
-*/\r
-static Py_ssize_t\r
-count_run(PyObject **lo, PyObject **hi, PyObject *compare, int *descending)\r
-{\r
-    Py_ssize_t k;\r
-    Py_ssize_t n;\r
-\r
-    assert(lo < hi);\r
-    *descending = 0;\r
-    ++lo;\r
-    if (lo == hi)\r
-        return 1;\r
-\r
-    n = 2;\r
-    IFLT(*lo, *(lo-1)) {\r
-        *descending = 1;\r
-        for (lo = lo+1; lo < hi; ++lo, ++n) {\r
-            IFLT(*lo, *(lo-1))\r
-                ;\r
-            else\r
-                break;\r
-        }\r
-    }\r
-    else {\r
-        for (lo = lo+1; lo < hi; ++lo, ++n) {\r
-            IFLT(*lo, *(lo-1))\r
-                break;\r
-        }\r
-    }\r
-\r
-    return n;\r
-fail:\r
-    return -1;\r
-}\r
-\r
-/*\r
-Locate the proper position of key in a sorted vector; if the vector contains\r
-an element equal to key, return the position immediately to the left of\r
-the leftmost equal element.  [gallop_right() does the same except returns\r
-the position to the right of the rightmost equal element (if any).]\r
-\r
-"a" is a sorted vector with n elements, starting at a[0].  n must be > 0.\r
-\r
-"hint" is an index at which to begin the search, 0 <= hint < n.  The closer\r
-hint is to the final result, the faster this runs.\r
-\r
-The return value is the int k in 0..n such that\r
-\r
-    a[k-1] < key <= a[k]\r
-\r
-pretending that *(a-1) is minus infinity and a[n] is plus infinity.  IOW,\r
-key belongs at index k; or, IOW, the first k elements of a should precede\r
-key, and the last n-k should follow key.\r
-\r
-Returns -1 on error.  See listsort.txt for info on the method.\r
-*/\r
-static Py_ssize_t\r
-gallop_left(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare)\r
-{\r
-    Py_ssize_t ofs;\r
-    Py_ssize_t lastofs;\r
-    Py_ssize_t k;\r
-\r
-    assert(key && a && n > 0 && hint >= 0 && hint < n);\r
-\r
-    a += hint;\r
-    lastofs = 0;\r
-    ofs = 1;\r
-    IFLT(*a, key) {\r
-        /* a[hint] < key -- gallop right, until\r
-         * a[hint + lastofs] < key <= a[hint + ofs]\r
-         */\r
-        const Py_ssize_t maxofs = n - hint;             /* &a[n-1] is highest */\r
-        while (ofs < maxofs) {\r
-            IFLT(a[ofs], key) {\r
-                lastofs = ofs;\r
-                ofs = (ofs << 1) + 1;\r
-                if (ofs <= 0)                   /* int overflow */\r
-                    ofs = maxofs;\r
-            }\r
-            else                /* key <= a[hint + ofs] */\r
-                break;\r
-        }\r
-        if (ofs > maxofs)\r
-            ofs = maxofs;\r
-        /* Translate back to offsets relative to &a[0]. */\r
-        lastofs += hint;\r
-        ofs += hint;\r
-    }\r
-    else {\r
-        /* key <= a[hint] -- gallop left, until\r
-         * a[hint - ofs] < key <= a[hint - lastofs]\r
-         */\r
-        const Py_ssize_t maxofs = hint + 1;             /* &a[0] is lowest */\r
-        while (ofs < maxofs) {\r
-            IFLT(*(a-ofs), key)\r
-                break;\r
-            /* key <= a[hint - ofs] */\r
-            lastofs = ofs;\r
-            ofs = (ofs << 1) + 1;\r
-            if (ofs <= 0)               /* int overflow */\r
-                ofs = maxofs;\r
-        }\r
-        if (ofs > maxofs)\r
-            ofs = maxofs;\r
-        /* Translate back to positive offsets relative to &a[0]. */\r
-        k = lastofs;\r
-        lastofs = hint - ofs;\r
-        ofs = hint - k;\r
-    }\r
-    a -= hint;\r
-\r
-    assert(-1 <= lastofs && lastofs < ofs && ofs <= n);\r
-    /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the\r
-     * right of lastofs but no farther right than ofs.  Do a binary\r
-     * search, with invariant a[lastofs-1] < key <= a[ofs].\r
-     */\r
-    ++lastofs;\r
-    while (lastofs < ofs) {\r
-        Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);\r
-\r
-        IFLT(a[m], key)\r
-            lastofs = m+1;              /* a[m] < key */\r
-        else\r
-            ofs = m;                    /* key <= a[m] */\r
-    }\r
-    assert(lastofs == ofs);             /* so a[ofs-1] < key <= a[ofs] */\r
-    return ofs;\r
-\r
-fail:\r
-    return -1;\r
-}\r
-\r
-/*\r
-Exactly like gallop_left(), except that if key already exists in a[0:n],\r
-finds the position immediately to the right of the rightmost equal value.\r
-\r
-The return value is the int k in 0..n such that\r
-\r
-    a[k-1] <= key < a[k]\r
-\r
-or -1 if error.\r
-\r
-The code duplication is massive, but this is enough different given that\r
-we're sticking to "<" comparisons that it's much harder to follow if\r
-written as one routine with yet another "left or right?" flag.\r
-*/\r
-static Py_ssize_t\r
-gallop_right(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare)\r
-{\r
-    Py_ssize_t ofs;\r
-    Py_ssize_t lastofs;\r
-    Py_ssize_t k;\r
-\r
-    assert(key && a && n > 0 && hint >= 0 && hint < n);\r
-\r
-    a += hint;\r
-    lastofs = 0;\r
-    ofs = 1;\r
-    IFLT(key, *a) {\r
-        /* key < a[hint] -- gallop left, until\r
-         * a[hint - ofs] <= key < a[hint - lastofs]\r
-         */\r
-        const Py_ssize_t maxofs = hint + 1;             /* &a[0] is lowest */\r
-        while (ofs < maxofs) {\r
-            IFLT(key, *(a-ofs)) {\r
-                lastofs = ofs;\r
-                ofs = (ofs << 1) + 1;\r
-                if (ofs <= 0)                   /* int overflow */\r
-                    ofs = maxofs;\r
-            }\r
-            else                /* a[hint - ofs] <= key */\r
-                break;\r
-        }\r
-        if (ofs > maxofs)\r
-            ofs = maxofs;\r
-        /* Translate back to positive offsets relative to &a[0]. */\r
-        k = lastofs;\r
-        lastofs = hint - ofs;\r
-        ofs = hint - k;\r
-    }\r
-    else {\r
-        /* a[hint] <= key -- gallop right, until\r
-         * a[hint + lastofs] <= key < a[hint + ofs]\r
-        */\r
-        const Py_ssize_t maxofs = n - hint;             /* &a[n-1] is highest */\r
-        while (ofs < maxofs) {\r
-            IFLT(key, a[ofs])\r
-                break;\r
-            /* a[hint + ofs] <= key */\r
-            lastofs = ofs;\r
-            ofs = (ofs << 1) + 1;\r
-            if (ofs <= 0)               /* int overflow */\r
-                ofs = maxofs;\r
-        }\r
-        if (ofs > maxofs)\r
-            ofs = maxofs;\r
-        /* Translate back to offsets relative to &a[0]. */\r
-        lastofs += hint;\r
-        ofs += hint;\r
-    }\r
-    a -= hint;\r
-\r
-    assert(-1 <= lastofs && lastofs < ofs && ofs <= n);\r
-    /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the\r
-     * right of lastofs but no farther right than ofs.  Do a binary\r
-     * search, with invariant a[lastofs-1] <= key < a[ofs].\r
-     */\r
-    ++lastofs;\r
-    while (lastofs < ofs) {\r
-        Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);\r
-\r
-        IFLT(key, a[m])\r
-            ofs = m;                    /* key < a[m] */\r
-        else\r
-            lastofs = m+1;              /* a[m] <= key */\r
-    }\r
-    assert(lastofs == ofs);             /* so a[ofs-1] <= key < a[ofs] */\r
-    return ofs;\r
-\r
-fail:\r
-    return -1;\r
-}\r
-\r
-/* The maximum number of entries in a MergeState's pending-runs stack.\r
- * This is enough to sort arrays of size up to about\r
- *     32 * phi ** MAX_MERGE_PENDING\r
- * where phi ~= 1.618.  85 is ridiculouslylarge enough, good for an array\r
- * with 2**64 elements.\r
- */\r
-#define MAX_MERGE_PENDING 85\r
-\r
-/* When we get into galloping mode, we stay there until both runs win less\r
- * often than MIN_GALLOP consecutive times.  See listsort.txt for more info.\r
- */\r
-#define MIN_GALLOP 7\r
-\r
-/* Avoid malloc for small temp arrays. */\r
-#define MERGESTATE_TEMP_SIZE 256\r
-\r
-/* One MergeState exists on the stack per invocation of mergesort.  It's just\r
- * a convenient way to pass state around among the helper functions.\r
- */\r
-struct s_slice {\r
-    PyObject **base;\r
-    Py_ssize_t len;\r
-};\r
-\r
-typedef struct s_MergeState {\r
-    /* The user-supplied comparison function. or NULL if none given. */\r
-    PyObject *compare;\r
-\r
-    /* This controls when we get *into* galloping mode.  It's initialized\r
-     * to MIN_GALLOP.  merge_lo and merge_hi tend to nudge it higher for\r
-     * random data, and lower for highly structured data.\r
-     */\r
-    Py_ssize_t min_gallop;\r
-\r
-    /* 'a' is temp storage to help with merges.  It contains room for\r
-     * alloced entries.\r
-     */\r
-    PyObject **a;       /* may point to temparray below */\r
-    Py_ssize_t alloced;\r
-\r
-    /* A stack of n pending runs yet to be merged.  Run #i starts at\r
-     * address base[i] and extends for len[i] elements.  It's always\r
-     * true (so long as the indices are in bounds) that\r
-     *\r
-     *     pending[i].base + pending[i].len == pending[i+1].base\r
-     *\r
-     * so we could cut the storage for this, but it's a minor amount,\r
-     * and keeping all the info explicit simplifies the code.\r
-     */\r
-    int n;\r
-    struct s_slice pending[MAX_MERGE_PENDING];\r
-\r
-    /* 'a' points to this when possible, rather than muck with malloc. */\r
-    PyObject *temparray[MERGESTATE_TEMP_SIZE];\r
-} MergeState;\r
-\r
-/* Conceptually a MergeState's constructor. */\r
-static void\r
-merge_init(MergeState *ms, PyObject *compare)\r
-{\r
-    assert(ms != NULL);\r
-    ms->compare = compare;\r
-    ms->a = ms->temparray;\r
-    ms->alloced = MERGESTATE_TEMP_SIZE;\r
-    ms->n = 0;\r
-    ms->min_gallop = MIN_GALLOP;\r
-}\r
-\r
-/* Free all the temp memory owned by the MergeState.  This must be called\r
- * when you're done with a MergeState, and may be called before then if\r
- * you want to free the temp memory early.\r
- */\r
-static void\r
-merge_freemem(MergeState *ms)\r
-{\r
-    assert(ms != NULL);\r
-    if (ms->a != ms->temparray)\r
-        PyMem_Free(ms->a);\r
-    ms->a = ms->temparray;\r
-    ms->alloced = MERGESTATE_TEMP_SIZE;\r
-}\r
-\r
-/* Ensure enough temp memory for 'need' array slots is available.\r
- * Returns 0 on success and -1 if the memory can't be gotten.\r
- */\r
-static int\r
-merge_getmem(MergeState *ms, Py_ssize_t need)\r
-{\r
-    assert(ms != NULL);\r
-    if (need <= ms->alloced)\r
-        return 0;\r
-    /* Don't realloc!  That can cost cycles to copy the old data, but\r
-     * we don't care what's in the block.\r
-     */\r
-    merge_freemem(ms);\r
-    if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*)) {\r
-        PyErr_NoMemory();\r
-        return -1;\r
-    }\r
-    ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*));\r
-    if (ms->a) {\r
-        ms->alloced = need;\r
-        return 0;\r
-    }\r
-    PyErr_NoMemory();\r
-    merge_freemem(ms);          /* reset to sane state */\r
-    return -1;\r
-}\r
-#define MERGE_GETMEM(MS, NEED) ((NEED) <= (MS)->alloced ? 0 :   \\r
-                                merge_getmem(MS, NEED))\r
-\r
-/* Merge the na elements starting at pa with the nb elements starting at pb\r
- * in a stable way, in-place.  na and nb must be > 0, and pa + na == pb.\r
- * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the\r
- * merge, and should have na <= nb.  See listsort.txt for more info.\r
- * Return 0 if successful, -1 if error.\r
- */\r
-static Py_ssize_t\r
-merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na,\r
-                         PyObject **pb, Py_ssize_t nb)\r
-{\r
-    Py_ssize_t k;\r
-    PyObject *compare;\r
-    PyObject **dest;\r
-    int result = -1;            /* guilty until proved innocent */\r
-    Py_ssize_t min_gallop;\r
-\r
-    assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);\r
-    if (MERGE_GETMEM(ms, na) < 0)\r
-        return -1;\r
-    memcpy(ms->a, pa, na * sizeof(PyObject*));\r
-    dest = pa;\r
-    pa = ms->a;\r
-\r
-    *dest++ = *pb++;\r
-    --nb;\r
-    if (nb == 0)\r
-        goto Succeed;\r
-    if (na == 1)\r
-        goto CopyB;\r
-\r
-    min_gallop = ms->min_gallop;\r
-    compare = ms->compare;\r
-    for (;;) {\r
-        Py_ssize_t acount = 0;          /* # of times A won in a row */\r
-        Py_ssize_t bcount = 0;          /* # of times B won in a row */\r
-\r
-        /* Do the straightforward thing until (if ever) one run\r
-         * appears to win consistently.\r
-         */\r
-        for (;;) {\r
-            assert(na > 1 && nb > 0);\r
-            k = ISLT(*pb, *pa, compare);\r
-            if (k) {\r
-                if (k < 0)\r
-                    goto Fail;\r
-                *dest++ = *pb++;\r
-                ++bcount;\r
-                acount = 0;\r
-                --nb;\r
-                if (nb == 0)\r
-                    goto Succeed;\r
-                if (bcount >= min_gallop)\r
-                    break;\r
-            }\r
-            else {\r
-                *dest++ = *pa++;\r
-                ++acount;\r
-                bcount = 0;\r
-                --na;\r
-                if (na == 1)\r
-                    goto CopyB;\r
-                if (acount >= min_gallop)\r
-                    break;\r
-            }\r
-        }\r
-\r
-        /* One run is winning so consistently that galloping may\r
-         * be a huge win.  So try that, and continue galloping until\r
-         * (if ever) neither run appears to be winning consistently\r
-         * anymore.\r
-         */\r
-        ++min_gallop;\r
-        do {\r
-            assert(na > 1 && nb > 0);\r
-            min_gallop -= min_gallop > 1;\r
-            ms->min_gallop = min_gallop;\r
-            k = gallop_right(*pb, pa, na, 0, compare);\r
-            acount = k;\r
-            if (k) {\r
-                if (k < 0)\r
-                    goto Fail;\r
-                memcpy(dest, pa, k * sizeof(PyObject *));\r
-                dest += k;\r
-                pa += k;\r
-                na -= k;\r
-                if (na == 1)\r
-                    goto CopyB;\r
-                /* na==0 is impossible now if the comparison\r
-                 * function is consistent, but we can't assume\r
-                 * that it is.\r
-                 */\r
-                if (na == 0)\r
-                    goto Succeed;\r
-            }\r
-            *dest++ = *pb++;\r
-            --nb;\r
-            if (nb == 0)\r
-                goto Succeed;\r
-\r
-            k = gallop_left(*pa, pb, nb, 0, compare);\r
-            bcount = k;\r
-            if (k) {\r
-                if (k < 0)\r
-                    goto Fail;\r
-                memmove(dest, pb, k * sizeof(PyObject *));\r
-                dest += k;\r
-                pb += k;\r
-                nb -= k;\r
-                if (nb == 0)\r
-                    goto Succeed;\r
-            }\r
-            *dest++ = *pa++;\r
-            --na;\r
-            if (na == 1)\r
-                goto CopyB;\r
-        } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);\r
-        ++min_gallop;           /* penalize it for leaving galloping mode */\r
-        ms->min_gallop = min_gallop;\r
-    }\r
-Succeed:\r
-    result = 0;\r
-Fail:\r
-    if (na)\r
-        memcpy(dest, pa, na * sizeof(PyObject*));\r
-    return result;\r
-CopyB:\r
-    assert(na == 1 && nb > 0);\r
-    /* The last element of pa belongs at the end of the merge. */\r
-    memmove(dest, pb, nb * sizeof(PyObject *));\r
-    dest[nb] = *pa;\r
-    return 0;\r
-}\r
-\r
-/* Merge the na elements starting at pa with the nb elements starting at pb\r
- * in a stable way, in-place.  na and nb must be > 0, and pa + na == pb.\r
- * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the\r
- * merge, and should have na >= nb.  See listsort.txt for more info.\r
- * Return 0 if successful, -1 if error.\r
- */\r
-static Py_ssize_t\r
-merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t nb)\r
-{\r
-    Py_ssize_t k;\r
-    PyObject *compare;\r
-    PyObject **dest;\r
-    int result = -1;            /* guilty until proved innocent */\r
-    PyObject **basea;\r
-    PyObject **baseb;\r
-    Py_ssize_t min_gallop;\r
-\r
-    assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);\r
-    if (MERGE_GETMEM(ms, nb) < 0)\r
-        return -1;\r
-    dest = pb + nb - 1;\r
-    memcpy(ms->a, pb, nb * sizeof(PyObject*));\r
-    basea = pa;\r
-    baseb = ms->a;\r
-    pb = ms->a + nb - 1;\r
-    pa += na - 1;\r
-\r
-    *dest-- = *pa--;\r
-    --na;\r
-    if (na == 0)\r
-        goto Succeed;\r
-    if (nb == 1)\r
-        goto CopyA;\r
-\r
-    min_gallop = ms->min_gallop;\r
-    compare = ms->compare;\r
-    for (;;) {\r
-        Py_ssize_t acount = 0;          /* # of times A won in a row */\r
-        Py_ssize_t bcount = 0;          /* # of times B won in a row */\r
-\r
-        /* Do the straightforward thing until (if ever) one run\r
-         * appears to win consistently.\r
-         */\r
-        for (;;) {\r
-            assert(na > 0 && nb > 1);\r
-            k = ISLT(*pb, *pa, compare);\r
-            if (k) {\r
-                if (k < 0)\r
-                    goto Fail;\r
-                *dest-- = *pa--;\r
-                ++acount;\r
-                bcount = 0;\r
-                --na;\r
-                if (na == 0)\r
-                    goto Succeed;\r
-                if (acount >= min_gallop)\r
-                    break;\r
-            }\r
-            else {\r
-                *dest-- = *pb--;\r
-                ++bcount;\r
-                acount = 0;\r
-                --nb;\r
-                if (nb == 1)\r
-                    goto CopyA;\r
-                if (bcount >= min_gallop)\r
-                    break;\r
-            }\r
-        }\r
-\r
-        /* One run is winning so consistently that galloping may\r
-         * be a huge win.  So try that, and continue galloping until\r
-         * (if ever) neither run appears to be winning consistently\r
-         * anymore.\r
-         */\r
-        ++min_gallop;\r
-        do {\r
-            assert(na > 0 && nb > 1);\r
-            min_gallop -= min_gallop > 1;\r
-            ms->min_gallop = min_gallop;\r
-            k = gallop_right(*pb, basea, na, na-1, compare);\r
-            if (k < 0)\r
-                goto Fail;\r
-            k = na - k;\r
-            acount = k;\r
-            if (k) {\r
-                dest -= k;\r
-                pa -= k;\r
-                memmove(dest+1, pa+1, k * sizeof(PyObject *));\r
-                na -= k;\r
-                if (na == 0)\r
-                    goto Succeed;\r
-            }\r
-            *dest-- = *pb--;\r
-            --nb;\r
-            if (nb == 1)\r
-                goto CopyA;\r
-\r
-            k = gallop_left(*pa, baseb, nb, nb-1, compare);\r
-            if (k < 0)\r
-                goto Fail;\r
-            k = nb - k;\r
-            bcount = k;\r
-            if (k) {\r
-                dest -= k;\r
-                pb -= k;\r
-                memcpy(dest+1, pb+1, k * sizeof(PyObject *));\r
-                nb -= k;\r
-                if (nb == 1)\r
-                    goto CopyA;\r
-                /* nb==0 is impossible now if the comparison\r
-                 * function is consistent, but we can't assume\r
-                 * that it is.\r
-                 */\r
-                if (nb == 0)\r
-                    goto Succeed;\r
-            }\r
-            *dest-- = *pa--;\r
-            --na;\r
-            if (na == 0)\r
-                goto Succeed;\r
-        } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);\r
-        ++min_gallop;           /* penalize it for leaving galloping mode */\r
-        ms->min_gallop = min_gallop;\r
-    }\r
-Succeed:\r
-    result = 0;\r
-Fail:\r
-    if (nb)\r
-        memcpy(dest-(nb-1), baseb, nb * sizeof(PyObject*));\r
-    return result;\r
-CopyA:\r
-    assert(nb == 1 && na > 0);\r
-    /* The first element of pb belongs at the front of the merge. */\r
-    dest -= na;\r
-    pa -= na;\r
-    memmove(dest+1, pa+1, na * sizeof(PyObject *));\r
-    *dest = *pb;\r
-    return 0;\r
-}\r
-\r
-/* Merge the two runs at stack indices i and i+1.\r
- * Returns 0 on success, -1 on error.\r
- */\r
-static Py_ssize_t\r
-merge_at(MergeState *ms, Py_ssize_t i)\r
-{\r
-    PyObject **pa, **pb;\r
-    Py_ssize_t na, nb;\r
-    Py_ssize_t k;\r
-    PyObject *compare;\r
-\r
-    assert(ms != NULL);\r
-    assert(ms->n >= 2);\r
-    assert(i >= 0);\r
-    assert(i == ms->n - 2 || i == ms->n - 3);\r
-\r
-    pa = ms->pending[i].base;\r
-    na = ms->pending[i].len;\r
-    pb = ms->pending[i+1].base;\r
-    nb = ms->pending[i+1].len;\r
-    assert(na > 0 && nb > 0);\r
-    assert(pa + na == pb);\r
-\r
-    /* Record the length of the combined runs; if i is the 3rd-last\r
-     * run now, also slide over the last run (which isn't involved\r
-     * in this merge).  The current run i+1 goes away in any case.\r
-     */\r
-    ms->pending[i].len = na + nb;\r
-    if (i == ms->n - 3)\r
-        ms->pending[i+1] = ms->pending[i+2];\r
-    --ms->n;\r
-\r
-    /* Where does b start in a?  Elements in a before that can be\r
-     * ignored (already in place).\r
-     */\r
-    compare = ms->compare;\r
-    k = gallop_right(*pb, pa, na, 0, compare);\r
-    if (k < 0)\r
-        return -1;\r
-    pa += k;\r
-    na -= k;\r
-    if (na == 0)\r
-        return 0;\r
-\r
-    /* Where does a end in b?  Elements in b after that can be\r
-     * ignored (already in place).\r
-     */\r
-    nb = gallop_left(pa[na-1], pb, nb, nb-1, compare);\r
-    if (nb <= 0)\r
-        return nb;\r
-\r
-    /* Merge what remains of the runs, using a temp array with\r
-     * min(na, nb) elements.\r
-     */\r
-    if (na <= nb)\r
-        return merge_lo(ms, pa, na, pb, nb);\r
-    else\r
-        return merge_hi(ms, pa, na, pb, nb);\r
-}\r
-\r
-/* Examine the stack of runs waiting to be merged, merging adjacent runs\r
- * until the stack invariants are re-established:\r
- *\r
- * 1. len[-3] > len[-2] + len[-1]\r
- * 2. len[-2] > len[-1]\r
- *\r
- * See listsort.txt for more info.\r
- *\r
- * Returns 0 on success, -1 on error.\r
- */\r
-static int\r
-merge_collapse(MergeState *ms)\r
-{\r
-    struct s_slice *p = ms->pending;\r
-\r
-    assert(ms);\r
-    while (ms->n > 1) {\r
-        Py_ssize_t n = ms->n - 2;\r
-        if ((n > 0 && p[n-1].len <= p[n].len + p[n+1].len) ||\r
-            (n > 1 && p[n-2].len <= p[n-1].len + p[n].len)) {\r
-            if (p[n-1].len < p[n+1].len)\r
-                --n;\r
-            if (merge_at(ms, n) < 0)\r
-                return -1;\r
-        }\r
-        else if (p[n].len <= p[n+1].len) {\r
-                 if (merge_at(ms, n) < 0)\r
-                        return -1;\r
-        }\r
-        else\r
-            break;\r
-    }\r
-    return 0;\r
-}\r
-\r
-/* Regardless of invariants, merge all runs on the stack until only one\r
- * remains.  This is used at the end of the mergesort.\r
- *\r
- * Returns 0 on success, -1 on error.\r
- */\r
-static int\r
-merge_force_collapse(MergeState *ms)\r
-{\r
-    struct s_slice *p = ms->pending;\r
-\r
-    assert(ms);\r
-    while (ms->n > 1) {\r
-        Py_ssize_t n = ms->n - 2;\r
-        if (n > 0 && p[n-1].len < p[n+1].len)\r
-            --n;\r
-        if (merge_at(ms, n) < 0)\r
-            return -1;\r
-    }\r
-    return 0;\r
-}\r
-\r
-/* Compute a good value for the minimum run length; natural runs shorter\r
- * than this are boosted artificially via binary insertion.\r
- *\r
- * If n < 64, return n (it's too small to bother with fancy stuff).\r
- * Else if n is an exact power of 2, return 32.\r
- * Else return an int k, 32 <= k <= 64, such that n/k is close to, but\r
- * strictly less than, an exact power of 2.\r
- *\r
- * See listsort.txt for more info.\r
- */\r
-static Py_ssize_t\r
-merge_compute_minrun(Py_ssize_t n)\r
-{\r
-    Py_ssize_t r = 0;           /* becomes 1 if any 1 bits are shifted off */\r
-\r
-    assert(n >= 0);\r
-    while (n >= 64) {\r
-        r |= n & 1;\r
-        n >>= 1;\r
-    }\r
-    return n + r;\r
-}\r
-\r
-/* Special wrapper to support stable sorting using the decorate-sort-undecorate\r
-   pattern.  Holds a key which is used for comparisons and the original record\r
-   which is returned during the undecorate phase.  By exposing only the key\r
-   during comparisons, the underlying sort stability characteristics are left\r
-   unchanged.  Also, if a custom comparison function is used, it will only see\r
-   the key instead of a full record. */\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *key;\r
-    PyObject *value;\r
-} sortwrapperobject;\r
-\r
-PyDoc_STRVAR(sortwrapper_doc, "Object wrapper with a custom sort key.");\r
-static PyObject *\r
-sortwrapper_richcompare(sortwrapperobject *, sortwrapperobject *, int);\r
-static void\r
-sortwrapper_dealloc(sortwrapperobject *);\r
-\r
-static PyTypeObject sortwrapper_type = {\r
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
-    "sortwrapper",                              /* tp_name */\r
-    sizeof(sortwrapperobject),                  /* tp_basicsize */\r
-    0,                                          /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)sortwrapper_dealloc,            /* tp_dealloc */\r
-    0,                                          /* tp_print */\r
-    0,                                          /* tp_getattr */\r
-    0,                                          /* tp_setattr */\r
-    0,                                          /* tp_compare */\r
-    0,                                          /* tp_repr */\r
-    0,                                          /* tp_as_number */\r
-    0,                                          /* tp_as_sequence */\r
-    0,                                          /* tp_as_mapping */\r
-    0,                                          /* tp_hash */\r
-    0,                                          /* tp_call */\r
-    0,                                          /* tp_str */\r
-    PyObject_GenericGetAttr,                    /* tp_getattro */\r
-    0,                                          /* tp_setattro */\r
-    0,                                          /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT |\r
-    Py_TPFLAGS_HAVE_RICHCOMPARE,                /* tp_flags */\r
-    sortwrapper_doc,                            /* tp_doc */\r
-    0,                                          /* tp_traverse */\r
-    0,                                          /* tp_clear */\r
-    (richcmpfunc)sortwrapper_richcompare,       /* tp_richcompare */\r
-};\r
-\r
-\r
-static PyObject *\r
-sortwrapper_richcompare(sortwrapperobject *a, sortwrapperobject *b, int op)\r
-{\r
-    if (!PyObject_TypeCheck(b, &sortwrapper_type)) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-            "expected a sortwrapperobject");\r
-        return NULL;\r
-    }\r
-    return PyObject_RichCompare(a->key, b->key, op);\r
-}\r
-\r
-static void\r
-sortwrapper_dealloc(sortwrapperobject *so)\r
-{\r
-    Py_XDECREF(so->key);\r
-    Py_XDECREF(so->value);\r
-    PyObject_Del(so);\r
-}\r
-\r
-/* Returns a new reference to a sortwrapper.\r
-   Consumes the references to the two underlying objects. */\r
-\r
-static PyObject *\r
-build_sortwrapper(PyObject *key, PyObject *value)\r
-{\r
-    sortwrapperobject *so;\r
-\r
-    so = PyObject_New(sortwrapperobject, &sortwrapper_type);\r
-    if (so == NULL)\r
-        return NULL;\r
-    so->key = key;\r
-    so->value = value;\r
-    return (PyObject *)so;\r
-}\r
-\r
-/* Returns a new reference to the value underlying the wrapper. */\r
-static PyObject *\r
-sortwrapper_getvalue(PyObject *so)\r
-{\r
-    PyObject *value;\r
-\r
-    if (!PyObject_TypeCheck(so, &sortwrapper_type)) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-            "expected a sortwrapperobject");\r
-        return NULL;\r
-    }\r
-    value = ((sortwrapperobject *)so)->value;\r
-    Py_INCREF(value);\r
-    return value;\r
-}\r
-\r
-/* Wrapper for user specified cmp functions in combination with a\r
-   specified key function.  Makes sure the cmp function is presented\r
-   with the actual key instead of the sortwrapper */\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *func;\r
-} cmpwrapperobject;\r
-\r
-static void\r
-cmpwrapper_dealloc(cmpwrapperobject *co)\r
-{\r
-    Py_XDECREF(co->func);\r
-    PyObject_Del(co);\r
-}\r
-\r
-static PyObject *\r
-cmpwrapper_call(cmpwrapperobject *co, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *x, *y, *xx, *yy;\r
-\r
-    if (!PyArg_UnpackTuple(args, "", 2, 2, &x, &y))\r
-        return NULL;\r
-    if (!PyObject_TypeCheck(x, &sortwrapper_type) ||\r
-        !PyObject_TypeCheck(y, &sortwrapper_type)) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-            "expected a sortwrapperobject");\r
-        return NULL;\r
-    }\r
-    xx = ((sortwrapperobject *)x)->key;\r
-    yy = ((sortwrapperobject *)y)->key;\r
-    return PyObject_CallFunctionObjArgs(co->func, xx, yy, NULL);\r
-}\r
-\r
-PyDoc_STRVAR(cmpwrapper_doc, "cmp() wrapper for sort with custom keys.");\r
-\r
-static PyTypeObject cmpwrapper_type = {\r
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
-    "cmpwrapper",                               /* tp_name */\r
-    sizeof(cmpwrapperobject),                   /* tp_basicsize */\r
-    0,                                          /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)cmpwrapper_dealloc,             /* tp_dealloc */\r
-    0,                                          /* tp_print */\r
-    0,                                          /* tp_getattr */\r
-    0,                                          /* tp_setattr */\r
-    0,                                          /* tp_compare */\r
-    0,                                          /* tp_repr */\r
-    0,                                          /* tp_as_number */\r
-    0,                                          /* tp_as_sequence */\r
-    0,                                          /* tp_as_mapping */\r
-    0,                                          /* tp_hash */\r
-    (ternaryfunc)cmpwrapper_call,               /* tp_call */\r
-    0,                                          /* tp_str */\r
-    PyObject_GenericGetAttr,                    /* tp_getattro */\r
-    0,                                          /* tp_setattro */\r
-    0,                                          /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT,                         /* tp_flags */\r
-    cmpwrapper_doc,                             /* tp_doc */\r
-};\r
-\r
-static PyObject *\r
-build_cmpwrapper(PyObject *cmpfunc)\r
-{\r
-    cmpwrapperobject *co;\r
-\r
-    co = PyObject_New(cmpwrapperobject, &cmpwrapper_type);\r
-    if (co == NULL)\r
-        return NULL;\r
-    Py_INCREF(cmpfunc);\r
-    co->func = cmpfunc;\r
-    return (PyObject *)co;\r
-}\r
-\r
-/* An adaptive, stable, natural mergesort.  See listsort.txt.\r
- * Returns Py_None on success, NULL on error.  Even in case of error, the\r
- * list will be some permutation of its input state (nothing is lost or\r
- * duplicated).\r
- */\r
-static PyObject *\r
-listsort(PyListObject *self, PyObject *args, PyObject *kwds)\r
-{\r
-    MergeState ms;\r
-    PyObject **lo, **hi;\r
-    Py_ssize_t nremaining;\r
-    Py_ssize_t minrun;\r
-    Py_ssize_t saved_ob_size, saved_allocated;\r
-    PyObject **saved_ob_item;\r
-    PyObject **final_ob_item;\r
-    PyObject *compare = NULL;\r
-    PyObject *result = NULL;            /* guilty until proved innocent */\r
-    int reverse = 0;\r
-    PyObject *keyfunc = NULL;\r
-    Py_ssize_t i;\r
-    PyObject *key, *value, *kvpair;\r
-    static char *kwlist[] = {"cmp", "key", "reverse", 0};\r
-\r
-    assert(self != NULL);\r
-    assert (PyList_Check(self));\r
-    if (args != NULL) {\r
-        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi:sort",\r
-            kwlist, &compare, &keyfunc, &reverse))\r
-            return NULL;\r
-    }\r
-    if (compare == Py_None)\r
-        compare = NULL;\r
-    if (compare != NULL &&\r
-        PyErr_WarnPy3k("the cmp argument is not supported in 3.x", 1) < 0)\r
-        return NULL;\r
-    if (keyfunc == Py_None)\r
-        keyfunc = NULL;\r
-    if (compare != NULL && keyfunc != NULL) {\r
-        compare = build_cmpwrapper(compare);\r
-        if (compare == NULL)\r
-            return NULL;\r
-    } else\r
-        Py_XINCREF(compare);\r
-\r
-    /* The list is temporarily made empty, so that mutations performed\r
-     * by comparison functions can't affect the slice of memory we're\r
-     * sorting (allowing mutations during sorting is a core-dump\r
-     * factory, since ob_item may change).\r
-     */\r
-    saved_ob_size = Py_SIZE(self);\r
-    saved_ob_item = self->ob_item;\r
-    saved_allocated = self->allocated;\r
-    Py_SIZE(self) = 0;\r
-    self->ob_item = NULL;\r
-    self->allocated = -1; /* any operation will reset it to >= 0 */\r
-\r
-    if (keyfunc != NULL) {\r
-        for (i=0 ; i < saved_ob_size ; i++) {\r
-            value = saved_ob_item[i];\r
-            key = PyObject_CallFunctionObjArgs(keyfunc, value,\r
-                                               NULL);\r
-            if (key == NULL) {\r
-                for (i=i-1 ; i>=0 ; i--) {\r
-                    kvpair = saved_ob_item[i];\r
-                    value = sortwrapper_getvalue(kvpair);\r
-                    saved_ob_item[i] = value;\r
-                    Py_DECREF(kvpair);\r
-                }\r
-                goto dsu_fail;\r
-            }\r
-            kvpair = build_sortwrapper(key, value);\r
-            if (kvpair == NULL)\r
-                goto dsu_fail;\r
-            saved_ob_item[i] = kvpair;\r
-        }\r
-    }\r
-\r
-    /* Reverse sort stability achieved by initially reversing the list,\r
-    applying a stable forward sort, then reversing the final result. */\r
-    if (reverse && saved_ob_size > 1)\r
-        reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);\r
-\r
-    merge_init(&ms, compare);\r
-\r
-    nremaining = saved_ob_size;\r
-    if (nremaining < 2)\r
-        goto succeed;\r
-\r
-    /* March over the array once, left to right, finding natural runs,\r
-     * and extending short natural runs to minrun elements.\r
-     */\r
-    lo = saved_ob_item;\r
-    hi = lo + nremaining;\r
-    minrun = merge_compute_minrun(nremaining);\r
-    do {\r
-        int descending;\r
-        Py_ssize_t n;\r
-\r
-        /* Identify next run. */\r
-        n = count_run(lo, hi, compare, &descending);\r
-        if (n < 0)\r
-            goto fail;\r
-        if (descending)\r
-            reverse_slice(lo, lo + n);\r
-        /* If short, extend to min(minrun, nremaining). */\r
-        if (n < minrun) {\r
-            const Py_ssize_t force = nremaining <= minrun ?\r
-                              nremaining : minrun;\r
-            if (binarysort(lo, lo + force, lo + n, compare) < 0)\r
-                goto fail;\r
-            n = force;\r
-        }\r
-        /* Push run onto pending-runs stack, and maybe merge. */\r
-        assert(ms.n < MAX_MERGE_PENDING);\r
-        ms.pending[ms.n].base = lo;\r
-        ms.pending[ms.n].len = n;\r
-        ++ms.n;\r
-        if (merge_collapse(&ms) < 0)\r
-            goto fail;\r
-        /* Advance to find next run. */\r
-        lo += n;\r
-        nremaining -= n;\r
-    } while (nremaining);\r
-    assert(lo == hi);\r
-\r
-    if (merge_force_collapse(&ms) < 0)\r
-        goto fail;\r
-    assert(ms.n == 1);\r
-    assert(ms.pending[0].base == saved_ob_item);\r
-    assert(ms.pending[0].len == saved_ob_size);\r
-\r
-succeed:\r
-    result = Py_None;\r
-fail:\r
-    if (keyfunc != NULL) {\r
-        for (i=0 ; i < saved_ob_size ; i++) {\r
-            kvpair = saved_ob_item[i];\r
-            value = sortwrapper_getvalue(kvpair);\r
-            saved_ob_item[i] = value;\r
-            Py_DECREF(kvpair);\r
-        }\r
-    }\r
-\r
-    if (self->allocated != -1 && result != NULL) {\r
-        /* The user mucked with the list during the sort,\r
-         * and we don't already have another error to report.\r
-         */\r
-        PyErr_SetString(PyExc_ValueError, "list modified during sort");\r
-        result = NULL;\r
-    }\r
-\r
-    if (reverse && saved_ob_size > 1)\r
-        reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);\r
-\r
-    merge_freemem(&ms);\r
-\r
-dsu_fail:\r
-    final_ob_item = self->ob_item;\r
-    i = Py_SIZE(self);\r
-    Py_SIZE(self) = saved_ob_size;\r
-    self->ob_item = saved_ob_item;\r
-    self->allocated = saved_allocated;\r
-    if (final_ob_item != NULL) {\r
-        /* we cannot use list_clear() for this because it does not\r
-           guarantee that the list is really empty when it returns */\r
-        while (--i >= 0) {\r
-            Py_XDECREF(final_ob_item[i]);\r
-        }\r
-        PyMem_FREE(final_ob_item);\r
-    }\r
-    Py_XDECREF(compare);\r
-    Py_XINCREF(result);\r
-    return result;\r
-}\r
-#undef IFLT\r
-#undef ISLT\r
-\r
-int\r
-PyList_Sort(PyObject *v)\r
-{\r
-    if (v == NULL || !PyList_Check(v)) {\r
-        PyErr_BadInternalCall();\r
-        return -1;\r
-    }\r
-    v = listsort((PyListObject *)v, (PyObject *)NULL, (PyObject *)NULL);\r
-    if (v == NULL)\r
-        return -1;\r
-    Py_DECREF(v);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-listreverse(PyListObject *self)\r
-{\r
-    if (Py_SIZE(self) > 1)\r
-        reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));\r
-    Py_RETURN_NONE;\r
-}\r
-\r
-int\r
-PyList_Reverse(PyObject *v)\r
-{\r
-    PyListObject *self = (PyListObject *)v;\r
-\r
-    if (v == NULL || !PyList_Check(v)) {\r
-        PyErr_BadInternalCall();\r
-        return -1;\r
-    }\r
-    if (Py_SIZE(self) > 1)\r
-        reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));\r
-    return 0;\r
-}\r
-\r
-PyObject *\r
-PyList_AsTuple(PyObject *v)\r
-{\r
-    PyObject *w;\r
-    PyObject **p, **q;\r
-    Py_ssize_t n;\r
-    if (v == NULL || !PyList_Check(v)) {\r
-        PyErr_BadInternalCall();\r
-        return NULL;\r
-    }\r
-    n = Py_SIZE(v);\r
-    w = PyTuple_New(n);\r
-    if (w == NULL)\r
-        return NULL;\r
-    p = ((PyTupleObject *)w)->ob_item;\r
-    q = ((PyListObject *)v)->ob_item;\r
-    while (--n >= 0) {\r
-        Py_INCREF(*q);\r
-        *p = *q;\r
-        p++;\r
-        q++;\r
-    }\r
-    return w;\r
-}\r
-\r
-static PyObject *\r
-listindex(PyListObject *self, PyObject *args)\r
-{\r
-    Py_ssize_t i, start=0, stop=Py_SIZE(self);\r
-    PyObject *v, *format_tuple, *err_string;\r
-    static PyObject *err_format = NULL;\r
-\r
-    if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,\r
-                                _PyEval_SliceIndex, &start,\r
-                                _PyEval_SliceIndex, &stop))\r
-        return NULL;\r
-    if (start < 0) {\r
-        start += Py_SIZE(self);\r
-        if (start < 0)\r
-            start = 0;\r
-    }\r
-    if (stop < 0) {\r
-        stop += Py_SIZE(self);\r
-        if (stop < 0)\r
-            stop = 0;\r
-    }\r
-    for (i = start; i < stop && i < Py_SIZE(self); i++) {\r
-        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);\r
-        if (cmp > 0)\r
-            return PyInt_FromSsize_t(i);\r
-        else if (cmp < 0)\r
-            return NULL;\r
-    }\r
-    if (err_format == NULL) {\r
-        err_format = PyString_FromString("%r is not in list");\r
-        if (err_format == NULL)\r
-            return NULL;\r
-    }\r
-    format_tuple = PyTuple_Pack(1, v);\r
-    if (format_tuple == NULL)\r
-        return NULL;\r
-    err_string = PyString_Format(err_format, format_tuple);\r
-    Py_DECREF(format_tuple);\r
-    if (err_string == NULL)\r
-        return NULL;\r
-    PyErr_SetObject(PyExc_ValueError, err_string);\r
-    Py_DECREF(err_string);\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-listcount(PyListObject *self, PyObject *v)\r
-{\r
-    Py_ssize_t count = 0;\r
-    Py_ssize_t i;\r
-\r
-    for (i = 0; i < Py_SIZE(self); i++) {\r
-        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);\r
-        if (cmp > 0)\r
-            count++;\r
-        else if (cmp < 0)\r
-            return NULL;\r
-    }\r
-    return PyInt_FromSsize_t(count);\r
-}\r
-\r
-static PyObject *\r
-listremove(PyListObject *self, PyObject *v)\r
-{\r
-    Py_ssize_t i;\r
-\r
-    for (i = 0; i < Py_SIZE(self); i++) {\r
-        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);\r
-        if (cmp > 0) {\r
-            if (list_ass_slice(self, i, i+1,\r
-                               (PyObject *)NULL) == 0)\r
-                Py_RETURN_NONE;\r
-            return NULL;\r
-        }\r
-        else if (cmp < 0)\r
-            return NULL;\r
-    }\r
-    PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list");\r
-    return NULL;\r
-}\r
-\r
-static int\r
-list_traverse(PyListObject *o, visitproc visit, void *arg)\r
-{\r
-    Py_ssize_t i;\r
-\r
-    for (i = Py_SIZE(o); --i >= 0; )\r
-        Py_VISIT(o->ob_item[i]);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-list_richcompare(PyObject *v, PyObject *w, int op)\r
-{\r
-    PyListObject *vl, *wl;\r
-    Py_ssize_t i;\r
-\r
-    if (!PyList_Check(v) || !PyList_Check(w)) {\r
-        Py_INCREF(Py_NotImplemented);\r
-        return Py_NotImplemented;\r
-    }\r
-\r
-    vl = (PyListObject *)v;\r
-    wl = (PyListObject *)w;\r
-\r
-    if (Py_SIZE(vl) != Py_SIZE(wl) && (op == Py_EQ || op == Py_NE)) {\r
-        /* Shortcut: if the lengths differ, the lists differ */\r
-        PyObject *res;\r
-        if (op == Py_EQ)\r
-            res = Py_False;\r
-        else\r
-            res = Py_True;\r
-        Py_INCREF(res);\r
-        return res;\r
-    }\r
-\r
-    /* Search for the first index where items are different */\r
-    for (i = 0; i < Py_SIZE(vl) && i < Py_SIZE(wl); i++) {\r
-        int k = PyObject_RichCompareBool(vl->ob_item[i],\r
-                                         wl->ob_item[i], Py_EQ);\r
-        if (k < 0)\r
-            return NULL;\r
-        if (!k)\r
-            break;\r
-    }\r
-\r
-    if (i >= Py_SIZE(vl) || i >= Py_SIZE(wl)) {\r
-        /* No more items to compare -- compare sizes */\r
-        Py_ssize_t vs = Py_SIZE(vl);\r
-        Py_ssize_t ws = Py_SIZE(wl);\r
-        int cmp;\r
-        PyObject *res;\r
-        switch (op) {\r
-        case Py_LT: cmp = vs <  ws; break;\r
-        case Py_LE: cmp = vs <= ws; break;\r
-        case Py_EQ: cmp = vs == ws; break;\r
-        case Py_NE: cmp = vs != ws; break;\r
-        case Py_GT: cmp = vs >  ws; break;\r
-        case Py_GE: cmp = vs >= ws; break;\r
-        default: return NULL; /* cannot happen */\r
-        }\r
-        if (cmp)\r
-            res = Py_True;\r
-        else\r
-            res = Py_False;\r
-        Py_INCREF(res);\r
-        return res;\r
-    }\r
-\r
-    /* We have an item that differs -- shortcuts for EQ/NE */\r
-    if (op == Py_EQ) {\r
-        Py_INCREF(Py_False);\r
-        return Py_False;\r
-    }\r
-    if (op == Py_NE) {\r
-        Py_INCREF(Py_True);\r
-        return Py_True;\r
-    }\r
-\r
-    /* Compare the final item again using the proper operator */\r
-    return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);\r
-}\r
-\r
-static int\r
-list_init(PyListObject *self, PyObject *args, PyObject *kw)\r
-{\r
-    PyObject *arg = NULL;\r
-    static char *kwlist[] = {"sequence", 0};\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:list", kwlist, &arg))\r
-        return -1;\r
-\r
-    /* Verify list invariants established by PyType_GenericAlloc() */\r
-    assert(0 <= Py_SIZE(self));\r
-    assert(Py_SIZE(self) <= self->allocated || self->allocated == -1);\r
-    assert(self->ob_item != NULL ||\r
-           self->allocated == 0 || self->allocated == -1);\r
-\r
-    /* Empty previous contents */\r
-    if (self->ob_item != NULL) {\r
-        (void)list_clear(self);\r
-    }\r
-    if (arg != NULL) {\r
-        PyObject *rv = listextend(self, arg);\r
-        if (rv == NULL)\r
-            return -1;\r
-        Py_DECREF(rv);\r
-    }\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-list_sizeof(PyListObject *self)\r
-{\r
-    Py_ssize_t res;\r
-\r
-    res = sizeof(PyListObject) + self->allocated * sizeof(void*);\r
-    return PyInt_FromSsize_t(res);\r
-}\r
-\r
-static PyObject *list_iter(PyObject *seq);\r
-static PyObject *list_reversed(PyListObject* seq, PyObject* unused);\r
-\r
-PyDoc_STRVAR(getitem_doc,\r
-"x.__getitem__(y) <==> x[y]");\r
-PyDoc_STRVAR(reversed_doc,\r
-"L.__reversed__() -- return a reverse iterator over the list");\r
-PyDoc_STRVAR(sizeof_doc,\r
-"L.__sizeof__() -- size of L in memory, in bytes");\r
-PyDoc_STRVAR(append_doc,\r
-"L.append(object) -- append object to end");\r
-PyDoc_STRVAR(extend_doc,\r
-"L.extend(iterable) -- extend list by appending elements from the iterable");\r
-PyDoc_STRVAR(insert_doc,\r
-"L.insert(index, object) -- insert object before index");\r
-PyDoc_STRVAR(pop_doc,\r
-"L.pop([index]) -> item -- remove and return item at index (default last).\n"\r
-"Raises IndexError if list is empty or index is out of range.");\r
-PyDoc_STRVAR(remove_doc,\r
-"L.remove(value) -- remove first occurrence of value.\n"\r
-"Raises ValueError if the value is not present.");\r
-PyDoc_STRVAR(index_doc,\r
-"L.index(value, [start, [stop]]) -> integer -- return first index of value.\n"\r
-"Raises ValueError if the value is not present.");\r
-PyDoc_STRVAR(count_doc,\r
-"L.count(value) -> integer -- return number of occurrences of value");\r
-PyDoc_STRVAR(reverse_doc,\r
-"L.reverse() -- reverse *IN PLACE*");\r
-PyDoc_STRVAR(sort_doc,\r
-"L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;\n\\r
-cmp(x, y) -> -1, 0, 1");\r
-\r
-static PyObject *list_subscript(PyListObject*, PyObject*);\r
-\r
-static PyMethodDef list_methods[] = {\r
-    {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, getitem_doc},\r
-    {"__reversed__",(PyCFunction)list_reversed, METH_NOARGS, reversed_doc},\r
-    {"__sizeof__",  (PyCFunction)list_sizeof, METH_NOARGS, sizeof_doc},\r
-    {"append",          (PyCFunction)listappend,  METH_O, append_doc},\r
-    {"insert",          (PyCFunction)listinsert,  METH_VARARGS, insert_doc},\r
-    {"extend",      (PyCFunction)listextend,  METH_O, extend_doc},\r
-    {"pop",             (PyCFunction)listpop,     METH_VARARGS, pop_doc},\r
-    {"remove",          (PyCFunction)listremove,  METH_O, remove_doc},\r
-    {"index",           (PyCFunction)listindex,   METH_VARARGS, index_doc},\r
-    {"count",           (PyCFunction)listcount,   METH_O, count_doc},\r
-    {"reverse",         (PyCFunction)listreverse, METH_NOARGS, reverse_doc},\r
-    {"sort",            (PyCFunction)listsort,    METH_VARARGS | METH_KEYWORDS, sort_doc},\r
-    {NULL,              NULL}           /* sentinel */\r
-};\r
-\r
-static PySequenceMethods list_as_sequence = {\r
-    (lenfunc)list_length,                       /* sq_length */\r
-    (binaryfunc)list_concat,                    /* sq_concat */\r
-    (ssizeargfunc)list_repeat,                  /* sq_repeat */\r
-    (ssizeargfunc)list_item,                    /* sq_item */\r
-    (ssizessizeargfunc)list_slice,              /* sq_slice */\r
-    (ssizeobjargproc)list_ass_item,             /* sq_ass_item */\r
-    (ssizessizeobjargproc)list_ass_slice,       /* sq_ass_slice */\r
-    (objobjproc)list_contains,                  /* sq_contains */\r
-    (binaryfunc)list_inplace_concat,            /* sq_inplace_concat */\r
-    (ssizeargfunc)list_inplace_repeat,          /* sq_inplace_repeat */\r
-};\r
-\r
-PyDoc_STRVAR(list_doc,\r
-"list() -> new empty list\n"\r
-"list(iterable) -> new list initialized from iterable's items");\r
-\r
-\r
-static PyObject *\r
-list_subscript(PyListObject* self, PyObject* item)\r
-{\r
-    if (PyIndex_Check(item)) {\r
-        Py_ssize_t i;\r
-        i = PyNumber_AsSsize_t(item, PyExc_IndexError);\r
-        if (i == -1 && PyErr_Occurred())\r
-            return NULL;\r
-        if (i < 0)\r
-            i += PyList_GET_SIZE(self);\r
-        return list_item(self, i);\r
-    }\r
-    else if (PySlice_Check(item)) {\r
-        Py_ssize_t start, stop, step, slicelength, cur, i;\r
-        PyObject* result;\r
-        PyObject* it;\r
-        PyObject **src, **dest;\r
-\r
-        if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self),\r
-                         &start, &stop, &step, &slicelength) < 0) {\r
-            return NULL;\r
-        }\r
-\r
-        if (slicelength <= 0) {\r
-            return PyList_New(0);\r
-        }\r
-        else if (step == 1) {\r
-            return list_slice(self, start, stop);\r
-        }\r
-        else {\r
-            result = PyList_New(slicelength);\r
-            if (!result) return NULL;\r
-\r
-            src = self->ob_item;\r
-            dest = ((PyListObject *)result)->ob_item;\r
-            for (cur = start, i = 0; i < slicelength;\r
-                 cur += step, i++) {\r
-                it = src[cur];\r
-                Py_INCREF(it);\r
-                dest[i] = it;\r
-            }\r
-\r
-            return result;\r
-        }\r
-    }\r
-    else {\r
-        PyErr_Format(PyExc_TypeError,\r
-                     "list indices must be integers, not %.200s",\r
-                     item->ob_type->tp_name);\r
-        return NULL;\r
-    }\r
-}\r
-\r
-static int\r
-list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)\r
-{\r
-    if (PyIndex_Check(item)) {\r
-        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);\r
-        if (i == -1 && PyErr_Occurred())\r
-            return -1;\r
-        if (i < 0)\r
-            i += PyList_GET_SIZE(self);\r
-        return list_ass_item(self, i, value);\r
-    }\r
-    else if (PySlice_Check(item)) {\r
-        Py_ssize_t start, stop, step, slicelength;\r
-\r
-        if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self),\r
-                         &start, &stop, &step, &slicelength) < 0) {\r
-            return -1;\r
-        }\r
-\r
-        if (step == 1)\r
-            return list_ass_slice(self, start, stop, value);\r
-\r
-        /* Make sure s[5:2] = [..] inserts at the right place:\r
-           before 5, not before 2. */\r
-        if ((step < 0 && start < stop) ||\r
-            (step > 0 && start > stop))\r
-            stop = start;\r
-\r
-        if (value == NULL) {\r
-            /* delete slice */\r
-            PyObject **garbage;\r
-            size_t cur;\r
-            Py_ssize_t i;\r
-\r
-            if (slicelength <= 0)\r
-                return 0;\r
-\r
-            if (step < 0) {\r
-                stop = start + 1;\r
-                start = stop + step*(slicelength - 1) - 1;\r
-                step = -step;\r
-            }\r
-\r
-            assert((size_t)slicelength <=\r
-                   PY_SIZE_MAX / sizeof(PyObject*));\r
-\r
-            garbage = (PyObject**)\r
-                PyMem_MALLOC(slicelength*sizeof(PyObject*));\r
-            if (!garbage) {\r
-                PyErr_NoMemory();\r
-                return -1;\r
-            }\r
-\r
-            /* drawing pictures might help understand these for\r
-               loops. Basically, we memmove the parts of the\r
-               list that are *not* part of the slice: step-1\r
-               items for each item that is part of the slice,\r
-               and then tail end of the list that was not\r
-               covered by the slice */\r
-            for (cur = start, i = 0;\r
-                 cur < (size_t)stop;\r
-                 cur += step, i++) {\r
-                Py_ssize_t lim = step - 1;\r
-\r
-                garbage[i] = PyList_GET_ITEM(self, cur);\r
-\r
-                if (cur + step >= (size_t)Py_SIZE(self)) {\r
-                    lim = Py_SIZE(self) - cur - 1;\r
-                }\r
-\r
-                memmove(self->ob_item + cur - i,\r
-                    self->ob_item + cur + 1,\r
-                    lim * sizeof(PyObject *));\r
-            }\r
-            cur = start + slicelength*step;\r
-            if (cur < (size_t)Py_SIZE(self)) {\r
-                memmove(self->ob_item + cur - slicelength,\r
-                    self->ob_item + cur,\r
-                    (Py_SIZE(self) - cur) *\r
-                     sizeof(PyObject *));\r
-            }\r
-\r
-            Py_SIZE(self) -= slicelength;\r
-            list_resize(self, Py_SIZE(self));\r
-\r
-            for (i = 0; i < slicelength; i++) {\r
-                Py_DECREF(garbage[i]);\r
-            }\r
-            PyMem_FREE(garbage);\r
-\r
-            return 0;\r
-        }\r
-        else {\r
-            /* assign slice */\r
-            PyObject *ins, *seq;\r
-            PyObject **garbage, **seqitems, **selfitems;\r
-            Py_ssize_t cur, i;\r
-\r
-            /* protect against a[::-1] = a */\r
-            if (self == (PyListObject*)value) {\r
-                seq = list_slice((PyListObject*)value, 0,\r
-                                   PyList_GET_SIZE(value));\r
-            }\r
-            else {\r
-                seq = PySequence_Fast(value,\r
-                                      "must assign iterable "\r
-                                      "to extended slice");\r
-            }\r
-            if (!seq)\r
-                return -1;\r
-\r
-            if (PySequence_Fast_GET_SIZE(seq) != slicelength) {\r
-                PyErr_Format(PyExc_ValueError,\r
-                    "attempt to assign sequence of "\r
-                    "size %zd to extended slice of "\r
-                    "size %zd",\r
-                         PySequence_Fast_GET_SIZE(seq),\r
-                         slicelength);\r
-                Py_DECREF(seq);\r
-                return -1;\r
-            }\r
-\r
-            if (!slicelength) {\r
-                Py_DECREF(seq);\r
-                return 0;\r
-            }\r
-\r
-            garbage = (PyObject**)\r
-                PyMem_MALLOC(slicelength*sizeof(PyObject*));\r
-            if (!garbage) {\r
-                Py_DECREF(seq);\r
-                PyErr_NoMemory();\r
-                return -1;\r
-            }\r
-\r
-            selfitems = self->ob_item;\r
-            seqitems = PySequence_Fast_ITEMS(seq);\r
-            for (cur = start, i = 0; i < slicelength;\r
-                 cur += step, i++) {\r
-                garbage[i] = selfitems[cur];\r
-                ins = seqitems[i];\r
-                Py_INCREF(ins);\r
-                selfitems[cur] = ins;\r
-            }\r
-\r
-            for (i = 0; i < slicelength; i++) {\r
-                Py_DECREF(garbage[i]);\r
-            }\r
-\r
-            PyMem_FREE(garbage);\r
-            Py_DECREF(seq);\r
-\r
-            return 0;\r
-        }\r
-    }\r
-    else {\r
-        PyErr_Format(PyExc_TypeError,\r
-                     "list indices must be integers, not %.200s",\r
-                     item->ob_type->tp_name);\r
-        return -1;\r
-    }\r
-}\r
-\r
-static PyMappingMethods list_as_mapping = {\r
-    (lenfunc)list_length,\r
-    (binaryfunc)list_subscript,\r
-    (objobjargproc)list_ass_subscript\r
-};\r
-\r
-PyTypeObject PyList_Type = {\r
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
-    "list",\r
-    sizeof(PyListObject),\r
-    0,\r
-    (destructor)list_dealloc,                   /* tp_dealloc */\r
-    (printfunc)list_print,                      /* tp_print */\r
-    0,                                          /* tp_getattr */\r
-    0,                                          /* tp_setattr */\r
-    0,                                          /* tp_compare */\r
-    (reprfunc)list_repr,                        /* tp_repr */\r
-    0,                                          /* tp_as_number */\r
-    &list_as_sequence,                          /* tp_as_sequence */\r
-    &list_as_mapping,                           /* tp_as_mapping */\r
-    (hashfunc)PyObject_HashNotImplemented,      /* tp_hash */\r
-    0,                                          /* tp_call */\r
-    0,                                          /* tp_str */\r
-    PyObject_GenericGetAttr,                    /* tp_getattro */\r
-    0,                                          /* tp_setattro */\r
-    0,                                          /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS,         /* tp_flags */\r
-    list_doc,                                   /* tp_doc */\r
-    (traverseproc)list_traverse,                /* tp_traverse */\r
-    (inquiry)list_clear,                        /* tp_clear */\r
-    list_richcompare,                           /* tp_richcompare */\r
-    0,                                          /* tp_weaklistoffset */\r
-    list_iter,                                  /* tp_iter */\r
-    0,                                          /* tp_iternext */\r
-    list_methods,                               /* tp_methods */\r
-    0,                                          /* tp_members */\r
-    0,                                          /* tp_getset */\r
-    0,                                          /* tp_base */\r
-    0,                                          /* tp_dict */\r
-    0,                                          /* tp_descr_get */\r
-    0,                                          /* tp_descr_set */\r
-    0,                                          /* tp_dictoffset */\r
-    (initproc)list_init,                        /* tp_init */\r
-    PyType_GenericAlloc,                        /* tp_alloc */\r
-    PyType_GenericNew,                          /* tp_new */\r
-    PyObject_GC_Del,                            /* tp_free */\r
-};\r
-\r
-\r
-/*********************** List Iterator **************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    long it_index;\r
-    PyListObject *it_seq; /* Set to NULL when iterator is exhausted */\r
-} listiterobject;\r
-\r
-static PyObject *list_iter(PyObject *);\r
-static void listiter_dealloc(listiterobject *);\r
-static int listiter_traverse(listiterobject *, visitproc, void *);\r
-static PyObject *listiter_next(listiterobject *);\r
-static PyObject *listiter_len(listiterobject *);\r
-\r
-PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");\r
-\r
-static PyMethodDef listiter_methods[] = {\r
-    {"__length_hint__", (PyCFunction)listiter_len, METH_NOARGS, length_hint_doc},\r
-    {NULL,              NULL}           /* sentinel */\r
-};\r
-\r
-PyTypeObject PyListIter_Type = {\r
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
-    "listiterator",                             /* tp_name */\r
-    sizeof(listiterobject),                     /* tp_basicsize */\r
-    0,                                          /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)listiter_dealloc,               /* tp_dealloc */\r
-    0,                                          /* tp_print */\r
-    0,                                          /* tp_getattr */\r
-    0,                                          /* tp_setattr */\r
-    0,                                          /* tp_compare */\r
-    0,                                          /* tp_repr */\r
-    0,                                          /* tp_as_number */\r
-    0,                                          /* tp_as_sequence */\r
-    0,                                          /* tp_as_mapping */\r
-    0,                                          /* tp_hash */\r
-    0,                                          /* tp_call */\r
-    0,                                          /* tp_str */\r
-    PyObject_GenericGetAttr,                    /* tp_getattro */\r
-    0,                                          /* tp_setattro */\r
-    0,                                          /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */\r
-    0,                                          /* tp_doc */\r
-    (traverseproc)listiter_traverse,            /* tp_traverse */\r
-    0,                                          /* tp_clear */\r
-    0,                                          /* tp_richcompare */\r
-    0,                                          /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                          /* tp_iter */\r
-    (iternextfunc)listiter_next,                /* tp_iternext */\r
-    listiter_methods,                           /* tp_methods */\r
-    0,                                          /* tp_members */\r
-};\r
-\r
-\r
-static PyObject *\r
-list_iter(PyObject *seq)\r
-{\r
-    listiterobject *it;\r
-\r
-    if (!PyList_Check(seq)) {\r
-        PyErr_BadInternalCall();\r
-        return NULL;\r
-    }\r
-    it = PyObject_GC_New(listiterobject, &PyListIter_Type);\r
-    if (it == NULL)\r
-        return NULL;\r
-    it->it_index = 0;\r
-    Py_INCREF(seq);\r
-    it->it_seq = (PyListObject *)seq;\r
-    _PyObject_GC_TRACK(it);\r
-    return (PyObject *)it;\r
-}\r
-\r
-static void\r
-listiter_dealloc(listiterobject *it)\r
-{\r
-    _PyObject_GC_UNTRACK(it);\r
-    Py_XDECREF(it->it_seq);\r
-    PyObject_GC_Del(it);\r
-}\r
-\r
-static int\r
-listiter_traverse(listiterobject *it, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(it->it_seq);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-listiter_next(listiterobject *it)\r
-{\r
-    PyListObject *seq;\r
-    PyObject *item;\r
-\r
-    assert(it != NULL);\r
-    seq = it->it_seq;\r
-    if (seq == NULL)\r
-        return NULL;\r
-    assert(PyList_Check(seq));\r
-\r
-    if (it->it_index < PyList_GET_SIZE(seq)) {\r
-        item = PyList_GET_ITEM(seq, it->it_index);\r
-        ++it->it_index;\r
-        Py_INCREF(item);\r
-        return item;\r
-    }\r
-\r
-    Py_DECREF(seq);\r
-    it->it_seq = NULL;\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-listiter_len(listiterobject *it)\r
-{\r
-    Py_ssize_t len;\r
-    if (it->it_seq) {\r
-        len = PyList_GET_SIZE(it->it_seq) - it->it_index;\r
-        if (len >= 0)\r
-            return PyInt_FromSsize_t(len);\r
-    }\r
-    return PyInt_FromLong(0);\r
-}\r
-/*********************** List Reverse Iterator **************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    Py_ssize_t it_index;\r
-    PyListObject *it_seq; /* Set to NULL when iterator is exhausted */\r
-} listreviterobject;\r
-\r
-static PyObject *list_reversed(PyListObject *, PyObject *);\r
-static void listreviter_dealloc(listreviterobject *);\r
-static int listreviter_traverse(listreviterobject *, visitproc, void *);\r
-static PyObject *listreviter_next(listreviterobject *);\r
-static PyObject *listreviter_len(listreviterobject *);\r
-\r
-static PyMethodDef listreviter_methods[] = {\r
-    {"__length_hint__", (PyCFunction)listreviter_len, METH_NOARGS, length_hint_doc},\r
-    {NULL,              NULL}           /* sentinel */\r
-};\r
-\r
-PyTypeObject PyListRevIter_Type = {\r
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
-    "listreverseiterator",                      /* tp_name */\r
-    sizeof(listreviterobject),                  /* tp_basicsize */\r
-    0,                                          /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)listreviter_dealloc,            /* tp_dealloc */\r
-    0,                                          /* tp_print */\r
-    0,                                          /* tp_getattr */\r
-    0,                                          /* tp_setattr */\r
-    0,                                          /* tp_compare */\r
-    0,                                          /* tp_repr */\r
-    0,                                          /* tp_as_number */\r
-    0,                                          /* tp_as_sequence */\r
-    0,                                          /* tp_as_mapping */\r
-    0,                                          /* tp_hash */\r
-    0,                                          /* tp_call */\r
-    0,                                          /* tp_str */\r
-    PyObject_GenericGetAttr,                    /* tp_getattro */\r
-    0,                                          /* tp_setattro */\r
-    0,                                          /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */\r
-    0,                                          /* tp_doc */\r
-    (traverseproc)listreviter_traverse,         /* tp_traverse */\r
-    0,                                          /* tp_clear */\r
-    0,                                          /* tp_richcompare */\r
-    0,                                          /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                          /* tp_iter */\r
-    (iternextfunc)listreviter_next,             /* tp_iternext */\r
-    listreviter_methods,                /* tp_methods */\r
-    0,\r
-};\r
-\r
-static PyObject *\r
-list_reversed(PyListObject *seq, PyObject *unused)\r
-{\r
-    listreviterobject *it;\r
-\r
-    it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type);\r
-    if (it == NULL)\r
-        return NULL;\r
-    assert(PyList_Check(seq));\r
-    it->it_index = PyList_GET_SIZE(seq) - 1;\r
-    Py_INCREF(seq);\r
-    it->it_seq = seq;\r
-    PyObject_GC_Track(it);\r
-    return (PyObject *)it;\r
-}\r
-\r
-static void\r
-listreviter_dealloc(listreviterobject *it)\r
-{\r
-    PyObject_GC_UnTrack(it);\r
-    Py_XDECREF(it->it_seq);\r
-    PyObject_GC_Del(it);\r
-}\r
-\r
-static int\r
-listreviter_traverse(listreviterobject *it, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(it->it_seq);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-listreviter_next(listreviterobject *it)\r
-{\r
-    PyObject *item;\r
-    Py_ssize_t index = it->it_index;\r
-    PyListObject *seq = it->it_seq;\r
-\r
-    if (index>=0 && index < PyList_GET_SIZE(seq)) {\r
-        item = PyList_GET_ITEM(seq, index);\r
-        it->it_index--;\r
-        Py_INCREF(item);\r
-        return item;\r
-    }\r
-    it->it_index = -1;\r
-    if (seq != NULL) {\r
-        it->it_seq = NULL;\r
-        Py_DECREF(seq);\r
-    }\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-listreviter_len(listreviterobject *it)\r
-{\r
-    Py_ssize_t len = it->it_index + 1;\r
-    if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len)\r
-        len = 0;\r
-    return PyLong_FromSsize_t(len);\r
-}\r