On Sunday, 15 May 2016 at 02:12:38 UTC, Ann W. Griffith wrote:
use "Parameters" in the constraint or make a template that you can reeuse.

This is what I've got going so far. Using static asserts to have clearer errors when an incorrect callback is supplied. I'm not... sure storage class is important.

import std.traits: isSomeFunction, isCallable,
  ParameterTypeTuple, ParameterStorageClassTuple, ReturnType,
  isDelegate;

import std.stdio;

template isCompatibleFunction(alias Src, alias Dest) {
     static assert(isSomeFunction!Src || isCallable!Src,
                                   "Source is not callable");
     static assert(isSomeFunction!Dest || isCallable!Dest,
                                   "Destination is not callable");

static assert(is(ParameterTypeTuple!Src == ParameterTypeTuple!Dest),
                                "Type Tuples differ");
  pragma(msg,ParameterStorageClassTuple!Src ==
                                ParameterStorageClassTuple!Dest);
  static assert(ParameterStorageClassTuple!Src ==
                                ParameterStorageClassTuple!Dest,
                                "Storage classes differ");
  static assert(is(ReturnType!Src == ReturnType!Dest),
                                "Return type differs");
  immutable bool isCompatibleFunction = true;
}


bool function_callback(string a) {
  return true;
}

template foobar(Callable) if(isCompatibleFunction!(function_callback,Callable)) {
  template foobar(Callable c) {
        immutable bool foobar = c("foo");
  }
}

void main() {
  bool result = true;
  bool delegate_callback(string a) {
        return result;
  }
  bool delegate(string) dg = &delegate_callback;
  static assert(isDelegate!dg);
static assert(isCompatibleFunction!(function_callback, delegate_callback));
  struct Derp {
        static bool opCall(string a) {
          return true;
        }
        bool opCall(string a) {
          return false;
        }
        bool member(string a) {
          return true;
        }
  };
static assert(isCompatibleFunction!(function_callback,Derp.init.member)); static assert(isCompatibleFunction!(function_callback,Derp.init));
  static assert(isCompatibleFunction!(function_callback,Derp));
  static assert(isCompatibleFunction!(delegate_callback,Derp));
  if(foobar!function_callback) {
        writeln("foo");
  } else {
        writeln("bar");
  }
  writeln("derp");
}

Reply via email to