diff options
author | Armin Rigo <arigo@tunes.org> | 2013-02-10 17:37:01 +0100 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2013-02-10 17:37:01 +0100 |
commit | 5160deb4eef35b473ac75293b31e7b6faff90161 (patch) | |
tree | 5e1ec4437a0fe9bb45a1a8590e3e7009af23b5f9 | |
parent | c06458545ef05fdd2137c5497e3d6c7da4d3886b (diff) | |
download | cffi-slicing.tar.gz |
Add a past path for slice assignment with a cdata-of-same-type source.slicing
-rw-r--r-- | c/_cffi_backend.c | 18 | ||||
-rw-r--r-- | c/test_c.py | 14 |
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] |