From: Russell E. O. <ro...@uw...> - 2012-03-21 20:32:38
|
In article <row...@ne...>, "Russell E. Owen" <ro...@uw...> wrote: > I'm hoping somebody will eventually wrap std::array (much like > std_vector.i). Meanwhile I'll use the appended hack, adapted from > <http://stackoverflow.com/questions/7713318/nested-structure-array-access > -in-python-using-swig>. It has some unfortunate limitations: no way to > set all values at once, no range indexing, no relative indexing. But it > works and it certainly avoids excessive copying. I was able to overcome these problems using the appended .i excerpt. The resulting Python is as clean as I could hope for. One can do things like: test.d[:] = (1, 2, 3) atuple = test.d[:] test.d[0] = 1 test.d[-1] = 3.0 ... One cannot do this: test.d = (1, 2, 3) but I am fine with that because one cannot rebind test.d in any case. The C++ side is not ideal because of the array data is one level down from where it should be: in my example test.d.arr instead of test.d. I tried wrapping boost::array directly to make the C++ look normal, but unsurprisingly got an enormous number of errors -- enough to convince me to live with my simple solution for now. I hope somebody more familiar with SWIG will be able to figure out how to wrap std::array (the modern version of boost::array). -- Russell %extend tcc::swigArray { inline size_t __len__() const { return N; } inline const Type& _get(size_t i) const throw(std::out_of_range) { return $self->arr.at(i); } inline void _set(size_t i, const Type& v) throw(std::out_of_range) { $self->arr.at(i) = v; } %pythoncode { def __getitem__(self, key): if isinstance(key, slice): return tuple(self._get(i) for i in range(*key.indices(len(self)))) if key < 0: key += len(self) return self._get(key) def __setitem__(self, key, v): if isinstance(key, slice): for i in range(*key.indices(len(self))): self._set(i, v[i]) else: if key < 0: key += len(self) self._set(key, v) } } %template (swigArray_int_2) tcc::swigArray<int, 2>; %template (swigArray_int_3) tcc::swigArray<int, 3>; %template (swigArray_double_2) tcc::swigArray<double, 2>; %template (swigArray_double_3) tcc::swigArray<double, 3>; |