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);

Reply via email to