/*========================================================================== * newforeach.d * Written in the D Programming Language (http://www.digitalmars.com/d) */ /*************************************************************************** * * * * * Authors: William V. Baxter III * Date: 05 Jan 2008 * Copyright: (C) 2007 William Baxter */ //=========================================================================== module newforeach; import std.stdio; enum {BREAK=1,RETURN} alias string T; void do_something() { writefln(" Doing something"); } struct Apply(Args...) { alias void delegate(Args) LoopBody; LoopBody _loop_body; int* _ret = null; void _call(Args a) { if (_ret) *_ret = 0; _loop_body(a); // may set *_ret! } } class Class { T[] values; void opApply( Apply!(T) dg) { foreach(x; values) { //yield(dg, x); dg._call(x); if (dg._ret && *dg._ret) return; } } } void test(T[] obj_values) { auto obj = new Class; obj.values = obj_values; writefln("before foreach over %s", obj.values); //The user's foreach: //foreach(x; obj) { // writefln("x is ", x); // if (x=="two") break; // if (x=="three") return; // do_something; //} // Hypothetically generated foreach code: int _ret = 0; void _loop_body(/*ref*/ T x) { writefln("x is ", x); if (x=="two") { _ret = BREAK; return; } if (x=="three") { _ret = RETURN; return; } do_something; } obj.opApply( Apply!(T)(&_loop_body, &_ret) ); writefln("(_ret code: %s)", _ret); if (_ret==RETURN) return; writefln("after foreach"); } void main() { test(["one"[],"two", "three", "four"]); writefln; test(["four"[],"one", "three", "two"]); } //--- Emacs setup --- // Local Variables: // c-basic-offset: 4 // indent-tabs-mode: nil // End: