3#ifndef __NUITKA_HELPER_SLICES_H__
4#define __NUITKA_HELPER_SLICES_H__
8#include "nuitka/prelude.h"
11#if PYTHON_VERSION >= 0x3a0
12extern PyObject *Nuitka_Slice_New(PyThreadState *tstate, PyObject *start, PyObject *stop, PyObject *step);
14#define Nuitka_Slice_New(tstate, start, stop, step) PySlice_New(start, stop, step)
18NUITKA_MAY_BE_UNUSED
static PyObject *MAKE_SLICE_OBJECT3(PyThreadState *tstate, PyObject *start, PyObject *stop,
24 return Nuitka_Slice_New(tstate, start, stop, step);
26NUITKA_MAY_BE_UNUSED
static PyObject *MAKE_SLICE_OBJECT2(PyThreadState *tstate, PyObject *start, PyObject *stop) {
30 return Nuitka_Slice_New(tstate, start, stop, Py_None);
32NUITKA_MAY_BE_UNUSED
static PyObject *MAKE_SLICE_OBJECT1(PyThreadState *tstate, PyObject *stop) {
35 return Nuitka_Slice_New(tstate, Py_None, stop, Py_None);
38#if PYTHON_VERSION < 0x300
43static inline bool IS_INDEXABLE(PyObject *value) {
44 return value == Py_None ||
45#if PYTHON_VERSION < 0x300
48 PyLong_Check(value) || Nuitka_Index_Check(value);
51static Py_ssize_t CONVERT_TO_INDEX(PyThreadState *tstate, PyObject *value) {
54 if (PyInt_Check(value)) {
55 return PyInt_AS_LONG(value);
56 }
else if (Nuitka_Index_Check(value)) {
57 return PyNumber_AsSsize_t(value, NULL);
59 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
60 "slice indices must be integers or None or have an __index__ method");
65NUITKA_MAY_BE_UNUSED
static PyObject *LOOKUP_SLICE(PyThreadState *tstate, PyObject *source, PyObject *lower,
71 PySequenceMethods *tp_as_sequence = Py_TYPE(source)->tp_as_sequence;
73 if (tp_as_sequence && tp_as_sequence->sq_slice && IS_INDEXABLE(lower) && IS_INDEXABLE(upper)) {
76 if (lower != Py_None) {
77 ilow = CONVERT_TO_INDEX(tstate, lower);
79 if (ilow == -1 && HAS_ERROR_OCCURRED(tstate)) {
84 Py_ssize_t ihigh = PY_SSIZE_T_MAX;
86 if (upper != Py_None) {
87 ihigh = CONVERT_TO_INDEX(tstate, upper);
89 if (ihigh == -1 && HAS_ERROR_OCCURRED(tstate)) {
94 PyObject *result = PySequence_GetSlice(source, ilow, ihigh);
96 if (unlikely(result == NULL)) {
102 PyObject *slice = PySlice_New(lower, upper, NULL);
104 if (unlikely(slice == NULL)) {
108 PyObject *result = PyObject_GetItem(source, slice);
111 if (unlikely(result == NULL)) {
119NUITKA_MAY_BE_UNUSED
static PyObject *LOOKUP_INDEX_SLICE(PyObject *source, Py_ssize_t lower, Py_ssize_t upper) {
120 CHECK_OBJECT(source);
122 PyObject *result = PySequence_GetSlice(source, lower, upper);
124 if (unlikely(result == NULL)) {
131NUITKA_MAY_BE_UNUSED
static bool SET_SLICE(PyThreadState *tstate, PyObject *target, PyObject *lower, PyObject *upper,
133 CHECK_OBJECT(target);
138 PySequenceMethods *tp_as_sequence = Py_TYPE(target)->tp_as_sequence;
140 if (tp_as_sequence && tp_as_sequence->sq_ass_slice && IS_INDEXABLE(lower) && IS_INDEXABLE(upper)) {
141 Py_ssize_t lower_int = 0;
143 if (lower != Py_None) {
144 lower_int = CONVERT_TO_INDEX(tstate, lower);
146 if (lower_int == -1 && HAS_ERROR_OCCURRED(tstate)) {
151 Py_ssize_t upper_int = PY_SSIZE_T_MAX;
153 if (upper != Py_None) {
154 upper_int = CONVERT_TO_INDEX(tstate, upper);
156 if (upper_int == -1 && HAS_ERROR_OCCURRED(tstate)) {
161 int status = PySequence_SetSlice(target, lower_int, upper_int, value);
163 if (unlikely(status == -1)) {
167 PyObject *slice = PySlice_New(lower, upper, NULL);
169 if (unlikely(slice == NULL)) {
173 int status = PyObject_SetItem(target, slice, value);
176 if (unlikely(status == -1)) {
184NUITKA_MAY_BE_UNUSED
static bool SET_INDEX_SLICE(PyObject *target, Py_ssize_t lower, Py_ssize_t upper,
186 CHECK_OBJECT(target);
189 PySequenceMethods *tp_as_sequence = Py_TYPE(target)->tp_as_sequence;
191 if (tp_as_sequence && tp_as_sequence->sq_ass_slice) {
192 int status = PySequence_SetSlice(target, lower, upper, value);
194 if (unlikely(status == -1)) {
198 PyObject *slice = _PySlice_FromIndices(lower, upper);
200 if (unlikely(slice == NULL)) {
204 int status = PyObject_SetItem(target, slice, value);
208 if (unlikely(status == -1)) {
216NUITKA_MAY_BE_UNUSED
static bool DEL_SLICE(PyThreadState *tstate, PyObject *target, PyObject *lower, PyObject *upper) {
217 CHECK_OBJECT(target);
221 PySequenceMethods *tp_as_sequence = Py_TYPE(target)->tp_as_sequence;
223 if (tp_as_sequence && tp_as_sequence->sq_ass_slice && IS_INDEXABLE(lower) && IS_INDEXABLE(upper)) {
224 Py_ssize_t lower_int = 0;
226 if (lower != Py_None) {
227 lower_int = CONVERT_TO_INDEX(tstate, lower);
229 if (lower_int == -1 && HAS_ERROR_OCCURRED(tstate)) {
234 Py_ssize_t upper_int = PY_SSIZE_T_MAX;
236 if (upper != Py_None) {
237 upper_int = CONVERT_TO_INDEX(tstate, upper);
239 if (upper_int == -1 && HAS_ERROR_OCCURRED(tstate)) {
244 int status = PySequence_DelSlice(target, lower_int, upper_int);
246 if (unlikely(status == -1)) {
250 PyObject *slice = PySlice_New(lower, upper, NULL);
252 if (unlikely(slice == NULL)) {
256 int status = PyObject_DelItem(target, slice);
259 if (unlikely(status == -1)) {
267NUITKA_MAY_BE_UNUSED
static bool DEL_INDEX_SLICE(PyObject *target, Py_ssize_t lower, Py_ssize_t upper) {
268 CHECK_OBJECT(target);
270 PySequenceMethods *tp_as_sequence = Py_TYPE(target)->tp_as_sequence;
272 if (tp_as_sequence && tp_as_sequence->sq_ass_slice) {
273 int status = PySequence_DelSlice(target, lower, upper);
275 if (unlikely(status == -1)) {
279 PyObject *slice = _PySlice_FromIndices(lower, upper);
281 if (unlikely(slice == NULL)) {
285 int status = PyObject_DelItem(target, slice);
289 if (unlikely(status == -1)) {