refract

Return a Function object that captures all the aspects of Fun, using the value of localSymbol to represent the return and parameter types, and the UDAs.

refract
(
alias fun
string localSymbol
)
()
if (
is(typeof(fun) == function)
)

Parameters

fun

a function

localSymbol

a string mixin that represents fun in the caller's context

Examples

pure @nogc int answer(lazy string question);
alias F = answer; // typically F is a template argument
static assert(
  refract!(F, "F").mixture ==
  "pure @nogc @system std.traits.ReturnType!(F) answer(lazy std.traits.Parameters!(F)[0] _0);");
import std.format;
import std.traits;

interface GrandTour
{
  pure int foo() immutable;
  @nogc @trusted nothrow ref int foo(out real, return ref int, lazy int) const;
  @safe shared scope void bar(scope Object);
}

class Mock(Interface) : Interface
{
  static foreach (member; __traits(allMembers, Interface)) {
      static foreach (fun; __traits(getOverloads, Interface, member)) {
        mixin({
            enum Model = refract!(fun, "fun");
            if (is(ReturnType!fun == void)) {
              return Model.setBody("{}").mixture;
            } else if (Model.attributes & FunctionAttribute.ref_) {
              return Model.setBody(q{{
                  static %s rv;
                  return rv;
                }}.format(Model.returnType)).mixture;
            } else {
              return Model.setBody(q{{
                  return %s.init;
                }}.format(Model.returnType)).mixture;
            }
          }());
      }
  }
}

GrandTour mock = new Mock!GrandTour;
real x;
int i, l;
mock.foo(x, i, l++) = 1;
assert(mock.foo(x, i, l++) == 1);
assert(l == 0);

Meta