List-MoreUtils-XS
view release on metacpan or search on metacpan
int exhausted = 1;
/* 'cv' is the hidden argument with which XS_List__MoreUtils__array_iterator (this XSUB)
* is called. The closure_arg struct is stored in this CV. */
arrayeach_args *args = (arrayeach_args *)(CvXSUBANY(cv).any_ptr);
if (strEQ(method, "index"))
{
EXTEND(SP, 1);
ST(0) = args->curidx > 0 ? sv_2mortal(newSViv(args->curidx-1)) : &PL_sv_undef;
XSRETURN(1);
}
EXTEND(SP, args->navs);
for (i = 0; i < args->navs; i++)
{
AV *av = args->avs[i];
if (args->curidx <= av_len(av))
{
ST(i) = sv_2mortal(newSVsv(*av_fetch(av, args->curidx, FALSE)));
exhausted = 0;
continue;
}
ST(i) = &PL_sv_undef;
}
if (exhausted)
XSRETURN_EMPTY;
args->curidx++;
XSRETURN(args->navs);
}
SV *
each_array (...)
PROTOTYPE: \@;\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@
CODE:
{
EACH_ARRAY_BODY;
}
OUTPUT:
RETVAL
SV *
each_arrayref (...)
CODE:
{
EACH_ARRAY_BODY;
}
OUTPUT:
RETVAL
void
pairwise (code, list1, list2)
SV *code;
AV *list1;
AV *list2;
PROTOTYPE: &\@\@
PPCODE:
{
dMULTICALL;
dMULTICALLSVCV;
int i, maxitems;
AV *rc = newAV();
sv_2mortal(newRV_noinc((SV*)rc));
if(!codelike(code))
croak_xs_usage(cv, "code, list, list");
if (in_pad(aTHX_ code)) {
croak("Can't use lexical $a or $b in pairwise code block");
}
/* deref AV's for convenience and
* get maximum items */
maxitems = MAX(av_len(list1),av_len(list2))+1;
av_extend(rc, maxitems);
gimme = G_ARRAY;
PUSH_MULTICALL(mc_cv);
SAVEGENERICSV(PL_firstgv);
SAVEGENERICSV(PL_secondgv);
PL_firstgv = MUTABLE_GV(SvREFCNT_inc(
gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV)
));
PL_secondgv = MUTABLE_GV(SvREFCNT_inc(
gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV)
));
/* make sure the GP isn't removed out from under us for
* the SAVESPTR() */
save_gp(PL_firstgv, 0);
save_gp(PL_secondgv, 0);
/* we don't want modifications localized */
GvINTRO_off(PL_firstgv);
GvINTRO_off(PL_secondgv);
SAVEGENERICSV(GvSV(PL_firstgv));
SvREFCNT_inc(GvSV(PL_firstgv));
SAVEGENERICSV(GvSV(PL_secondgv));
SvREFCNT_inc(GvSV(PL_secondgv));
for (i = 0; i < maxitems; ++i)
{
SV **j;
SV *olda = GvSV(PL_firstgv), *oldb = GvSV(PL_secondgv);
SV **svp = av_fetch(list1, i, FALSE);
GvSV(PL_firstgv) = SvREFCNT_inc_simple_NN(svp ? *svp : &PL_sv_undef);
svp = av_fetch(list2, i, FALSE);
GvSV(PL_secondgv) = SvREFCNT_inc_simple_NN(svp ? *svp : &PL_sv_undef);
SvREFCNT_dec(olda);
SvREFCNT_dec(oldb);
MULTICALL;
for (j = PL_stack_base+1; j <= PL_stack_sp; ++j)
av_push(rc, newSVsv(*j));
}
( run in 0.530 second using v1.01-cache-2.11-cpan-5511b514fd6 )