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 robins - extension of std.typecons; 7 */ 8 module stribog.meta.robin; 9 10 import stribog.meta.base; 11 import stribog.meta.map; 12 import stribog.meta.fold; 13 14 /** 15 * Compile-time variant of std.range.robin for expression ExpressionLists. 16 * 17 * Template expects $(B StrictExpressionList) list as parameter and returns 18 * new expression list where first element is from first expression ExpressionList, 19 * second element is from second ExpressionList and so on, until one of input ExpressionLists 20 * doesn't end. 21 */ 22 template staticRobin(SF...) 23 { 24 // Calculating minimum length of all ExpressionLists 25 private template minimum(T...) 26 { 27 enum length = T[1].expand.length; 28 enum minimum = T[0] > length ? length : T[0]; 29 } 30 31 enum minLength = staticFold!(minimum, size_t.max, SF); 32 33 private template robin(ulong i) 34 { 35 private template takeByIndex(alias T) 36 { 37 static if(!__traits(compiles, {enum takeByIndex = T.expand[i];})) 38 alias takeByIndex = T.expand[i]; 39 else 40 enum takeByIndex = T.expand[i]; 41 } 42 43 static if(i >= minLength) 44 { 45 alias robin = ExpressionList!(); 46 } 47 else 48 { 49 alias robin = ExpressionList!(staticMap!(takeByIndex, SF), robin!(i+1)); 50 } 51 } 52 53 alias staticRobin = robin!0; 54 } 55 /// Example 56 unittest 57 { 58 alias test = staticRobin!(StrictExpressionList!(int, int, int), StrictExpressionList!(float, float)); 59 static assert(is(test == ExpressionList!(int, float, int, float))); 60 61 alias test2 = staticRobin!(StrictExpressionList!(1, 2), StrictExpressionList!(3, 4, 5), StrictExpressionList!(6, 7)); 62 static assert([test2]== [1, 3, 6, 2, 4, 7]); 63 }