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     template doubleString(alias T) {
85         enum _ = T ~ T;
86     }
87     mixin _mapApply!(doubleString,"Test","Test2") m;
88     static assert(_y!m == AliasSeq!("TestTest","Test2Test2"));
89 }
90 
91 unittest {
92     import yyd.arith;
93 
94     mixin _partialm!(_add,1) _a;
95 
96     static assert( ( _a._!2 )._ == 3);
97     static assert( _yy!( _a, 2 ) == 3 );
98     
99     //alias _b = _a._;
100     alias _b = _y!_a; // wont work yet it tries to instance the template without its args
101     static assert( _y!( _b!1 ) == 2);
102     static assert ( _yy!( _b, 1 ) == 2 );
103 
104 }
105 
106 unittest {
107     import yyd.arith;
108 
109     mixin _mpartial!(add,1) _a;
110     mixin _a._!(2) _b;
111     static assert(_y!_b == 3);
112 
113 }
114 
115 unittest {
116     import yyd.arith;
117     mixin template addOne(alias T) {
118         alias _ = add!(1,T);
119     }
120     mixin _mapApply!(addOne,1,2,3) m;
121     static assert(_y!m == AliasSeq!(2,3,4));
122 }
123