Home | History | Annotate | Download | only in Utility
      1 /*
      2  * Optional optimisations of built-in functions and methods.
      3  *
      4  * Required replacements of builtins are in Builtins.c.
      5  *
      6  * General object operations and protocols are in ObjectHandling.c.
      7  */
      8 
      9 /////////////// append.proto ///////////////
     10 
     11 static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x); /*proto*/
     12 
     13 /////////////// append ///////////////
     14 //@requires: ListAppend
     15 //@requires: ObjectHandling.c::PyObjectCallMethod
     16 
     17 static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
     18     if (likely(PyList_CheckExact(L))) {
     19         if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1;
     20     } else {
     21         PyObject* retval = __Pyx_PyObject_CallMethod1(L, PYIDENT("append"), x);
     22         if (unlikely(!retval))
     23             return -1;
     24         Py_DECREF(retval);
     25     }
     26     return 0;
     27 }
     28 
     29 /////////////// ListAppend.proto ///////////////
     30 
     31 #if CYTHON_COMPILING_IN_CPYTHON
     32 static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
     33     PyListObject* L = (PyListObject*) list;
     34     Py_ssize_t len = Py_SIZE(list);
     35     if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
     36         Py_INCREF(x);
     37         PyList_SET_ITEM(list, len, x);
     38         Py_SIZE(list) = len+1;
     39         return 0;
     40     }
     41     return PyList_Append(list, x);
     42 }
     43 #else
     44 #define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
     45 #endif
     46 
     47 /////////////// ListCompAppend.proto ///////////////
     48 
     49 #if CYTHON_COMPILING_IN_CPYTHON
     50 static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
     51     PyListObject* L = (PyListObject*) list;
     52     Py_ssize_t len = Py_SIZE(list);
     53     if (likely(L->allocated > len)) {
     54         Py_INCREF(x);
     55         PyList_SET_ITEM(list, len, x);
     56         Py_SIZE(list) = len+1;
     57         return 0;
     58     }
     59     return PyList_Append(list, x);
     60 }
     61 #else
     62 #define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
     63 #endif
     64 
     65 //////////////////// ListExtend.proto ////////////////////
     66 
     67 static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
     68 #if CYTHON_COMPILING_IN_CPYTHON
     69     PyObject* none = _PyList_Extend((PyListObject*)L, v);
     70     if (unlikely(!none))
     71         return -1;
     72     Py_DECREF(none);
     73     return 0;
     74 #else
     75     return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
     76 #endif
     77 }
     78 
     79 /////////////// pop.proto ///////////////
     80 
     81 #define __Pyx_PyObject_Pop(L) (PyList_CheckExact(L) ? \
     82     __Pyx_PyList_Pop(L) : __Pyx__PyObject_Pop(L))
     83 
     84 static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L); /*proto*/
     85 static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L); /*proto*/
     86 
     87 /////////////// pop ///////////////
     88 //@requires: ObjectHandling.c::PyObjectCallMethod
     89 
     90 static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L) {
     91 #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02050000
     92     if (Py_TYPE(L) == &PySet_Type) {
     93         return PySet_Pop(L);
     94     }
     95 #endif
     96     return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop"));
     97 }
     98 
     99 static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L) {
    100 #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02040000
    101     /* Check that both the size is positive and no reallocation shrinking needs to be done. */
    102     if (likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) {
    103         Py_SIZE(L) -= 1;
    104         return PyList_GET_ITEM(L, PyList_GET_SIZE(L));
    105     }
    106 #endif
    107     return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop"));
    108 }
    109 
    110 
    111 /////////////// pop_index.proto ///////////////
    112 
    113 #define __Pyx_PyObject_PopIndex(L, ix) (PyList_CheckExact(L) ? \
    114     __Pyx_PyList_PopIndex(L, ix) : __Pyx__PyObject_PopIndex(L, ix))
    115 
    116 static PyObject* __Pyx_PyList_PopIndex(PyObject* L, Py_ssize_t ix); /*proto*/
    117 static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, Py_ssize_t ix); /*proto*/
    118 
    119 /////////////// pop_index ///////////////
    120 //@requires: ObjectHandling.c::PyObjectCallMethod
    121 
    122 static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, Py_ssize_t ix) {
    123     PyObject *r, *py_ix;
    124     py_ix = PyInt_FromSsize_t(ix);
    125     if (!py_ix) return NULL;
    126     r = __Pyx_PyObject_CallMethod1(L, PYIDENT("pop"), py_ix);
    127     Py_DECREF(py_ix);
    128     return r;
    129 }
    130 
    131 static PyObject* __Pyx_PyList_PopIndex(PyObject* L, Py_ssize_t ix) {
    132 #if CYTHON_COMPILING_IN_CPYTHON
    133     Py_ssize_t size = PyList_GET_SIZE(L);
    134     if (likely(size > (((PyListObject*)L)->allocated >> 1))) {
    135         Py_ssize_t cix = ix;
    136         if (cix < 0) {
    137             cix += size;
    138         }
    139         if (likely(0 <= cix && cix < size)) {
    140             PyObject* v = PyList_GET_ITEM(L, cix);
    141             Py_SIZE(L) -= 1;
    142             size -= 1;
    143             memmove(&PyList_GET_ITEM(L, cix), &PyList_GET_ITEM(L, cix+1), (size_t)(size-cix)*sizeof(PyObject*));
    144             return v;
    145         }
    146     }
    147 #endif
    148     return __Pyx__PyObject_PopIndex(L, ix);
    149 }
    150 
    151 
    152 /////////////// dict_getitem_default.proto ///////////////
    153 
    154 static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value); /*proto*/
    155 
    156 /////////////// dict_getitem_default ///////////////
    157 
    158 static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value) {
    159     PyObject* value;
    160 #if PY_MAJOR_VERSION >= 3
    161     value = PyDict_GetItemWithError(d, key);
    162     if (unlikely(!value)) {
    163         if (unlikely(PyErr_Occurred()))
    164             return NULL;
    165         value = default_value;
    166     }
    167     Py_INCREF(value);
    168 #else
    169     if (PyString_CheckExact(key) || PyUnicode_CheckExact(key) || PyInt_CheckExact(key)) {
    170         /* these presumably have safe hash functions */
    171         value = PyDict_GetItem(d, key);
    172         if (unlikely(!value)) {
    173             value = default_value;
    174         }
    175         Py_INCREF(value);
    176     } else {
    177         if (default_value == Py_None)
    178             default_value = NULL;
    179         value = PyObject_CallMethodObjArgs(
    180             d, PYIDENT("get"), key, default_value, NULL);
    181     }
    182 #endif
    183     return value;
    184 }
    185 
    186 
    187 /////////////// dict_setdefault.proto ///////////////
    188 
    189 static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value, int is_safe_type); /*proto*/
    190 
    191 /////////////// dict_setdefault ///////////////
    192 //@requires: ObjectHandling.c::PyObjectCallMethod
    193 
    194 static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value,
    195                                                        CYTHON_UNUSED int is_safe_type) {
    196     PyObject* value;
    197 #if PY_VERSION_HEX >= 0x030400A0
    198     // we keep the method call at the end to avoid "unused" C compiler warnings
    199     if (1) {
    200         value = PyDict_SetDefault(d, key, default_value);
    201         if (unlikely(!value)) return NULL;
    202         Py_INCREF(value);
    203 #else
    204     if (is_safe_type == 1 || (is_safe_type == -1 &&
    205         /* the following builtins presumably have repeatably safe and fast hash functions */
    206 #if PY_MAJOR_VERSION >= 3
    207             (PyUnicode_CheckExact(key) || PyString_CheckExact(key) || PyLong_CheckExact(key)))) {
    208         value = PyDict_GetItemWithError(d, key);
    209         if (unlikely(!value)) {
    210             if (unlikely(PyErr_Occurred()))
    211                 return NULL;
    212             if (unlikely(PyDict_SetItem(d, key, default_value) == -1))
    213                 return NULL;
    214             value = default_value;
    215         }
    216         Py_INCREF(value);
    217 #else
    218             (PyString_CheckExact(key) || PyUnicode_CheckExact(key) || PyInt_CheckExact(key) || PyLong_CheckExact(key)))) {
    219         value = PyDict_GetItem(d, key);
    220         if (unlikely(!value)) {
    221             if (unlikely(PyDict_SetItem(d, key, default_value) == -1))
    222                 return NULL;
    223             value = default_value;
    224         }
    225         Py_INCREF(value);
    226 #endif
    227 #endif
    228     } else {
    229         value = __Pyx_PyObject_CallMethod2(d, PYIDENT("setdefault"), key, default_value);
    230     }
    231     return value;
    232 }
    233 
    234 
    235 /////////////// py_dict_clear.proto ///////////////
    236 
    237 #define __Pyx_PyDict_Clear(d) (PyDict_Clear(d), 0)
    238 
    239 /////////////// dict_iter.proto ///////////////
    240 
    241 static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name,
    242                                                    Py_ssize_t* p_orig_length, int* p_is_dict);
    243 static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos,
    244                                               PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict);
    245 
    246 /////////////// dict_iter ///////////////
    247 //@requires: ObjectHandling.c::UnpackTuple2
    248 //@requires: ObjectHandling.c::IterFinish
    249 //@requires: ObjectHandling.c::PyObjectCallMethod
    250 
    251 static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name,
    252                                                    Py_ssize_t* p_orig_length, int* p_source_is_dict) {
    253     is_dict = is_dict || likely(PyDict_CheckExact(iterable));
    254     *p_source_is_dict = is_dict;
    255 #if !CYTHON_COMPILING_IN_PYPY
    256     if (is_dict) {
    257         *p_orig_length = PyDict_Size(iterable);
    258         Py_INCREF(iterable);
    259         return iterable;
    260     }
    261 #endif
    262     *p_orig_length = 0;
    263     if (method_name) {
    264         PyObject* iter;
    265         iterable = __Pyx_PyObject_CallMethod0(iterable, method_name);
    266         if (!iterable)
    267             return NULL;
    268 #if !CYTHON_COMPILING_IN_PYPY
    269         if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable))
    270             return iterable;
    271 #endif
    272         iter = PyObject_GetIter(iterable);
    273         Py_DECREF(iterable);
    274         return iter;
    275     }
    276     return PyObject_GetIter(iterable);
    277 }
    278 
    279 static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* iter_obj, Py_ssize_t orig_length, Py_ssize_t* ppos,
    280                                               PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) {
    281     PyObject* next_item;
    282 #if !CYTHON_COMPILING_IN_PYPY
    283     if (source_is_dict) {
    284         PyObject *key, *value;
    285         if (unlikely(orig_length != PyDict_Size(iter_obj))) {
    286             PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration");
    287             return -1;
    288         }
    289         if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) {
    290             return 0;
    291         }
    292         if (pitem) {
    293             PyObject* tuple = PyTuple_New(2);
    294             if (unlikely(!tuple)) {
    295                 return -1;
    296             }
    297             Py_INCREF(key);
    298             Py_INCREF(value);
    299             PyTuple_SET_ITEM(tuple, 0, key);
    300             PyTuple_SET_ITEM(tuple, 1, value);
    301             *pitem = tuple;
    302         } else {
    303             if (pkey) {
    304                 Py_INCREF(key);
    305                 *pkey = key;
    306             }
    307             if (pvalue) {
    308                 Py_INCREF(value);
    309                 *pvalue = value;
    310             }
    311         }
    312         return 1;
    313     } else if (PyTuple_CheckExact(iter_obj)) {
    314         Py_ssize_t pos = *ppos;
    315         if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0;
    316         *ppos = pos + 1;
    317         next_item = PyTuple_GET_ITEM(iter_obj, pos);
    318         Py_INCREF(next_item);
    319     } else if (PyList_CheckExact(iter_obj)) {
    320         Py_ssize_t pos = *ppos;
    321         if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0;
    322         *ppos = pos + 1;
    323         next_item = PyList_GET_ITEM(iter_obj, pos);
    324         Py_INCREF(next_item);
    325     } else
    326 #endif
    327     {
    328         next_item = PyIter_Next(iter_obj);
    329         if (unlikely(!next_item)) {
    330             return __Pyx_IterFinish();
    331         }
    332     }
    333     if (pitem) {
    334         *pitem = next_item;
    335     } else if (pkey && pvalue) {
    336         if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1))
    337             return -1;
    338     } else if (pkey) {
    339         *pkey = next_item;
    340     } else {
    341         *pvalue = next_item;
    342     }
    343     return 1;
    344 }
    345 
    346 
    347 /////////////// unicode_iter.proto ///////////////
    348 
    349 static CYTHON_INLINE int __Pyx_init_unicode_iteration(
    350     PyObject* ustring, Py_ssize_t *length, void** data, int *kind); /* proto */
    351 
    352 /////////////// unicode_iter ///////////////
    353 
    354 static CYTHON_INLINE int __Pyx_init_unicode_iteration(
    355     PyObject* ustring, Py_ssize_t *length, void** data, int *kind) {
    356 #if CYTHON_PEP393_ENABLED
    357     if (unlikely(__Pyx_PyUnicode_READY(ustring) < 0)) return -1;
    358     *kind   = PyUnicode_KIND(ustring);
    359     *length = PyUnicode_GET_LENGTH(ustring);
    360     *data   = PyUnicode_DATA(ustring);
    361 #else
    362     *kind   = 0;
    363     *length = PyUnicode_GET_SIZE(ustring);
    364     *data   = (void*)PyUnicode_AS_UNICODE(ustring);
    365 #endif
    366     return 0;
    367 }
    368 
    369 /////////////// pyobject_as_double.proto ///////////////
    370 
    371 static double __Pyx__PyObject_AsDouble(PyObject* obj); /* proto */
    372 
    373 #if CYTHON_COMPILING_IN_PYPY
    374 #define __Pyx_PyObject_AsDouble(obj) \
    375 (likely(PyFloat_CheckExact(obj)) ? PyFloat_AS_DOUBLE(obj) : \
    376  likely(PyInt_CheckExact(obj)) ? \
    377  PyFloat_AsDouble(obj) : __Pyx__PyObject_AsDouble(obj))
    378 #else
    379 #define __Pyx_PyObject_AsDouble(obj) \
    380 ((likely(PyFloat_CheckExact(obj))) ? \
    381  PyFloat_AS_DOUBLE(obj) : __Pyx__PyObject_AsDouble(obj))
    382 #endif
    383 
    384 /////////////// pyobject_as_double ///////////////
    385 
    386 static double __Pyx__PyObject_AsDouble(PyObject* obj) {
    387     PyObject* float_value;
    388 #if CYTHON_COMPILING_IN_PYPY
    389     float_value = PyNumber_Float(obj);
    390 #else
    391     PyNumberMethods *nb = Py_TYPE(obj)->tp_as_number;
    392     if (likely(nb) && likely(nb->nb_float)) {
    393         float_value = nb->nb_float(obj);
    394         if (likely(float_value) && unlikely(!PyFloat_Check(float_value))) {
    395             PyErr_Format(PyExc_TypeError,
    396                 "__float__ returned non-float (type %.200s)",
    397                 Py_TYPE(float_value)->tp_name);
    398             Py_DECREF(float_value);
    399             goto bad;
    400         }
    401     } else if (PyUnicode_CheckExact(obj) || PyBytes_CheckExact(obj)) {
    402 #if PY_MAJOR_VERSION >= 3
    403         float_value = PyFloat_FromString(obj);
    404 #else
    405         float_value = PyFloat_FromString(obj, 0);
    406 #endif
    407     } else {
    408         PyObject* args = PyTuple_New(1);
    409         if (unlikely(!args)) goto bad;
    410         PyTuple_SET_ITEM(args, 0, obj);
    411         float_value = PyObject_Call((PyObject*)&PyFloat_Type, args, 0);
    412         PyTuple_SET_ITEM(args, 0, 0);
    413         Py_DECREF(args);
    414     }
    415 #endif
    416     if (likely(float_value)) {
    417         double value = PyFloat_AS_DOUBLE(float_value);
    418         Py_DECREF(float_value);
    419         return value;
    420     }
    421 bad:
    422     return (double)-1;
    423 }
    424