The problem statement is this code in Phobos (std.range.primitives):
private void doPut(R, E)(ref R r, auto ref E e)
{
static if(is(PointerTarget!R == struct))
enum usingPut = hasMember!(PointerTarget!R, "put");
else
enum usingPut = hasMember!(R, "put");
//...
}
Observe that the range r is always taken by reference where if range is a class instance or a pointer it makes no sense to add an extra indirection.
Moreover ref Range* and ref Range instantiations should be exactly the same code as (would be) Range* so there is an opportunity to debloat by factor of 2 by merging them.
In simple cases presented compiler was able to optimize it out via inlining, but sometimes it might not. Certainly it won't do so in unoptimized or separately compiled builds.
See also original motivation and code:
https://github.com/D-Programming-Language/phobos/pull/2655
// Sketch of the technique to merge ref T and T* branches for output ranges
// while passing classes/delegates by value
private enum bool isPassByValue(T) = is(T: U*, U) || is( T == class ) ||
is (T == delegate) || is( T == function );
// Hook C-runtime to avoid being optimized out
extern(C) void putchar(int c);
//same doPut but _stripped_ of `ref` storage class
void doPut(T)(T arg){
pragma(msg, "Instantiated " ~ T.stringof);
// some sensible output ...
putchar(arg.value);
}
template forwardRef(alias Fn, T)
{
static if(isPassByValue!T)
{
pragma(msg, T.stringof ~" by value");
alias forwardRef = Fn!T;
}
else
{
pragma(msg, T.stringof ~" by ref");
auto forwardRef(ref T arg)
{
//convert to pointer explicitly
// ref T --> T* to debloat based on ref-ness
return Fn(&arg);
}
}
}
struct Val{
int value;
}
class CVal{
int value;
}
void main()
{
alias valFn = forwardRef!(doPut, Val);
alias ptrFn = forwardRef!(doPut, Val*);
alias classFn = forwardRef!(doPut, CVal);
Val v = Val('A');
CVal cv = new CVal;
cv.value = 'C';
// call each function to see codegen
valFn(v);
ptrFn(&v);
classFn(cv);
}
Comment #1 by johnnymarler — 2015-07-02T16:15:01Z
I'd like to add a link to a potential solution:
http://forum.dlang.org/thread/[email protected]
It may or may not be the best solution but I thought I'd put in on the table for consideration.
Comment #2 by robert.schadek — 2024-12-01T16:24:45Z