Skip to content

Instantly share code, notes, and snippets.

@majiang
Created April 20, 2012 16:57
Show Gist options
  • Save majiang/2430277 to your computer and use it in GitHub Desktop.
Save majiang/2430277 to your computer and use it in GitHub Desktop.
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