in reply to Re^4: perl inline::c sorting problem
in thread perl inline::c sorting problem
I'd just steal the implementation from PP_sort.c. You have to also grab a couple of #defines:
use warnings; use Inline C => Config => NAME => 'IC_sort', CLEAN_AFTER_BUILD => 0, BUILD_NOISY => 1; use Inline C => <<'END_OF_C_CODE'; #define SvSIOK(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV)) == SVf_IOK) #define SvNSIV(sv) ( SvNOK(sv) ? SvNVX(sv) : ( SvSIOK(sv) ? SvIVX(sv) +: sv_2nv(sv) ) ) static I32 S_sv_ncmp(pTHX_ SV *a, SV *b) { const NV nv1 = SvNSIV(a); const NV nv2 = SvNSIV(b); return nv1 < nv2 ? -1 : nv1 > nv2 ? 1 : 0; } void test(AV* data) { I32 i; I32 arrayLen; SV** pvalue; if( SvTYPE( data ) != SVt_PVAV ) croak( "Requires an array ref ( type %d)\n", SvTYPE( data ) ); arrayLen = av_len(data); sortsv(AvARRAY(data),arrayLen+1, S_sv_ncmp); for (i = 0; i < arrayLen+1; i++) { pvalue = av_fetch(data,i,0); printf("%s \n", SvPV_nolen( *pvalue ) ); } } END_OF_C_CODE my $ref = [ 5.0e-5,4.2e-5,4.3e-5,4.4e-5,4.4e-5,4.2e-5,4.2e-5,4.0e-5]; test($ref);
That works! However, there is something I do not understand about:
#define SvNSIV(sv) ( SvNOK(sv) ? SvNVX(sv) : ( SvSIOK(sv) ? SvIVX(sv) +: sv_2nv(sv) ) ) ... const NV nv1 = SvNSIV(a);
If the value is an NV, it grabs it. But if it is an IV, it grabs the IV and assigns it to the NV without coercion. Seems to work okay for mixed ints and floats and I don't see any warnings, so I guess that's yet another mystery to put down to "the magic of XS".
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^6: perl inline::c sorting problem
by dalittle (Novice) on May 01, 2009 at 19:57 UTC | |
by BrowserUk (Patriarch) on May 02, 2009 at 06:38 UTC | |
|
Re^6: perl inline::c sorting problem (implicit coercion)
by tye (Sage) on May 02, 2009 at 04:26 UTC | |
by BrowserUk (Patriarch) on May 02, 2009 at 05:32 UTC | |
by syphilis (Archbishop) on May 03, 2009 at 10:08 UTC | |
by BrowserUk (Patriarch) on May 03, 2009 at 10:41 UTC |