Algorithm-FastPermute
view release on metacpan or search on metacpan
multicall.h view on Meta::CPAN
/* multicall.h (version 1.0)
*
* Implements a poor-man's MULTICALL interface for old versions
* of perl that don't offer a proper one. Intended to be compatible
* with 5.6.0 and later.
*
*/
#ifdef dMULTICALL
#define REAL_MULTICALL
#else
#undef REAL_MULTICALL
/* In versions of perl where MULTICALL is not defined (i.e. prior
* to 5.9.4), Perl_pad_push is not exported either. It also has
* an extra argument in older versions; certainly in the 5.8 series.
* So we redefine it here.
*/
#ifndef AVf_REIFY
# ifdef SVpav_REIFY
# define AVf_REIFY SVpav_REIFY
# else
# error Neither AVf_REIFY nor SVpav_REIFY is defined
# endif
#endif
#ifndef AvFLAGS
# define AvFLAGS SvFLAGS
#endif
static void
multicall_pad_push(pTHX_ AV *padlist, int depth)
{
if (depth <= AvFILLp(padlist))
return;
{
SV** const svp = AvARRAY(padlist);
AV* const newpad = newAV();
SV** const oldpad = AvARRAY(svp[depth-1]);
I32 ix = AvFILLp((AV*)svp[1]);
const I32 names_fill = AvFILLp((AV*)svp[0]);
SV** const names = AvARRAY(svp[0]);
AV *av;
for ( ;ix > 0; ix--) {
if (names_fill >= ix && names[ix] != &PL_sv_undef) {
const char sigil = SvPVX(names[ix])[0];
if ((SvFLAGS(names[ix]) & SVf_FAKE) || sigil == '&') {
/* outer lexical or anon code */
av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]));
}
else { /* our own lexical */
SV *sv;
if (sigil == '@')
sv = (SV*)newAV();
else if (sigil == '%')
sv = (SV*)newHV();
else
sv = NEWSV(0, 0);
av_store(newpad, ix, sv);
SvPADMY_on(sv);
}
}
else if (IS_PADGV(oldpad[ix]) || IS_PADCONST(oldpad[ix])) {
av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]));
}
else {
/* save temporaries on recursion? */
SV * const sv = NEWSV(0, 0);
av_store(newpad, ix, sv);
SvPADTMP_on(sv);
}
}
av = newAV();
av_extend(av, 0);
av_store(newpad, 0, (SV*)av);
AvFLAGS(av) = AVf_REIFY;
av_store(padlist, depth, (SV*)newpad);
AvFILLp(padlist) = depth;
}
}
( run in 0.337 second using v1.01-cache-2.11-cpan-adec679a428 )