Created
April 20, 2012 16:57
-
-
Save majiang/2430277 to your computer and use it in GitHub Desktop.
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 main; | |
import std.stdio; | |
import std.conv; | |
import std.typecons; | |
auto proper_div(T)(T x, T y) | |
{ | |
T q = x / y; | |
if ((0 < y && x < q*y) || (y < 0 && q*y < x)) | |
{ | |
q -= 1; | |
} | |
return q; | |
} | |
auto proper_mod(T)(T x, T y) | |
{ | |
return x - proper_div(x, y)*y; | |
} | |
class proper(T) | |
{ | |
private T v; | |
mixin Proxy!v; | |
this (T v) | |
{ | |
this.v = v; | |
} | |
auto opBinary(string op:"/", S)(S y) | |
{ | |
return proper!T(proper_div(v, cast(T)y)); | |
} | |
auto opBinaryRight(string op:"/", S:T)(S x) | |
{ | |
return proper!T(proper_div(cast(T)x, v)); | |
} | |
auto opBinary(string op:"%", S)(S y) | |
{ | |
return proper!T(proper_mod(v, cast(T)y)); | |
} | |
auto opBinaryRight(string op:"%", S:T)(S x) | |
{ | |
return proper!T(proper_mod(cast(T)x, v)); | |
} | |
auto opBinary(string op, S)(S y) | |
{ | |
return proper!T(mixin("v" ~ op ~ "cast(T)y")); | |
} | |
auto opBinaryRight(string op, S:T)(S x) | |
{ | |
return proper!T(mixin("cast(T)x" ~ op ~ "v")); | |
} | |
auto opUnary(string op)() | |
{ | |
if (op=="-") | |
{ | |
return proper!T(-v); | |
} | |
if (op == "+") | |
{ | |
return proper!T(v); | |
} | |
} | |
} | |
void test_struct() | |
{ | |
auto x = proper!long(4); // Error: template instance main.proper!(long).proper.Proxy!(v).opCall!(proper, int) error instantiating | |
auto y = proper!long(3); | |
writefln("x := %d; y := %d", cast(int)x, cast(int)y); | |
writefln("x / y = %d", cast(int)(x / y)); | |
writefln("x %% y = %d", cast(int)(x % y)); | |
writefln("(-x) / y = %d", cast(int)((-x) / y)); | |
writefln("(-x) %% y = %d", cast(int)((-x) % y)); | |
writefln("x / (-y) = %d", cast(int)(x / (-y))); | |
writefln("x %% (-y) = %d", cast(int)(x % (-y))); | |
writefln("(-x) / (-y) = %d", cast(int)((-x) / (-y))); | |
writefln("(-x) %% (-y) = %d", cast(int)((-x) % (-y))); | |
} | |
void main(string[] argv) | |
{ | |
test_struct(); | |
} | |
struct pint // OK | |
{ | |
private int v; | |
mixin Proxy!v; | |
this (int v) | |
{ | |
this.v = v; | |
} | |
auto opBinary(string op:"/", T)(T y) | |
{ | |
return pint(proper_div(v, cast(int)y)); | |
} | |
auto opBinaryRight(string op:"/", T:int)(T x) | |
{ | |
return pint(proper_div(cast(int)x, v)); | |
} | |
auto opBinary(string op:"%", T)(T y) | |
{ | |
return pint(proper_mod(v, cast(int)y)); | |
} | |
auto opBinaryRight(string op:"%", T:int)(T x) | |
{ | |
return pint(proper_mod(cast(int)x, v)); | |
} | |
auto opBinary(string op, T)(T y) | |
{ | |
return pint(mixin("v" ~ op ~ "cast(int)y")); | |
} | |
auto opBinaryRight(string op, T:int)(T x) | |
{ | |
return pint(mixin("cast(int)x" ~ op ~ "v")); | |
} | |
auto opUnary(string op)() | |
{ | |
if (op=="-") | |
{ | |
return pint(-v); | |
} | |
if (op == "+") | |
{ | |
return pint(v); | |
} | |
} | |
} | |
void test_func() | |
{ | |
int x = 4; | |
int y = 3; | |
writefln("x := %d; y := %d", x, y); | |
writefln("proper_div(x, y) = %d", proper_div(x, y)); // 1 | |
writefln("proper_mod(x, y) = %d", proper_mod(x, y)); // 1 | |
writefln("proper_div(-x, y) = %d", proper_div(-x, y)); // -2 | |
writefln("proper_mod(-x, y) = %d", proper_mod(-x, y)); // 2 | |
writefln("proper_div(x, -y) = %d", proper_div(x, -y)); // -2 | |
writefln("proper_mod(x, -y) = %d", proper_mod(x, -y)); // -2 | |
writefln("proper_div(-x, -y) = %d", proper_div(-x, -y)); // 1 | |
writefln("proper_mod(-x, -y) = %d", proper_mod(-x, -y)); // -1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment