From 5983bcc8de9ab7a23b3487a52eaba28d3c43a6a2 Mon Sep 17 00:00:00 2001 From: dukc Date: Fri, 24 Feb 2017 23:41:14 +0200 Subject: [PATCH 1/2] Since std.concurrency.Generator is a class already, I made it to implement std.range.interfaces.InputRange without having to call inputRangeObject(). --- std/concurrency.d | 88 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/std/concurrency.d b/std/concurrency.d index 397c9d76c82..5ecbb70488a 100644 --- a/std/concurrency.d +++ b/std/concurrency.d @@ -74,6 +74,14 @@ import std.traits; private { + import core.atomic; + import core.thread; + import core.sync.mutex; + import core.sync.condition; + import std.range.primitives; + import std.range.interfaces; + import std.traits; + template hasLocalAliasing(T...) { static if (!T.length) @@ -1496,7 +1504,8 @@ private interface IsGenerator {} * } * --- */ -class Generator(T) : Fiber, IsGenerator +class Generator(T) : + Fiber, IsGenerator, InputRange!T { /** * Initializes a generator object which is associated with a static @@ -1585,13 +1594,52 @@ class Generator(T) : Fiber, IsGenerator } /** - * Returns the most recently generated value. + * Returns the most recently generated value by shallow copy. */ final T front() @property { return *m_value; } + /** + * Returns the most recently generated value without excuting a copy + * contructor. Will not compile for element types defining a + * postblit, because Generator does not return by reference. + */ + final T moveFront() + { + static if (!hasElaborateCopyConstructor!T) + { + return front; + } + else + { + static assert(0, + "Fiber front is rvalue and thus cannot be moved when it defines a postblit."); + } + } + + final int opApply(scope int delegate(T) loopBody) + { + int broken; + for (; !empty; popFront()) + { + broken = loopBody(front); + if (broken) break; + } + return broken; + } + + final int opApply(scope int delegate(size_t, T) loopBody) + { + int broken; + for (size_t i; !empty; ++i, popFront()) + { + broken = loopBody(i, front); + if (broken) break; + } + return broken; + } private: T* m_value; } @@ -1624,6 +1672,7 @@ void yield(T)(T value) { import core.exception; import std.exception; + import std.range.interfaces; static void testScheduler(Scheduler s) { @@ -1661,6 +1710,7 @@ void yield(T)(T value) { tid.send(e); } + }); scheduler = null; } @@ -1668,7 +1718,41 @@ void yield(T)(T value) testScheduler(new ThreadScheduler); testScheduler(new FiberScheduler); } +/// +@system unittest +{ + import std.range; + + InputRange!int myIota = iota(10).inputRangeObject; + + myIota.popFront(); + myIota.popFront(); + assert(myIota.moveFront == 2); + assert(myIota.front == 2); + myIota.popFront(); + assert(myIota.front == 3); + + //can be assigned to std.range.interfaces.InputRange directly + myIota = new Generator!int( + { + foreach (i; 0 .. 10) yield(i); + }); + + myIota.popFront(); + myIota.popFront(); + assert(myIota.moveFront == 2); + assert(myIota.front == 2); + myIota.popFront(); + assert(myIota.front == 3); + + size_t[2] counter = [0, 0]; + foreach (i, unused; myIota) counter[] += [1, i]; + + assert(myIota.empty); + assert(counter == [7, 21]); +} +// MessageBox Implementation private { /* From 942da358c24081ec59821703bb0f450c2c6dc905 Mon Sep 17 00:00:00 2001 From: dukc Date: Tue, 27 Jun 2017 16:35:10 +0300 Subject: [PATCH 2/2] Some cleanup on imports and comments --- std/concurrency.d | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/std/concurrency.d b/std/concurrency.d index 5ecbb70488a..82eebdfd999 100644 --- a/std/concurrency.d +++ b/std/concurrency.d @@ -70,18 +70,11 @@ import core.sync.condition; import core.sync.mutex; import core.thread; import std.range.primitives; +import std.range.interfaces : InputRange; import std.traits; private { - import core.atomic; - import core.thread; - import core.sync.mutex; - import core.sync.condition; - import std.range.primitives; - import std.range.interfaces; - import std.traits; - template hasLocalAliasing(T...) { static if (!T.length) @@ -1602,8 +1595,8 @@ class Generator(T) : } /** - * Returns the most recently generated value without excuting a copy - * contructor. Will not compile for element types defining a + * Returns the most recently generated value without executing a + * copy contructor. Will not compile for element types defining a * postblit, because Generator does not return by reference. */ final T moveFront() @@ -1615,7 +1608,7 @@ class Generator(T) : else { static assert(0, - "Fiber front is rvalue and thus cannot be moved when it defines a postblit."); + "Fiber front is always rvalue and thus cannot be moved since it defines a postblit."); } } @@ -1672,7 +1665,6 @@ void yield(T)(T value) { import core.exception; import std.exception; - import std.range.interfaces; static void testScheduler(Scheduler s) { @@ -1710,7 +1702,6 @@ void yield(T)(T value) { tid.send(e); } - }); scheduler = null; } @@ -1752,7 +1743,6 @@ void yield(T)(T value) assert(counter == [7, 21]); } -// MessageBox Implementation private { /*