[Issue 4085] Steps toward a static foreach
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sun Jun 6 07:09:46 PDT 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4085
--- Comment #1 from bearophile_hugs at eml.cc 2010-06-06 07:09:44 PDT ---
// Until bug 4085 gets fixed, I use something similar to this.
// I suggest to not add this to Phobos because it
// will become useless when bug 4085 is partially of fully fixed.
import std.typetuple: TypeTuple;
import std.traits: isArray;
version(unittest) {
import std.string: split; // for arrayToTypeTuple!() unittests
}
/****************************************
Converts at compile time an enum array into a TypeTuple that
contains the same items.
Example:
--------
foreach (i; arrayToTypeTuple!([1, 2]))
static assert(i > 0);
--------
*/
template arrayToTypeTuple(alias items) {
static assert (isArray!(typeof(items)));
static if (items == null || items.length == 0) // bug 4284
alias TypeTuple!() arrayToTypeTuple;
else
alias TypeTuple!(items[0], arrayToTypeTuple!(items[1..$]))
arrayToTypeTuple;
}
unittest { // Tests of arrayToTypeTuple!()
string[] items;
foreach (s; arrayToTypeTuple!(split(""))) {
static assert(s.length > 0);
items ~= s;
}
assert(items.length == 0);
items.length = 0;
foreach (s; arrayToTypeTuple!(split("foo"))) {
static assert(s.length > 0);
items ~= s;
}
assert(items == ["foo"]);
items.length = 0;
foreach (s; arrayToTypeTuple!(split("foo bar red"))) {
static assert(s.length > 0);
items ~= s;
}
assert(items == ["foo", "bar", "red"]);
foreach (i; arrayToTypeTuple!([1, 2]))
static assert(i > 0);
} // End tests of arrayToTypeTuple!()
/****************************************
Template, similar to iota(), but generates a tuple at compile time.
Useful for "static foreach" loops, where range extrema are compile time
constants:
-----------
foreach (i; Iota!(3))
a[i] = b[i];
// becomes unrolled and compiled as:
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
-----------
*/
template Iota(int stop) {
static if (stop <= 0)
alias TypeTuple!() Iota;
else
alias TypeTuple!(Iota!(stop-1), stop-1) Iota;
}
/// ditto
template Iota(int start, int stop) {
static if (stop <= start)
alias TypeTuple!() Iota;
else
alias TypeTuple!(Iota!(start, stop-1), stop-1) Iota;
}
/// ditto
template Iota(int start, int stop, int step) {
static assert(step != 0, "Iota: step must be != 0");
static if (step > 0) {
static if (stop <= start)
alias TypeTuple!() Iota;
else
alias TypeTuple!(Iota!(start, stop-step, step), stop-step) Iota;
} else {
static if (stop >= start)
alias TypeTuple!() Iota;
else
alias TypeTuple!(Iota!(start, stop-step, step), stop-step) Iota;
}
} // End Iota!(a,b,c)
unittest { // Tests of Iota!()
static assert(Iota!(0).length == 0);
int[] a;
foreach (n; Iota!(5))
a ~= n;
assert(a == [0, 1, 2, 3, 4]);
a.length = 0;
foreach (n; Iota!(-5))
a ~= n;
assert(a == new int[0]);
a.length = 0;
foreach (n; Iota!(4, 7))
a ~= n;
assert(a == [4, 5, 6]);
a.length = 0;
foreach (n; Iota!(-1, 4))
a ~= n;
static assert(Iota!(-1, 4).length == 5);
assert(a == [-1, 0, 1, 2, 3]);
a.length = 0;
foreach (n; Iota!(4, 2))
a ~= n;
assert(a == new int[0]);
a.length = 0;
foreach (n; Iota!(0, 10, 2))
a ~= n;
assert(a == [0, 2, 4, 6, 8]);
a.length = 0;
foreach (n; Iota!(3, 15, 3))
a ~= n;
assert(a == [3, 6, 9, 12]);
a.length = 0;
foreach (n; Iota!(15, 3, 1))
a ~= n;
assert(a == new int[0]);
a.length = 0;
foreach (n; Iota!(10, 0, -1))
a ~= n;
assert(a == [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);
a.length = 0;
foreach (n; Iota!(15, 3, -2))
a ~= n;
assert(a == [15, 13, 11, 9, 7, 5]);
static assert(!is(typeof( Iota!(15, 3, 0) ))); // stride = 0 statically
asserts
} // End tests of Iota!()
void main() {}
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list