Empowering foreach with multiple aggregates

Downs default_357-line at yahoo.de
Sun Sep 9 04:32:13 PDT 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This works, right now, but it requires a kind of abuse of the foreach
callback system. :D

xt4100 ~ $ cat foo2.d && gdc foo2.d -o foo2 && ./foo2
import std.stdio;

struct pairiter(T, U) {
  T[] first; U[] second;
  int opApply(int delegate(ref T, ref U) dg) {
    for (int i=0; i<first.length; ++i) {
      auto res=dg(first[i], second[i]);
      if (res) return res;
    }
    return 0;
  }
}

pairiter!(T, U) pair(T, U)(T[] a, U[] b) {
  assert(a.length==b.length);
  return pairiter!(T, U)(a, b);
}

void main() {
  char[] dst=new char[6]; char[] src="foobar";
  foreach (ref d, ref s; pair(dst, src)) {
    d=s+1;
  }
  writefln(dst);
}
gppcbs


Here's a version that works with arbitrary foreachable things (uses
scrapple.tools.stackthreads):

xt4100 ~ $ cat foo2.d && rebuild foo2 && ./foo2
module foo2;
import std.stdio;
import tools.stackthreads;

template isArray(T) { const bool isArray=false; }
template isArray(T: T[]) { const bool isArray=true; }

import std.traits;
template IT(T) { // itertype
  static if(isArray!(T)) alias typeof(T[0]) IT;
  else alias ParameterTypeTuple!(
    ParameterTypeTuple!(
      typeof(&T.init.opApply)
    )[0]
  )[$-1] IT;
}

struct pairiter(T, U) {
  T first; U second;
  int opApply(int delegate(ref IT!(T), ref IT!(U)) dg) {
    auto gen=new class Generator!(IT!(T)*) { void generate() {
      foreach (ref elem; first) yield (&elem);
    } };
    foreach (elem2; second) {
      auto elem1=gen();
      auto res=dg(*elem1, elem2);
      if (res) return res;
    }
    return 0;
  }
}

pairiter!(T, U) pair(T, U)(T a, U b) {
  return pairiter!(T, U)(a, b);
}

struct strng {
  string st;
  int opApply(int delegate(ref char) dg) {
    foreach (ref ch; st) {
      auto res=dg(ch); if (res) return res;
    }
    return 0;
  }
}

void main() {
  char[] dst=new char[6]; char[] src="foobar";
  foreach (ref d, ref s; pair(dst, strng(src))) {
    d=s+1;
  }
  writefln(dst);
}
gppcbs

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFG49m9pEPJRr05fBERApmEAJ9KwyXbsEOZ5plZwDqjw+BXvNU/8gCbB2b9
37UFe1OLUIalwF4gSNlfV0k=
=eYwJ
-----END PGP SIGNATURE-----



More information about the Digitalmars-d mailing list