@@ -185,6 +185,56 @@ V unref(V)(V value)
185185 return value;
186186}
187187
188+ private template autoExpandAndForwardElem (alias value)
189+ {
190+ import core.lifetime : move;
191+ enum isLazy = __traits(isRef, value) || __traits(isOut, value) || __traits(isLazy, value);
192+ private template autoExpandAndForwardElem (size_t i)
193+ {
194+ alias T = typeof (value.expand[i]);
195+ static if (isRef! T)
196+ {
197+ ref autoExpandAndForwardElem ()
198+ {
199+ return * value.expand[i].__ptr;
200+ }
201+ }
202+ else
203+ {
204+ static if (isLazy)
205+ @property ref autoExpandAndForwardElem(){ pragma (inline, true ); return value.expand[i]; }
206+ else
207+ static if (is (typeof (move(value.expand[i]))))
208+ @property auto autoExpandAndForwardElem(){ pragma (inline, true ); return move (value.expand[i]); }
209+ else
210+ @property auto autoExpandAndForwardElem(){ pragma (inline, true ); return value.expand[i]; }
211+ }
212+ }
213+ }
214+
215+ template autoExpandAndForward (alias value)
216+ if (is (typeof (value) : RefTuple! Types, Types... ))
217+ {
218+ import mir.internal.utility: Iota;
219+ import std.meta : staticMap;
220+ alias autoExpandAndForward = staticMap! (autoExpandAndForwardElem! value, Iota! (value.expand.length));
221+ }
222+
223+ version (mir_core_test) unittest
224+ {
225+ long v;
226+ auto tup = refTuple(v._ref, 2.3 );
227+
228+ auto f (ref long a, double b)
229+ {
230+ assert (b == 2.3 );
231+ assert (a == v);
232+ assert (&a == &v);
233+ }
234+
235+ f(autoExpandAndForward! tup);
236+ }
237+
188238private string joinStrings ()(string [] strs)
189239{
190240 if (strs.length)
@@ -223,8 +273,8 @@ template adjoin(fun...) if (fun.length && fun.length <= 26)
223273 {
224274 template _adjoin (size_t i)
225275 {
226- static if (__traits(compiles, &(fun[i](staticMap ! (copyArg, args) ))))
227- enum _adjoin = " Ref!(typeof(fun[" ~ i.stringof ~ " ](staticMap!(copyArg, args) )))(fun[" ~ i.stringof ~ " ](args)), " ;
276+ static if (__traits(compiles, &(fun[i](forward ! args))))
277+ enum _adjoin = " Ref!(typeof(fun[" ~ i.stringof ~ " ](forward! args)))(fun[" ~ i.stringof ~ " ](args)), " ;
228278 else
229279 enum _adjoin = " fun[" ~ i.stringof ~ " ](args), " ;
230280 }
@@ -253,7 +303,7 @@ template adjoin(fun...) if (fun.length && fun.length <= 26)
253303 alias f = pipe! (adjoin! (" a" , " a * a" ), " a[0]" );
254304 static assert (is (typeof (f(3 )) == int ));
255305 auto d = 4 ;
256- static assert (is (typeof (f(d)) == int ));
306+ static assert (is (typeof (f(d)) == Ref ! int ));
257307}
258308
259309@safe version(mir_core_test) unittest
@@ -608,7 +658,7 @@ private template _pipe(size_t n)
608658 enum _pipe = " f[" ~ i.stringof ~ " ](" ~ ._pipe! i ~ " )" ;
609659 }
610660 else
611- enum _pipe = " args" ;
661+ enum _pipe = " forward! args" ;
612662}
613663
614664private template _unpipe (alias fun)
0 commit comments