1 import std
.functional
: memoize
;
9 // provides dynamic function dispatch with objects, not classes
10 mixin template funcwrapper(alias func
) {
11 import std
.traits
: ReturnType
;
12 mixin(ReturnType
!func
.stringof
~ " "
13 ~ __traits(identifier
, func
)[1 .. $] // [1:$] to get rid of the leading _
14 ~ "(T...)(T args) {" // (Parameters!func).stringof
15 ~ (ReturnType
!func
.stringof
== "void" ?
"" : "return ")
16 ~ __traits(identifier
, func
) ~ " ? " // if the function exists, call it. Otherwise, do nothing (call pass)
17 ~ __traits(identifier
, func
) ~ "(this, args)"
18 ~ " : " ~ (ReturnType
!func
.stringof
== "void" ?
"pass" : (ReturnType
!func
.stringof
~ ".init")) ~ ";"
22 /*mixin template funcwrappers(funcs...) {
23 static foreach (func; funcs) {
24 mixin funcwrapper!func;
33 void delegate(ref Bla self) _func;
35 mixin funcwrapper!_func;
41 bla._func = (ref Bla self) {
42 writefln("I have %s", self.n);
50 class DException
: Exception
{
51 pragma(inline
, true) pure this(T
...)(T args
) {
56 class InternalError
: DException
{
57 pragma(inline
, true) pure this(T
...)(T args
) {
62 void exit(ubyte code
) {
63 import core
.runtime
: Runtime
;
64 static import core
.stdc
.stdlib
;
66 core
.stdc
.stdlib
.exit(code
);
69 pure string
fillstr(size_t length
, char ch
=' ') {
71 while (length
--> 0) {
79 // Taken directly from http://stackoverflow.com/a/41978310
80 /* It's supposed to be incredibly performant...but honestly I used it because
81 * I could copy-paste it easily.
83 alias get256colour
= memoize
!((RGBColour colour
) {
84 enum ubyte[6] i2cv
= [0, 0x5f, 0x87, 0xaf, 0xd7, 0xff];
85 pragma(inline
, true) {
86 auto v2ci
= (int v
) => v
< 48 ?
0 : v
< 115 ?
1 : (v
- 35) / 40;
87 auto colour_index
= (int r
, int g
, int b
) => 36*r
+ 6*g
+ b
;
88 auto distance
= (int r1
, int g1
, int b1
, int r2
, int g2
, int b2
) => (r1
-r2
)*(r1
-r2
) + (g1
-g2
)*(g1
-g2
) + (b1
-b2
)*(b1
-b2
);
91 int ir
= v2ci(colour
.r
), ig
= v2ci(colour
.g
), ib
= v2ci(colour
.b
);
92 int average
= (colour
.r
+ colour
.g
+ colour
.b
) / 3;
93 int igray
= average
> 238 ?
23 : (average
-3) / 10;
94 int cr
= i2cv
[ir
], cg
= i2cv
[ig
], cb
= i2cv
[ib
];
95 int gv
= 8 + 10 * igray
;
97 int colour_err
= distance(cr
, cg
, cb
, colour
.r
, colour
.g
, colour
.b
);
98 int gray_err
= distance(gv
, gv
, gv
, colour
.r
, colour
.g
, colour
.b
);
100 return cast(ubyte)(colour_err
<= gray_err ?
16 + colour_index(ir
, ig
, ib
) : 232 + igray
);
103 float dist(int x1
, int y1
, int x2
, int y2
) {
104 return sqrt(dist_sq(x1
, y1
, x2
, y2
));
106 int dist_sq(int x1
, int y1
, int x2
, int y2
) {
109 return px
* px
+ py
* py
;
114 pragma(inline
, true) ubyte get256colour(ubyte r
, ubyte g
, ubyte b
) { return get256colour(RGBColour(r
, g
, b
)); }
115 pragma(inline
, true) ubyte get256colour(string colour
) { return get256colour(RGBColour(colour
)); }