1 module yyd.alg;
2 
3 import std.meta : AliasSeq;
4 
5 public import yyd.y;
6 
7 
8 // Algorithmic mixin templates
9 
10 template conditional(alias cond, alias _if, alias _else) 
11 {
12     static if(cond) {
13         alias conditional = _if;
14     } else {
15         alias conditional = _else;
16     }
17 }
18 
19 mixin template _conditional(alias cond, alias _if, alias _else) 
20 {
21     static if(cond) {
22         mixin _if!();
23     } else {
24         mixin _else!();
25     }
26 }
27 
28 mixin template _conditionalm(alias cond, alias _if, alias _else) 
29 {
30     mixin cond!() c;
31     static if(_y!c) {
32         mixin _if!();
33     } else {
34         mixin _else!();
35     }
36 }
37 
38 mixin template eachApply(alias T,alias F) 
39 {
40     static foreach(t;T) {
41         mixin F!(t);
42     }
43 }
44 
45 mixin template eachPairApply(alias T,alias F) 
46 {
47     static foreach(k,v;T) {
48         mixin F!(k,v);
49     }
50 }
51 
52 mixin template eachIndexApply(alias T,alias F) 
53 {
54     static foreach(i;0..T.length) {
55         mixin F!(i,T[i]);
56     }
57 }
58 
59 mixin template _mapApply(alias F,T...) 
60 if (T.length == 0) 
61 {}
62 
63 mixin template _mapApply(alias F,T...) 
64 if (T.length == 1) 
65 {
66     mixin F!(T[0]) _first;
67     alias _ = _y!_first;
68 }
69 
70 mixin template _mapApply(alias F,T...) 
71 if (T.length > 1) 
72 {
73     mixin F!(T[0]) _first;
74     mixin _mapApply!(F,T[1..$]) _next;
75     alias _ = AliasSeq!(_y!_first,_y!_next);
76 }
77 
78 unittest {
79     mixin _mapApply!(_identity,"Test","Test2") m;
80     static assert(_y!m == AliasSeq!("Test","Test2"));
81 }
82 
83 unittest {
84     import yyd.arith;
85 
86     mixin _partialm!(_add,1) _a;
87 
88     static assert( ( _a._!2 )._ == 3);
89     static assert( _yy!( _a, 2 ) == 3 );
90     
91     //alias _b = _a._;
92     alias _b = _y!_a; // wont work yet it tries to instance the template without its args
93     static assert( _y!( _b!1 ) == 2);
94     static assert ( _yy!( _b, 1 ) == 2 );
95 
96 }
97 
98 unittest {
99     import yyd.arith;
100 
101     mixin _mpartial!(add,1) _a;
102     mixin _a._!(2) _b;
103     static assert(_y!_b == 3);
104 
105 }
106 
107 unittest {
108     import yyd.arith;
109     mixin template addOne(alias T) {
110         alias _ = add!(1,T);
111     }
112     mixin _mapApply!(addOne,1,2,3) m;
113     static assert(_y!m == AliasSeq!(2,3,4));
114 }
115