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 }