summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2013-02-10 17:37:01 +0100
committerArmin Rigo <arigo@tunes.org>2013-02-10 17:37:01 +0100
commit5160deb4eef35b473ac75293b31e7b6faff90161 (patch)
tree5e1ec4437a0fe9bb45a1a8590e3e7009af23b5f9
parentc06458545ef05fdd2137c5497e3d6c7da4d3886b (diff)
downloadcffi-slicing.tar.gz
Add a past path for slice assignment with a cdata-of-same-type source.slicing
-rw-r--r--c/_cffi_backend.c18
-rw-r--r--c/test_c.py14
2 files changed, 28 insertions, 4 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
index f34b033..844febc 100644
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1815,16 +1815,26 @@ cdata_ass_slice(CDataObject *cd, PySliceObject *slice, PyObject *v)
CTypeDescrObject *ct = _cdata_getslicearg(cd, slice, bounds);
if (ct == NULL)
return -1;
+ ct = ct->ct_itemdescr;
+ itemsize = ct->ct_size;
+ cdata = cd->c_data + itemsize * bounds[0];
+ length = bounds[1];
+
+ if (CData_Check(v)) {
+ CTypeDescrObject *ctv = ((CDataObject *)v)->c_type;
+ if ((ctv->ct_flags & CT_ARRAY) && (ctv->ct_itemdescr == ct) &&
+ (get_array_length((CDataObject *)v) == length)) {
+ /* fast path: copying from exactly the correct type */
+ memcpy(cdata, ((CDataObject *)v)->c_data, itemsize * length);
+ return 0;
+ }
+ }
it = PyObject_GetIter(v);
if (it == NULL)
return -1;
iternext = *it->ob_type->tp_iternext;
- ct = ct->ct_itemdescr;
- itemsize = ct->ct_size;
- cdata = cd->c_data + itemsize * bounds[0];
- length = bounds[1];
for (i = 0; i < length; i++) {
item = iternext(it);
if (item == NULL) {
diff --git a/c/test_c.py b/c/test_c.py
index ced4b13..c8202ad 100644
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -2642,3 +2642,17 @@ def test_setslice():
assert list(c) == [0, 100, 1000, 600, 0]
py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)")
assert list(c) == [0, 100, 700, 800, 0]
+
+def test_setslice_array():
+ BIntP = new_pointer_type(new_primitive_type("int"))
+ BIntArray = new_array_type(BIntP, None)
+ c = newp(BIntArray, 5)
+ d = newp(BIntArray, [10, 20, 30])
+ c[1:4] = d
+ assert list(c) == [0, 10, 20, 30, 0]
+ #
+ BShortP = new_pointer_type(new_primitive_type("short"))
+ BShortArray = new_array_type(BShortP, None)
+ d = newp(BShortArray, [40, 50])
+ c[1:3] = d
+ assert list(c) == [0, 40, 50, 30, 0]