Skip to content

Commit fb2a375

Browse files
committed
Fixed bug with Implicit array cpp backend
1 parent 9a424a7 commit fb2a375

File tree

2 files changed

+43
-35
lines changed

2 files changed

+43
-35
lines changed

pydatastructs/linear_data_structures/_backend/cpp/arrays/OneDimensionalImplicitArray.hpp

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@ typedef struct
1414
size_t _size;
1515
PyObject *_dtype;
1616
PyObject *_function;
17-
PyObject *_init;
1817
} OneDimensionalImplicitArray;
1918

2019
static void OneDimensionalImplicitArray_dealloc(OneDimensionalImplicitArray *self)
2120
{
2221
Py_XDECREF(self->_dtype);
2322
Py_XDECREF(self->_function);
24-
Py_XDECREF(self->_init);
2523
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject *>(self));
2624
}
2725

@@ -31,26 +29,17 @@ static PyObject *OneDimensionalImplicitArray___new__(PyTypeObject *type, PyObjec
3129
self = reinterpret_cast<OneDimensionalImplicitArray *>(type->tp_alloc(type, 0));
3230
size_t len_args = PyObject_Length(args);
3331

34-
if (len_args < 1)
32+
if (len_args < 2)
3533
{
36-
PyErr_SetString(PyExc_ValueError, "Too few arguments to create a 1D implicit array, pass the function of the array");
34+
PyErr_SetString(PyExc_ValueError, "Too few arguments to create a 1D implicit array, pass the function of the array and the size of the array");
3735
return NULL;
3836
}
3937
if (len_args > 2)
4038
{
41-
PyErr_SetString(PyExc_ValueError, "Too many arguments to create an implicit 1D array, pass the function of the array and optionally the size of the array");
39+
PyErr_SetString(PyExc_ValueError, "Too many arguments to create an implicit 1D array, pass the function of the array and the size of the array");
4240
return NULL;
4341
}
4442

45-
PyObject *function = PyObject_GetItem(args, PyZero);
46-
if (!PyCallable_Check(function))
47-
{
48-
PyErr_SetString(PyExc_TypeError, "Expected type of function is function");
49-
return NULL;
50-
}
51-
self->_function = function;
52-
Py_INCREF(self->_function);
53-
5443
PyObject *dtype = PyObject_GetItem(kwds, PyUnicode_FromString("dtype"));
5544
if (dtype == nullptr)
5645
{
@@ -60,32 +49,26 @@ static PyObject *OneDimensionalImplicitArray___new__(PyTypeObject *type, PyObjec
6049
self->_dtype = dtype;
6150
Py_INCREF(self->_dtype);
6251

63-
if (len_args == 2)
64-
{
65-
PyObject *size_obj = PyObject_GetItem(args, PyOne);
66-
if (!PyLong_Check(size_obj))
67-
{
68-
PyErr_SetString(PyExc_TypeError, "Expected type of size is int");
69-
return NULL;
70-
}
71-
self->_size = PyLong_AsSize_t(size_obj);
72-
}
73-
else
52+
PyObject *args0 = PyObject_GetItem(args, PyZero);
53+
PyObject *args1 = PyObject_GetItem(args, PyOne);
54+
55+
if (PyCallable_Check(args0) && PyLong_Check(args1))
7456
{
75-
self->_size = 0;
57+
self->_function = args0;
58+
Py_INCREF(self->_function);
59+
self->_size = PyLong_AsSize_t(args1);
7660
}
77-
78-
PyObject *init = PyObject_GetItem(kwds, PyUnicode_FromString("init"));
79-
if (init == nullptr)
61+
else if (PyCallable_Check(args1) && PyLong_Check(args0))
8062
{
81-
PyErr_Clear();
82-
self->_init = Py_None;
63+
self->_function = args1;
64+
Py_INCREF(self->_function);
65+
self->_size = PyLong_AsSize_t(args0);
8366
}
8467
else
8568
{
86-
self->_init = init;
69+
PyErr_SetString(PyExc_TypeError, "Expected one function and one integer for size");
70+
return NULL;
8771
}
88-
Py_INCREF(self->_init);
8972

9073
return reinterpret_cast<PyObject *>(self);
9174
}
@@ -115,6 +98,31 @@ static Py_ssize_t OneDimensionalImplicitArray___len__(OneDimensionalImplicitArra
11598
return self->_size;
11699
}
117100

101+
static PyObject *OneDimensionalImplicitArray_get_data(OneDimensionalImplicitArray *self, void *closure)
102+
{
103+
PyObject *list = PyList_New(self->_size);
104+
if (!list)
105+
{
106+
return NULL;
107+
}
108+
for (size_t i = 0; i < self->_size; i++)
109+
{
110+
PyObject *item = PyObject_CallFunctionObjArgs(self->_function, PyLong_FromSize_t(i), NULL);
111+
if (item == NULL)
112+
{
113+
Py_DECREF(list);
114+
return NULL;
115+
}
116+
PyList_SET_ITEM(list, i, item);
117+
}
118+
return list;
119+
}
120+
121+
static PyGetSetDef OneDimensionalImplicitArray_getsetters[] = {
122+
{"_data", (getter)OneDimensionalImplicitArray_get_data, NULL, "data", NULL},
123+
{NULL} /* Sentinel */
124+
};
125+
118126
static PyMappingMethods OneDimensionalImplicitArray_PyMappingMethods = {
119127
(lenfunc)OneDimensionalImplicitArray___len__,
120128
(binaryfunc)OneDimensionalImplicitArray___getitem__,
@@ -150,7 +158,7 @@ static PyTypeObject OneDimensionalImplicitArrayType = {
150158
/* tp_iternext */ 0,
151159
/* tp_methods */ 0,
152160
/* tp_members */ 0,
153-
/* tp_getset */ 0,
161+
/* tp_getset */ OneDimensionalImplicitArray_getsetters,
154162
/* tp_base */ &ArrayType,
155163
/* tp_dict */ 0,
156164
/* tp_descr_get */ 0,

pydatastructs/linear_data_structures/arrays.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ class OneDimensionalImplicitArray(ImplicitArray):
539539
def __new__(cls, dtype=NoneType, *args, **kwargs):
540540
backend = kwargs.get('backend', Backend.PYTHON)
541541
if backend == Backend.CPP:
542-
return _arrays.OneDimensionalImplicitArray(dtype, *args, **kwargs)
542+
return _arrays.OneDimensionalImplicitArray(dtype=dtype, *args, **kwargs)
543543
if dtype is NoneType:
544544
raise ValueError("Data type is not defined.")
545545
elif not _check_type(dtype, type):

0 commit comments

Comments
 (0)