Sort-Key

 view release on metacpan or  search on metacpan

Key.xs  view on Meta::CPAN


    if(!(SvROK(gen) && SvTYPE(SvRV(gen))==SVt_PVCV))
       croak("wrong argument type, subroutine reference required");

    if (items != 1)
	croak("not enough arguments, array reference required");

    if (SvROK(ST(offset)) && SvTYPE(SvRV(ST(offset)))==SVt_PVAV)
	values = (AV*)SvRV(ST(offset));
    else croak("wrong argument type, array reference required");

    if ((len=av_len(values)+1)) {
	/* warn("ix=%d\n", ix); */
	if (SvMAGICAL(values) || AvREIFY(values)) {
	    int i;
	    magic_values = values;
	    values = (AV*)sv_2mortal((SV*)newAV());
	    av_extend(values, len-1);
	    for (i=0; i<len; i++) {
		SV **currentp = av_fetch(magic_values, i, 0);
		av_store( values, i,
			  ( currentp
			    ? SvREFCNT_inc(*currentp)
			    : newSV(0) ) );
	    }
	}
	
	_multikeysort(aTHX_ types, gen, post, AvARRAY(values), 0, 0, len);
	
	if (magic_values) {
	    int i;
	    SV **values_array = AvARRAY(values);
	    for(i=0; i<len; i++) {
		SV *current = values_array[i];
		if (!current) current = &PL_sv_undef;
		if (!av_store(magic_values, i, SvREFCNT_inc(current)))
		    SvREFCNT_dec(current);
	    }
	}
    }
    PUTBACK;
}


MODULE = Sort::Key		PACKAGE = Sort::Key		
PROTOTYPES: ENABLE

void
keysort(SV *keygen, ...)
PROTOTYPE: &@
ALIAS:
    lkeysort = 1
    nkeysort = 2
    ikeysort = 3
    ukeysort = 4
    rkeysort = 128
    rlkeysort = 129
    rnkeysort = 130
    rikeysort = 131
    rukeysort = 132
PPCODE:
    items--;
    if (items) {
	_keysort(aTHX_ ix, keygen, 0, 1, ax, items);
        SPAGAIN;
	SP = &ST(items-1);
    }


void
keysort_inplace(SV *keygen, AV *values)
PROTOTYPE: &\@
PREINIT:
    AV *magic_values=0;
    int len;
ALIAS:
    lkeysort_inplace = 1
    nkeysort_inplace = 2
    ikeysort_inplace = 3
    ukeysort_inplace = 4
    rkeysort_inplace = 128
    rlkeysort_inplace = 129
    rnkeysort_inplace = 130
    rikeysort_inplace = 131
    rukeysort_inplace = 132
PPCODE:
    if ((len=av_len(values)+1)) {
	/* warn("ix=%d\n", ix); */
	if (SvMAGICAL(values) || AvREIFY(values)) {
	    int i;
	    magic_values = values;
	    values = (AV*)sv_2mortal((SV*)newAV());
	    av_extend(values, len-1);
	    for (i=0; i<len; i++) {
		SV **currentp = av_fetch(magic_values, i, 0);
		av_store( values, i,
			  ( currentp
			    ? SvREFCNT_inc(*currentp)
			    : newSV(0) ) );
	    }
	}
	_keysort(aTHX_ ix, keygen, AvARRAY(values), 0, 0, len);
        SPAGAIN;
	if (magic_values) {
	    int i;
	    SV **values_array = AvARRAY(values);
	    for(i=0; i<len; i++) {
		SV *current = values_array[i];
		if (!current) current = &PL_sv_undef;
		if (!av_store(magic_values, i, SvREFCNT_inc(current)))
		    SvREFCNT_dec(current);
	    }
	}
    }

void
_sort(...)
PROTOTYPE: @
ALIAS:
    lsort = 1
    nsort = 2
    isort = 3
    usort = 4
    rsort = 128
    rlsort = 129
    rnsort = 130
    risort = 131
    rusort = 132
PPCODE:
    if (items) {
	_keysort(aTHX_ ix, 0, 0, 0, ax, items);
        SPAGAIN;
	SP = &ST(items-1);
    }

void
_sort_inplace(AV *values)
PROTOTYPE: \@
PREINIT:
    AV *magic_values=0;
    int len;
ALIAS:
    lsort_inplace = 1
    nsort_inplace = 2
    isort_inplace = 3
    usort_inplace = 4
    rsort_inplace = 128
    rlsort_inplace = 129
    rnsort_inplace = 130
    risort_inplace = 131
    rusort_inplace = 132
PPCODE:
    if ((len=av_len(values)+1)) {
	/* warn("ix=%d\n", ix); */
	if (SvMAGICAL(values) || AvREIFY(values)) {
	    int i;
	    magic_values = values;
	    values = (AV*)sv_2mortal((SV*)newAV());
	    av_extend(values, len-1);
	    for (i=0; i<len; i++) {
		SV **currentp = av_fetch(magic_values, i, 0);
		av_store( values, i,
			  ( currentp
			    ? SvREFCNT_inc(*currentp)
			    : newSV(0) ) );
	    }
	}

	_keysort(aTHX_ ix, 0, AvARRAY(values), 0, 0, len);
        SPAGAIN;
	if (magic_values) {
	    int i;
	    SV **values_array = AvARRAY(values);
	    for(i=0; i<len; i++) {
		SV *current = values_array[i];
		if (!current) current = &PL_sv_undef;
		if (!av_store(magic_values, i, SvREFCNT_inc(current)))
		    SvREFCNT_dec(current);
	    }
	}
    }


PROTOTYPES: DISABLE

CV *
_multikeysorter(SV *types, SV *gen, SV *post)
PREINIT:
    AV *defaults;
CODE:
    if (!SvOK(types) || sv_len(types)<1)
	croak("invalid packed types argument");
    RETVAL = newXS(0, &XS_Sort__Key__multikeysort, __FILE__);
    defaults = (AV*)sv_2mortal((SV*)newAV());
    av_store(defaults, 0, newSVsv(types));
    av_store(defaults, 1, newSVsv(gen));
    av_store(defaults, 2, newSVsv(post));
    _xclosure_make(aTHX_ RETVAL, defaults);
    if (!SvOK(gen))
	sv_setpv((SV*)RETVAL, "&@");
OUTPUT:
    RETVAL

CV *
_multikeysorter_inplace(SV *types, SV *gen, SV *post)
PREINIT:
    AV *defaults;
CODE:
    if (!SvOK(types) || sv_len(types)<1)
	croak("invalid packed types argument");
    RETVAL = newXS(0, &XS_Sort__Key__multikeysort_inplace, __FILE__);
    defaults = (AV*)sv_2mortal((SV*)newAV());



( run in 0.639 second using v1.01-cache-2.11-cpan-5511b514fd6 )