1 /** 2 * Copyright: © 2014-2015 Anton Gushcha 3 * License: Subject to the terms of the Boost 1.0 license as specified in LICENSE file 4 * Authors: Anton Gushcha <ncrashed@gmail.com> 5 * 6 * Template for aggregates members expection - extension of std.traits; 7 */ 8 module stribog.meta.iota; 9 10 import stribog.meta.base; 11 12 /** 13 * Template, similar to iota(), but generates a tuple at compile time. 14 * 15 * Useful for "static foreach" loops, where range extrema are compile time constants: 16 * ----------- 17 * foreach (i; Iota!(3)) 18 * a[i] = b[i]; 19 * 20 * // becomes unrolled and compiled as: 21 * a[0] = b[0]; 22 * a[1] = b[1]; 23 * a[2] = b[2]; 24 * ----------- 25 * 26 * Source: https://issues.dlang.org/show_bug.cgi?id=4085 27 */ 28 template Iota(int stop) { 29 static if (stop <= 0) 30 alias ExpressionList!() Iota; 31 else 32 alias ExpressionList!(Iota!(stop-1), stop-1) Iota; 33 } 34 35 /// ditto 36 template Iota(int start, int stop) { 37 static if (stop <= start) 38 alias ExpressionList!() Iota; 39 else 40 alias ExpressionList!(Iota!(start, stop-1), stop-1) Iota; 41 } 42 43 /// ditto 44 template Iota(int start, int stop, int step) { 45 static assert(step != 0, "Iota: step must be != 0"); 46 47 static if (step > 0) { 48 static if (stop <= start) 49 alias ExpressionList!() Iota; 50 else 51 alias ExpressionList!(Iota!(start, stop-step, step), stop-step) Iota; 52 } else { 53 static if (stop >= start) 54 alias ExpressionList!() Iota; 55 else 56 alias ExpressionList!(Iota!(start, stop-step, step), stop-step) Iota; 57 } 58 } // End Iota!(a,b,c) 59 60 unittest { // Tests of Iota!() 61 static assert(Iota!(0).length == 0); 62 63 int[] a; 64 65 foreach (n; Iota!(5)) 66 a ~= n; 67 assert(a == [0, 1, 2, 3, 4]); 68 69 a.length = 0; 70 foreach (n; Iota!(-5)) 71 a ~= n; 72 assert(a == new int[0]); 73 74 a.length = 0; 75 foreach (n; Iota!(4, 7)) 76 a ~= n; 77 assert(a == [4, 5, 6]); 78 79 a.length = 0; 80 foreach (n; Iota!(-1, 4)) 81 a ~= n; 82 static assert(Iota!(-1, 4).length == 5); 83 assert(a == [-1, 0, 1, 2, 3]); 84 85 a.length = 0; 86 foreach (n; Iota!(4, 2)) 87 a ~= n; 88 assert(a == new int[0]); 89 90 a.length = 0; 91 foreach (n; Iota!(0, 10, 2)) 92 a ~= n; 93 assert(a == [0, 2, 4, 6, 8]); 94 95 a.length = 0; 96 foreach (n; Iota!(3, 15, 3)) 97 a ~= n; 98 assert(a == [3, 6, 9, 12]); 99 100 a.length = 0; 101 foreach (n; Iota!(15, 3, 1)) 102 a ~= n; 103 assert(a == new int[0]); 104 105 a.length = 0; 106 foreach (n; Iota!(10, 0, -1)) 107 a ~= n; 108 assert(a == [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]); 109 110 a.length = 0; 111 foreach (n; Iota!(15, 3, -2)) 112 a ~= n; 113 assert(a == [15, 13, 11, 9, 7, 5]); 114 115 static assert(!is(typeof( Iota!(15, 3, 0) ))); // stride = 0 statically asserts 116 } // End tests of Iota!()