Last active
December 22, 2015 06:29
-
-
Save rjmcguire/6431542 to your computer and use it in GitHub Desktop.
Little demo of allowing basic types to implement interfaces.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module traits; | |
import traits_impl; | |
import std.typecons; | |
void main() { | |
MyInt i = 0x34342343; | |
writebytes(i); | |
writebytes2(1); | |
//writebytes(1); // Cannot call Implements on basic types unless you specify the module for lookup, type:int | |
} | |
//enum Order { Big }; | |
//interface IRawBytes { ubyte[] bytes(Order); } | |
interface IRawBytes { ubyte[] bytes(); } | |
void writebytes(T)(T item) if (Implements!(T, IRawBytes)) { | |
import std.stdio : writeln; | |
writeln(item.bytes); | |
} | |
void writebytes2(T)(T item) if (Implements!(T, IRawBytes, __MODULE__)) { | |
import std.stdio : writeln; | |
writeln(item.bytes); | |
} | |
ubyte[] bytes(ref int i) { | |
ubyte* ptr; | |
ptr = cast(ubyte*)&i; | |
return ptr[0..i.sizeof]; | |
} | |
typedef int MyInt; | |
ubyte[] bytes(ref MyInt i) { | |
ubyte* ptr; | |
ptr = cast(ubyte*)&i; | |
return ptr[0..i.sizeof]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.traits; | |
import std.typetuple; | |
import std.typecons; | |
// Implementation ====================== | |
/** true if T implements interface I using UFCS or methods */ | |
bool Implements(T,I, string mod = "")() {//if (isInterface!I) { | |
static assert(!(mod=="" && is(T==int)), "Cannot call Implements on basic types unless you specify the module for lookup, type:"~ T.stringof); | |
bool check() { | |
static if (mod.length <= 0) | |
mixin("import "~ moduleName!T ~";"); | |
else | |
mixin("import "~ mod ~";"); | |
static if (!is(T == int)) //__traits(compiles, moduleName!T)) | |
foreach (m; __traits(allMembers, I)) { | |
foreach( overload; MemberFunctionsTuple!(I, m) ) { | |
alias ReturnType!overload RetType; | |
alias ParameterTypeTuple!overload params; | |
alias ParameterValueTuple!params Values; | |
alias ValuesString!Values parms; | |
T v; | |
static if (is(RetType == void)) { | |
//pragma(msg, "v."~m~"("~parms~")", " ", __traits(compiles, mixin("v."~m~"("~Values.stringof[6..$-1]~")"))); | |
enum s = "v."~m~"("~parms~")"; | |
static if (!__traits(compiles, mixin(s))) { | |
pragma(msg, "missing: "~ fullyQualifiedName!T ~"."~m~params.stringof); | |
return false; | |
} | |
} else { | |
RetType ret; | |
//pragma(msg, "v."~m~"("~parms~")", " ", __traits(compiles, mixin("ret = v."~m~"("~Values.stringof[6..$-1]~")"))) | |
enum s = "ret = v."~m~"("~parms~")"; | |
static if (!__traits(compiles, mixin(s))) { | |
pragma(msg, "missing: "~ fullyQualifiedName!RetType ~" "~ fullyQualifiedName!T ~"."~m~params.stringof); | |
return false; | |
} | |
} | |
} | |
} | |
return true; | |
} | |
static if(check()) | |
return true; | |
else { | |
pragma(msg, fullyQualifiedName!T ~", does not implement interface: "~ fullyQualifiedName!I); | |
return false; | |
} | |
} | |
string ValuesString(Values...)() { | |
static if (Values.length>0) { | |
return Values.stringof[6..$-1]; | |
} else { | |
return ""; | |
} | |
} | |
template ParameterValueTuple(Specs...) { | |
template parseSpecs(Specs...) | |
{ | |
static if (Specs.length == 0) | |
{ | |
alias TypeTuple!() parseSpecs; | |
} | |
else static if (is(Specs[0])) | |
{ | |
static if (is(typeof(Specs[1]) : string)) | |
{ | |
alias TypeTuple!(Specs[0 .. 2].init, | |
parseSpecs!(Specs[2 .. $])) parseSpecs; | |
} | |
else | |
{ | |
alias TypeTuple!(Specs[0].init, | |
parseSpecs!(Specs[1 .. $])) parseSpecs; | |
} | |
} | |
else | |
{ | |
static assert(0, "Attempted to instantiate Tuple with an " | |
~"invalid argument: "~ Specs[0].stringof); | |
} | |
} | |
alias parseSpecs!Specs ParameterValueTuple; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment