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 folds - extension of std.typecons;
7 */
8 module stribog.meta.fold;
9 
10 import stribog.meta.base;
11 
12 /**
13 *   Static version of std.algorithm.reduce (or fold). Expects that $(B F)
14 *   takes accumulator as first argument and a value as second argument.
15 *
16 *   First value of $(B T) have to be a initial value of accumulator.
17 */
18 template staticFold(alias F, T...)
19 {
20     static if(T.length == 0) // invalid input
21     {
22         alias staticFold = ExpressionList!(); 
23     }
24     else static if(T.length == 1)
25     {
26         static if(is(typeof(T[0])) && !is(typeof(T[0]) == void))
27             enum staticFold = T[0];
28         else
29             alias staticFold = T[0];
30     }
31     else 
32     {
33         alias staticFold = staticFold!(F, F!(T[0], T[1]), T[2 .. $]);
34     }
35 }
36 /// Example
37 unittest
38 {
39     template summ(T...)
40     {
41         enum summ = T[0] + T[1];
42     }
43     
44     static assert(staticFold!(summ, 0, 1, 2, 3, 4) == 10);
45     
46     template preferString(T...)
47     {
48         static if(is(T[0] == string))
49             alias preferString = T[0];
50         else
51             alias preferString = T[1];
52     }
53     
54     static assert(is(staticFold!(preferString, void, int, string, bool) == string));
55     static assert(is(staticFold!(preferString, void, int, double, bool) == bool));
56 }