@@ -185,6 +185,59 @@ V unref(V)(V value)
185185 return value;
186186}
187187
188+ private template autoExpandAndForwardElem (alias value)
189+ {
190+
191+ }
192+
193+ template autoExpandAndForward (alias value)
194+ if (is (typeof (value) : RefTuple! Types, Types... ))
195+ {
196+
197+ import core.lifetime : move;
198+ enum isLazy = __traits(isRef, value) || __traits(isOut, value) || __traits(isLazy, value);
199+ template autoExpandAndForwardElem (size_t i)
200+ {
201+ alias T = typeof (value.expand[i]);
202+ static if (isRef! T)
203+ {
204+ ref autoExpandAndForwardElem ()
205+ {
206+ return * value.expand[i].__ptr;
207+ }
208+ }
209+ else
210+ {
211+ static if (isLazy)
212+ @property ref autoExpandAndForwardElem(){ pragma (inline, true ); return value.expand[i]; }
213+ else
214+ static if (is (typeof (move(value.expand[i]))))
215+ @property auto autoExpandAndForwardElem(){ pragma (inline, true ); return move (value.expand[i]); }
216+ else
217+ @property auto autoExpandAndForwardElem(){ pragma (inline, true ); return value.expand[i]; }
218+ }
219+ }
220+
221+ import mir.internal.utility: Iota;
222+ import std.meta : staticMap;
223+ alias autoExpandAndForward = staticMap! (autoExpandAndForwardElem, Iota! (value.expand.length));
224+ }
225+
226+ version (mir_core_test) unittest
227+ {
228+ long v;
229+ auto tup = refTuple(v._ref, 2.3 );
230+
231+ auto f (ref long a, double b)
232+ {
233+ assert (b == 2.3 );
234+ assert (a == v);
235+ assert (&a == &v);
236+ }
237+
238+ f(autoExpandAndForward! tup);
239+ }
240+
188241private string joinStrings ()(string [] strs)
189242{
190243 if (strs.length)
@@ -223,8 +276,8 @@ template adjoin(fun...) if (fun.length && fun.length <= 26)
223276 {
224277 template _adjoin (size_t i)
225278 {
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)), " ;
279+ static if (__traits(compiles, &(fun[i](forward ! args))))
280+ enum _adjoin = " Ref!(typeof(fun[" ~ i.stringof ~ " ](forward! args)))(fun[" ~ i.stringof ~ " ](args)), " ;
228281 else
229282 enum _adjoin = " fun[" ~ i.stringof ~ " ](args), " ;
230283 }
@@ -253,7 +306,7 @@ template adjoin(fun...) if (fun.length && fun.length <= 26)
253306 alias f = pipe! (adjoin! (" a" , " a * a" ), " a[0]" );
254307 static assert (is (typeof (f(3 )) == int ));
255308 auto d = 4 ;
256- static assert (is (typeof (f(d)) == int ));
309+ static assert (is (typeof (f(d)) == Ref ! int ));
257310}
258311
259312@safe version(mir_core_test) unittest
@@ -608,7 +661,7 @@ private template _pipe(size_t n)
608661 enum _pipe = " f[" ~ i.stringof ~ " ](" ~ ._pipe! i ~ " )" ;
609662 }
610663 else
611- enum _pipe = " args" ;
664+ enum _pipe = " forward! args" ;
612665}
613666
614667private template _unpipe (alias fun)
0 commit comments