Commit b02b993c authored by Stefan Behnel's avatar Stefan Behnel

implement recursive carray copying (arrays of arrays)

parent ebc3df31
......@@ -4065,13 +4065,7 @@ class SliceIndexNode(ExprNode):
has_c_start, has_c_stop,
bool(code.globalstate.directives['wraparound'])))
else:
start_offset = ''
if self.start:
start_offset = self.start_code()
if start_offset == '0':
start_offset = ''
else:
start_offset += '+'
start_offset = self.start_code() if self.start else '0'
if rhs.type.is_array:
array_length = rhs.type.size
self.generate_slice_guard_code(code, array_length)
......@@ -4080,10 +4074,31 @@ class SliceIndexNode(ExprNode):
"Slice assignments from pointers are not yet supported.")
# FIXME: fix the array size according to start/stop
array_length = self.base.type.size
for i in range(array_length):
code.putln("%s[%s%s] = %s[%d];" % (
self.base.result(), start_offset, i,
rhs.result(), i))
def copy_carray(dst, src, item_type, start, count, depth):
var_name = Naming.quick_temp_cname
if depth:
var_name += str(depth)
dst_item, src_item = '{dst}[{i}+{start}] = {src}[{i}]'.format(
src=src,
dst=dst,
start=start,
i=var_name
).split(' = ')
code.putln('{')
code.putln('Py_ssize_t %s;' % var_name)
code.put('for ({i}=0; {i} < {count}; {i}++) '.format(
i=var_name,
count=count))
if item_type.is_array:
copy_carray(dst_item, src_item, item_type.base_type, 0, item_type.size, depth + 1)
else:
code.putln('%s = %s;' % (dst_item, src_item))
code.putln('}')
copy_carray(self.base.result(), rhs.result(), rhs.type.base_type,
start_offset, array_length, 0)
self.generate_subexpr_disposal_code(code)
self.free_subexpr_temps(code)
rhs.generate_disposal_code(code)
......
......@@ -115,6 +115,62 @@ def to_int_array(x):
return v[0], v[1], v[2]
def to_int_array_array(x):
"""
>>> to_int_array_array([[1, 2, 3], [4, 5, 6]])
(1, 2, 3, 4, 5, 6)
>>> to_int_array_array(iter([[1, 2, 3], [4, 5, 6]]))
(1, 2, 3, 4, 5, 6)
>>> to_int_array_array([[1, 2, 3]])
Traceback (most recent call last):
IndexError: not enough values found during array assignment, expected 2, got 1
>>> to_int_array_array(iter([[1, 2, 3]]))
Traceback (most recent call last):
IndexError: not enough values found during array assignment, expected 2, got 1
>>> to_int_array_array([[1, 2, 3], [4, 5]])
Traceback (most recent call last):
IndexError: not enough values found during array assignment, expected 3, got 2
>>> to_int_array_array(iter([[1, 2, 3], [4, 5]]))
Traceback (most recent call last):
IndexError: not enough values found during array assignment, expected 3, got 2
>>> to_int_array_array([[1, 2, 3, 4], [5, 6, 7]])
Traceback (most recent call last):
IndexError: too many values found during array assignment, expected 3
>>> to_int_array_array(iter([[1, 2, 3, 4], [5, 6, 7]]))
Traceback (most recent call last):
IndexError: too many values found during array assignment, expected 3
"""
cdef int[2][3] v = x
return v[0][0], v[0][1], v[0][2], v[1][0], v[1][1], v[1][2]
'''
# FIXME: this isn't currently allowed
cdef enum:
SIZE_A = 2
SIZE_B = 3
def to_int_array_array_enumsize(x):
"""
>>> to_int_array_array([[1, 2, 3], [4, 5, 6]])
(1, 2, 3, 4, 5, 6)
>>> to_int_array_array(iter([[1, 2, 3], [4, 5, 6]]))
(1, 2, 3, 4, 5, 6)
>>> to_int_array([1, 2])
Traceback (most recent call last):
IndexError: not enough values found during array assignment, expected 3, got 2
>>> to_int_array([1, 2, 3, 4])
Traceback (most recent call last):
IndexError: too many values found during array assignment, expected 3
"""
cdef int[SIZE_A][SIZE_B] v = x
return v[0][0], v[0][1], v[0][2], v[1][0], v[1][1], v[1][2]
'''
def to_int_array_slice(x):
"""
>>> to_int_array_slice([1, 2, 3])
......@@ -175,3 +231,18 @@ def to_struct_array(x):
assert w[1].y == v[1].y
return v[0], w[1]
def to_struct_array_array(x):
"""
>>> (a1, a2, a3), (b1, b2, b3) = to_struct_array_array([
... ({'x': 11, 'y': 12}, {'x': 13, 'y': 14}, {'x': 15, 'y': 16}),
... ({'x': 21, 'y': 22}, {'x': 23, 'y': 24}, {'x': 25, 'y': 26}),
... ])
>>> a1['x'], a1['y']
(11, 12.0)
>>> b3['x'], b3['y']
(25, 26.0)
"""
cdef MyStructType[2][3] v = x
return v[0], v[1]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment