Data-Swap

 view release on metacpan or  search on metacpan

Swap.xs  view on Meta::CPAN

	}

	return av;
}

STATIC void install_backrefs(pTHX_ SV *sv, AV *backrefs) {
	if (!backrefs)
		return;

#if BACKREFS_IN_HV
	if (SvTYPE(sv) == SVt_PVHV) {
		AV **const avp = Perl_hv_backreferences_p(aTHX_ (HV *) sv);
		*avp = backrefs;
		return;
	}
#endif

	sv_magic(sv, (SV *) backrefs, PERL_MAGIC_backref, NULL, 0);
}

STATIC AV *sv_move(pTHX_ SV *dst, SV *src, AV *br)
{
	AV *obr = extract_backrefs(aTHX_ src);

#if (PERL_COMBI_VERSION >= 5009003)
	dst->sv_u = src->sv_u;

	if (SvTYPE(src) == SVt_IV)
		SvANY(dst) = (XPVIV *) ((char *) &dst->sv_u.svu_iv
				- STRUCT_OFFSET(XPVIV, xiv_iv));
#if (PERL_COMBI_VERSION < 5011000)
	else if (SvTYPE(src) == SVt_RV)
		SvANY(dst) = &dst->sv_u.svu_rv;
#endif
	else
#endif
		SvANY(dst) = SvANY(src);

	SvFLAGS(dst) = (SvFLAGS(dst) & CONTAINER_FLAGS) |
			(SvFLAGS(src) & ~CONTAINER_FLAGS);

	install_backrefs(aTHX_ dst, br);

	return obr;
}


MODULE = Data::Swap  PACKAGE = Data::Swap

PROTOTYPES: DISABLE

BOOT:
	CvLVALUE_on(get_cv("Data::Swap::deref", TRUE));

void
deref(...)
    PREINIT:
	I32 i, n = 0;
	I32 sref;
	SV *sv;
    PPCODE:
	sref = (GIMME == G_SCALAR) && (PL_op->op_flags & OPf_REF);
	for (i = 0; i < items; i++) {
		if (!SvROK(ST(i))) {
			STRLEN z;
			if (SvOK(ST(i)))
				Perl_croak(aTHX_ DA_DEREF_ERR, SvPV(ST(i), z));
			if (ckWARN(WARN_UNINITIALIZED))
				custom_warn_uninit("deref");
			if (sref)
				return;
			continue;
		}
		sv = SvRV(ST(i));
		if (sref) {
			PUSHs(sv);
			PUTBACK;
			return;
		}
		switch (SvTYPE(sv)) {
			I32 x;
		case SVt_PVAV:
			if (!(x = av_len((AV *) sv) + 1))
				continue;
			SP += x;
			break;
		case SVt_PVHV:
			if (!(x = HvKEYS(sv)))
				continue;
			SP += x * 2;
			break;
		case SVt_PVCV:
			Perl_croak(aTHX_ "Can't deref subroutine reference");
		case SVt_PVFM:
			Perl_croak(aTHX_ "Can't deref format reference");
		case SVt_PVIO:
			Perl_croak(aTHX_ "Can't deref filehandle reference");
		default:
			SP++;
		}
		ST(n++) = ST(i);
	}
	EXTEND(SP, 0);
	for (i = 0; n--; ) {
		SV *sv = SvRV(ST(n));
		I32 x = SvTYPE(sv);
		if (x == SVt_PVAV) {
			i -= x = AvFILL((AV *) sv) + 1;
			Copy(AvARRAY((AV *) sv), SP + i + 1, x, SV *);
		} else if (x == SVt_PVHV) {
			HE *entry;
			HV *hv = (HV *) sv;
			i -= x = hv_iterinit(hv) * 2;
			PUTBACK;
			while ((entry = hv_iternext(hv))) {
				sv = hv_iterkeysv(entry);
				SPAGAIN;
				SvREADONLY_on(sv);
				SP[++i] = sv;
				sv = hv_iterval(hv, entry);
				SPAGAIN;



( run in 0.559 second using v1.01-cache-2.11-cpan-71847e10f99 )