aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sdlang/libinputvisitor/libInputVisitor.d
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdlang/libinputvisitor/libInputVisitor.d')
-rw-r--r--src/sdlang/libinputvisitor/libInputVisitor.d91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/sdlang/libinputvisitor/libInputVisitor.d b/src/sdlang/libinputvisitor/libInputVisitor.d
new file mode 100644
index 0000000..15c2ce8
--- /dev/null
+++ b/src/sdlang/libinputvisitor/libInputVisitor.d
@@ -0,0 +1,91 @@
+/++
+Copyright (C) 2012 Nick Sabalausky <http://semitwist.com/contact>
+
+This program is free software. It comes without any warranty, to
+the extent permitted by applicable law. You can redistribute it
+and/or modify it under the terms of the Do What The Fuck You Want
+To Public License, Version 2, as published by Sam Hocevar. See
+http://www.wtfpl.net/ for more details.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
+
+Everyone is permitted to copy and distribute verbatim or modified
+copies of this license document, and changing it is allowed as long
+as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. You just DO WHAT THE FUCK YOU WANT TO.
++/
+
+/++
+Should work with DMD 2.059 and up
+
+For more info on this, see:
+http://semitwist.com/articles/article/view/combine-coroutines-and-input-ranges-for-dead-simple-d-iteration
++/
+
+import core.thread;
+
+class InputVisitor(Obj, Elem) : Fiber
+{
+ bool started = false;
+ Obj obj;
+ this(Obj obj)
+ {
+ this.obj = obj;
+ super(&run);
+ }
+
+ private void run()
+ {
+ obj.visit(this);
+ }
+
+ private void ensureStarted()
+ {
+ if(!started)
+ {
+ call();
+ started = true;
+ }
+ }
+
+ // Member 'front' must be a function due to DMD Issue #5403
+ private Elem _front;
+ @property Elem front()
+ {
+ ensureStarted();
+ return _front;
+ }
+
+ void popFront()
+ {
+ ensureStarted();
+ call();
+ }
+
+ @property bool empty()
+ {
+ ensureStarted();
+ return state == Fiber.State.TERM;
+ }
+
+ void yield(Elem elem)
+ {
+ _front = elem;
+ Fiber.yield();
+ }
+}
+
+template inputVisitor(Elem)
+{
+ @property InputVisitor!(Obj, Elem) inputVisitor(Obj)(Obj obj)
+ {
+ return new InputVisitor!(Obj, Elem)(obj);
+ }
+}