On Thu, Nov 03, 2005 at 09:05:36AM +0100 Reinhard Pagitsch wrote: > Xavier Noria wrote: > >I founded nothing about slices in perlguts, perlxs*, or perlapi (where > >are they documented?), so I wrote this little utility to take a slice > >from AV* data using the indices in AV* indices (integers), and put the > >result in AV* out (indices and out are guaranteed to have the same > >length): > > > >void __slice(AV* indices, AV* data, AV* out) { > > int i; > > I32 last_index; > > I32 index; > > SV* val; > > > > last_index = av_len(indices); > > for (i = 0; i <= last_index; ++i) { > > index = SvIVX(*av_fetch(indices, i, 0)); > > val = *av_fetch(data, index, 0); > > av_store(out, i, newSVsv(val)); > > } > >} > > > >I am just starting to play around with the C API. Is this code right as > >far as XS is concerned? Is there a better idiom? > > > >-- fxn > > > > I do not understand what you mean. The code you posted here is only to > make a copy of the array data and put it into the array out.
No, his code copies only those elements whose indices are in the array passed as first argument to __slice. > I think simpler would be (not tested): > void __slice(AV* data, AV* out) { > int i; > I32 max; > > max = av_len(data); > for (i = 0; i <= max; ++i) { > av_store(out, i, newSVsv(*av_fetch(data, i, 0))); > } > } > > But on the other way a memcpy() coud be do the same, I think. That wouldn't work, unless you'd intend to make a deep memcpy. And that is more or less what newSVsv does. With a simple memcpy of the SV* array of an AV you'd sort of create aliases, but you'd mess up the ref-counts. They'd need to be adjusted as well (and I am not even sure that this is all it takes). Tassilo -- use bigint; $n=71423350343770280161397026330337371139054411854220053437565440; $m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);