Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implement unzip_by which is implemented List::UtilsBy version 0.9.

  • Loading branch information...
commit 2aee1d09d11a419056bbe9e466d1c2909843720f 1 parent b377382
@syohex authored
Showing with 63 additions and 0 deletions.
  1. +1 −0  lib/List/UtilsBy/XS.pm
  2. +62 −0 xs-src/UtilsBy.xs
View
1  lib/List/UtilsBy/XS.pm
@@ -25,6 +25,7 @@ our @EXPORT_OK = qw(
count_by
zip_by
+ unzip_by
extract_by
View
62 xs-src/UtilsBy.xs
@@ -539,6 +539,68 @@ CODE:
}
void
+unzip_by (code, ...)
+ SV *code
+PROTOTYPE: &@
+CODE:
+{
+ dSP;
+ SV **args = &PL_stack_base[ax];
+ AV *tmps, *retvals;
+ I32 i, j, count;
+ I32 len, initialized_num = -1;
+
+ if (items <= 1) {
+ XSRETURN_EMPTY;
+ }
+
+ retvals = (AV *)sv_2mortal((SV *)newAV());
+
+ SAVESPTR(GvSV(PL_defgv));
+
+ for (i = 1; i < items; i++) {
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(sp);
+ XPUSHs(sv_2mortal(newSVsv(args[i])));
+ PUTBACK;
+
+ GvSV(PL_defgv) = args[i];
+ count = call_sv(code, G_ARRAY);
+
+ SPAGAIN;
+
+ for (j = 0; j < count; j++) {
+ AV *tmps;
+ SV *ret = newSVsv(POPs);
+
+ if (j > initialized_num) {
+ tmps = newAV();
+ av_push(tmps, ret);
+ av_push(retvals, newRV((SV*)tmps));
+
+ initialized_num++;
+ } else {
+ tmps = (AV *)SvRV((SV*)*av_fetch(retvals, j, 0));
+ av_push(tmps, ret);
+ }
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
+
+ len = av_len(retvals) + 1;
+ for (i = 0; i < len; i++) {
+ ST(i) = *av_fetch(retvals, i, 0);
+ }
+
+ XSRETURN(len);
+}
+
+void
extract_by (code, ...)
SV *code
PROTOTYPE: &\@
Please sign in to comment.
Something went wrong with that request. Please try again.