1 module yyd.y; 2 3 private import std.meta : AliasSeq; 4 5 // Functional combinators 6 7 /** 8 * Identity 9 * Params: 10 * identity = 11 */ 12 mixin template _identity(alias T) 13 { 14 alias _ = T; 15 } 16 17 mixin template _identity(alias T,U...) 18 { 19 alias _ = T!U; 20 } 21 22 template identity(alias T) 23 { 24 alias identity = T; 25 } 26 27 auto ref identity(T)(inout ref T t) 28 { 29 return t; 30 } 31 32 mixin template _evaluate(alias T=identity) 33 { 34 enum _ = T; 35 } 36 37 template evaluate(alias T=identity) 38 { 39 enum evaluate = T; 40 } 41 42 43 /** 44 * Decombinators. 45 * These restore the original value where _ has been used as a replacement for eponymosity. 46 */ 47 48 /*mixin template __y() 49 { 50 static if(is(typeof(_))) { 51 alias _ = _; 52 } else { 53 } 54 }*/ 55 /* 56 template _y(alias T, V ...) 57 { 58 static if(is(typeof(T._))) { 59 static if( 60 is(typeof(T._.length)) 61 ) { // check if it's AliasSeq 62 alias _y = T._; 63 } else static if( 64 __traits(isTemplate,T._) 65 ) { 66 //mixin T!() _; 67 //alias _y = _y!(_); 68 //alias _y = _y!(T._!(V),V); 69 //static if (V.length == len) { 70 alias _y = _y!(T._!(V)); 71 //} else { 72 // alias _y = _y!(T._!(V[0..len]),V[len..$]); 73 //} 74 } else { 75 alias _y = _y!(T._,V); 76 } 77 } else { 78 alias _y = T; 79 } 80 } 81 */ 82 83 template _y(alias T) 84 { 85 static if(is(typeof(T._))) { 86 alias _y = T._; 87 } else { 88 // TODO check for eponymous template. The symbol would have a member with the same name as it's identifier. 89 alias _y = T; 90 } 91 } 92 93 /** 94 * Decombinator and instatiate T as template with given parameters V. 95 */ 96 template _yy(alias T,V...) 97 { 98 static if(is(typeof(T._))) { 99 alias _yy = _y!(T._!(V)); 100 } else { 101 alias _yy = _y!(T!(V)); 102 } 103 } 104 /** 105 * Same as _yy but instiate as mixin. 106 */ 107 mixin template _yyy(alias T,V...) 108 { 109 static if(is(typeof(T._))) { 110 mixin T._!(V); 111 } else { 112 mixin T!(V); 113 } 114 } 115 116 /*mixin template _yy_(alias T) 117 { 118 static if(is(typeof(T._))) { 119 alias _ ( V ... ) = () { 120 mixin T._!V; 121 }; 122 } else { 123 alias _ (V ... ) = () { 124 mixin T!V; 125 }; 126 } 127 }*/ 128 129 /** 130 * Create an alias to the instantiation of template T with parameters U 131 */ 132 mixin template _apply(alias T=identity,U...) 133 { 134 template _ () 135 { 136 alias _ = T!U; 137 } 138 } 139 140 /** 141 * Create an alias template that instantiates template T with a passed in argument. 142 */ 143 mixin template _call(alias T=identity) 144 { 145 alias _ (U...) = (U u) => T!u; 146 } 147 148 /** 149 * Create a template _ to form a "partial" version of a mixin template T with the first part of the 150 * supplied argument list, and the remainder as parameters to the created template. 151 */ 152 mixin template _partialm(alias T=_identity,U...) 153 { 154 template _ (V...) 155 { 156 mixin T!(U,V) _; 157 } 158 } 159 160 /** 161 * Create a template _ to form a "partial" version of template T with the last part of the 162 * supplied argument list, and the preceding parts as parameters to the created template. 163 */ 164 mixin template _rpartialm(alias T=_identity,U ...) 165 { 166 template _ (V ...) 167 { 168 mixin T!(V,U) _; 169 } 170 } 171 172 /** 173 * Same as _partial but creates a mixin template. 174 */ 175 mixin template _mpartial(alias T=identity, U ...) 176 { 177 mixin template _ (V ...) 178 { 179 alias _ = T!(U,V); 180 } 181 } 182 183 /** 184 * Create an alias template that is a partial version of template T with the first 185 * part of the argument list supplied as parameter U... and the remainder as 186 * parameters to the created template _ . 187 */ 188 mixin template _partial(alias T=identity, U ...) 189 { 190 template _ (V ...) 191 { 192 alias _ = T!(U,V); 193 } 194 } 195 196 mixin template _rpartial(alias T=_identity,U...) 197 { 198 template _ (V ...) 199 { 200 alias _ = T!(V,U); 201 } 202 } 203 204 /* 205 mixin template _partialf(alias T,U...) 206 { 207 alias _(V...) = (V v) => T(U,v); 208 } 209 210 mixin template _rpartialf(alias T,U...) { 211 alias _(V ...) = (V v) => T(v.U); 212 } 213 */ 214 215 mixin template _partialf(alias T=identity,U...) 216 { 217 auto _ (V ...) (V v) 218 { 219 return T(U,v); 220 } 221 //alias _ (V ...) = (V v) => T(U,v); 222 } 223 224 mixin template _rpartialf(alias T=identity,U...) 225 { 226 auto _ (V ...) (V v) 227 { 228 return T(v,U); 229 } 230 //alias _ (V ...) = (V v) => T(v,U); 231 } 232 233 mixin template _partialmf(alias T=identity,U...) 234 { 235 auto _ (V ...) (V v) 236 { 237 mixin T!(U,v) _; 238 return _y!_; 239 } 240 //alias _ (V ...) = (V v) => T(U,v); 241 } 242 243 mixin template _rpartialmf(alias T=identity,U...) 244 { 245 auto _ (V ...) (V v) 246 { 247 mixin T!(v,U) _; 248 return _y!_; 249 } 250 //alias _ (V ...) = (V v) => T(v,U); 251 } 252 253 254 unittest { 255 auto t1(string A,string B,string C)() { 256 return A ~ B ~ C; 257 } 258 259 mixin _partial!(t1,"First ","second ") p; 260 //enum result = _y!(p,"third"); 261 enum result = p._!"third"; 262 263 static assert (result == "First second third"); 264 } 265 266 unittest { 267 auto t1(string A,string B,string C)() { 268 return A ~ B ~ C; 269 } 270 271 mixin _rpartial!(t1,"First ","second") p; 272 //enum result = _y!(p,"third "); 273 enum result = _yy!(p,"third "); 274 275 static assert (result == "third First second"); 276 } 277 278 unittest { 279 template t1(string A,string B,string C) { 280 enum t1 = A ~ B ~ C; 281 } 282 283 mixin _partial!(t1,"First ") p; 284 //mixin _partial!(_y!(p,"second ")) q; 285 mixin _partial!(p._,"second ") q; 286 //enum result = q._!("third"); 287 enum result = _yy!(q,"third"); 288 289 static assert (result == "First second third"); 290 } 291 292 unittest { 293 template t1(string A,string B,string C) { 294 enum t1 = A ~ B ~ C; 295 } 296 297 mixin _partial!(t1,"First ") p; 298 mixin _partial!(p._,"second ") _p; 299 mixin _apply!(_p._,"third") _q; 300 //enum result = _q._!(); 301 enum result = _yy!(_q); 302 303 static assert (result == "First second third"); 304 } 305 306 unittest { 307 auto t1(string A,string B,string C) { 308 return A ~ B ~ C; 309 } 310 311 mixin _partialf!(t1,"First ") p; 312 //mixin _partialf!(p._,"second ") _p; 313 mixin _partialf!(_y!p,"second ") _p; 314 //enum result = _p._("third"); 315 enum result = _y!(_p)("third"); 316 317 static assert (result == "First second third"); 318 } 319 320 /** 321 * Embed a template into a lambda. 322 */ 323 template toFnc(alias op,V ...) 324 { 325 alias toFnc(T...) = (V v)=>op!T(v); 326 } 327 328 /** 329 * Mxin template decombinator into lambda. 330 */ 331 mixin template y__(alias op) 332 { 333 alias _ = () { 334 mixin op!(T) _; 335 return y!(_); 336 }; 337 } 338 339 template y_ (alias T) { 340 alias y_() = ()=>T!v; 341 } 342 343 mixin template _toFnc(alias op) 344 { 345 alias _ = toFnc!op; 346 } 347 348 mixin template _toFnc_m(alias op, V ...) 349 { 350 mixin toFnc_m!(op,V) _; 351 //alias _ = toFnc_m!(op,V); 352 } 353 354