Skip to content

Instantly share code, notes, and snippets.

@aliak00
Last active July 5, 2019 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aliak00/fcdd4fa7512035405bb7015cf6d8016f to your computer and use it in GitHub Desktop.
Save aliak00/fcdd4fa7512035405bb7015cf6d8016f to your computer and use it in GitHub Desktop.
Comparing functions in wrappers
import std.stdio;
template isTransformedWrapper(W) {
enum isTransformedWrapper = is(W : TrasformedWrapper!T, T...);
}
struct Wrapped(T) {
T value;
}
auto wrap(T)(T value) {
return Wrapped!(T)(value);
}
struct TrasformedWrapper(alias fun, T, U) {
alias Fun = fun;
T originalValue;
U value;
}
auto transform(alias fun, T)(Wrapped!T w) {
alias U = typeof(fun(w.value));
return TrasformedWrapper!(fun, T, U)(w.value, fun(w.value));
}
/*
template transformer(WT, alias fallback = null) {
static if (isTransformedWrapper!WT) {
alias transformer = WT.Fun;
} else {
alias transformer = fallback;
}
}
*/
enum isSame(alias f0, alias f1) = __traits(isSame, f0, f1);
auto ref resolveTrasnformedData(
alias receivedData,
alias isTransformedType,
alias isTransformOk,
alias transformFn,
alias untransformFn,
)() {
alias ReceivedType = typeof(receivedData);
enum identifier = __traits(identifier, receivedData);
static if (!isTransformedType!ReceivedType) {
writeln(identifier, " data not tranformed, transforming");
return transformFn(receivedData);
} else static if (isTransformOk!ReceivedType) {
writeln(identifier, " data tranformed, and transformer ok, doing nothing");
return receivedData;
} else {
writeln(identifier, " data transformed, but transformer not ok, transforming");
return transformFn(untransformFn(receivedData));
}
}
auto algorithm(alias fun, W0, W1)(W0 w0, W1 w1) {
alias isTransformOk(T) = isSame!(T.Fun, fun);
alias transform = (data) => .transform!fun(data);
alias untransform = (data) => data.originalValue.wrap;
auto t0 = resolveTrasnformedData!(w0, isTransformedWrapper, isTransformOk, transform, untransform);
auto t1 = resolveTrasnformedData!(w1, isTransformedWrapper, isTransformOk, transform, untransform);
// writeln("## ", a0);
/*
write("t0: ");
static if (!isTransformedWrapper!W0) {
write("needs transform");
auto t0 = w0.transform!fun;
} else static if (isSame!(W0.Fun, fun)) {
write("transformed correctly");
auto t0 = w0;
} else {
write("transformed incorrectly");
auto t0 = w0.originalValue.wrap.transform!fun;
}
write(", t1: ");
static if (!isTransformedWrapper!W1) {
write("needs transform");
auto t1 = w1.transform!fun;
} else static if (isSame!(W1.Fun, fun)) {
write("transformed correctly");
auto t1 = w0;
} else {
write("transformed incorrectly");
auto t1 = w0.originalValue.wrap.transform!fun;
}
writeln;
*/
/*
static if (isTransformedWrapper!W0 && isTransformedWrapper!W1) {
// Both already transformed
static if (isSame!(W0.Fun, fun) && isSame!(W1.Fun, fun)) {
// They both have the same transformer
writeln("both wrapped, no transforms needed");
auto t0 = w0;
auto t1 = w1;
} else {
static if (isSame!(W0.Fun, fun)) {
writeln("both wrapped, w0.fun ok, w1 needs transform");
auto t0 = w0;
auto t1 = w1.originalValue.wrap.transform!fun;
} else static if (isSame!(W1.Fun, fun)) {
writeln("both wrapped, w0 needs transform, w1.fun ok");
auto t0 = w0.originalValue.wrap.transform!fun;
auto t1 = w1;
} else {
writeln("both wrapped, w0 needs transform, w1 needs transform");
auto t0 = w0.originalValue.wrap.transform!fun;
auto t1 = w1.originalValue.wrap.transform!fun;
}
}
} else static if (isTransformedWrapper!W0) {
// Only w0 is transformed
static if (isSame!(W0.Fun, fun)) {
writeln("w0 wrapped, w0.fun ok");
auto t0 = w0;
} else {
writeln("w0 wrapped, w0 needs transform");
auto t0 = w0.originalValue.wrap.transform!fun;
}
auto t1 = w1;
} else static if (isTransformedWrapper!W1) {
// Only w1 is transformed
auto t0 = w0;
static if (isSame!(W1.Fun, fun)) {
writeln("w1 wrapped, w1.fun ok");
auto t1 = w1;
} else {
writeln("w1 wrapped, w1 needs transform");
auto t1 = w1.originalValue.wrap.transform!fun;
}
} else {
// Neither are transformed types
writeln("neither wrapped, transforming both");
auto t0 = w0.transform!fun;
auto t1 = w1.transform!fun;
}
*/
// Perform algorithm on transformed values.
return t0.value + t1.value;
}
int f(int a) {
return a + a + a;
}
void main() {
alias x2 = (a) => a * 2;
alias x3 = (a) => a * 3;
auto a = 2.wrap;
auto tx2 = a.transform!x2;
auto tx3 = a.transform!x3;
tx2.writeln;
tx3.writeln;
writeln("x2(a, a)");
algorithm!x2(a, a).writeln;
writeln("x3(a, a)");
algorithm!x3(a, a).writeln;
writeln("x2(tx2, tx2)");
algorithm!x2(tx2, tx2).writeln;
writeln("x3(tx2, tx2)");
algorithm!x3(tx2, tx2).writeln;
writeln("x2(tx3, tx3)");
algorithm!x2(tx3, tx3).writeln;
writeln("x3(tx3, tx3)");
algorithm!x3(tx3, tx3).writeln;
writeln("x2(tx2, tx3)");
algorithm!x2(tx2, tx3).writeln;
writeln("x2(tx2, tx3)");
algorithm!x3(tx2, tx3).writeln;
writeln("x2(a.transform!f, a)");
algorithm!f(a.transform!f, a).writeln;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment