1 module mutils.functional; 2 3 //TODO use taggedPointer https://dlang.org/phobos/std_bitmanip.html 4 import std.traits; 5 6 struct FunctionOrDelegate(DelegateOrFunctionType){ 7 static assert(isSomeFunction!DelegateOrFunctionType); 8 alias Ret=ReturnType!DelegateOrFunctionType; 9 alias Par=Parameters!DelegateOrFunctionType; 10 11 alias DelegateType=Ret delegate(Par); 12 alias FunctionType=Ret function(Par); 13 union{ 14 DelegateType del; 15 FunctionType func; 16 } 17 bool isDelegate; 18 19 this(DelegateType cal){ 20 opAssign(cal); 21 } 22 this(FunctionType cal){ 23 opAssign(cal); 24 } 25 Ret opCall(Args...)(Args parameters){ 26 static assert(is(Args==Par)); 27 assert(func !is null); 28 static if(is(Ret==void)){ 29 if(isDelegate){ 30 del(parameters); 31 }else{ 32 func(parameters); 33 } 34 }else{ 35 if(isDelegate){ 36 return del(parameters); 37 }else{ 38 return func(parameters); 39 } 40 } 41 } 42 43 void opAssign(DelegateType cal){ 44 del=cal; 45 isDelegate=true; 46 } 47 void opAssign(FunctionType cal){ 48 func=cal; 49 isDelegate=false; 50 } 51 bool opEquals(typeof(this) a){ 52 if(isDelegate!=a.isDelegate){ 53 return false; 54 } 55 if(isDelegate){ 56 return del==a.del; 57 }else{ 58 return func==a.func; 59 } 60 } 61 } 62