1 import std
.exception
: Exception
;
2 import std
.functional
: memoize
;
3 import std
.string
: format
;
10 // provides dynamic function dispatch with objects, not classes
11 mixin template funcwrapper(alias func
) {
12 import std
.traits
: ReturnType
;
13 mixin(ReturnType
!func
.stringof
~ " "
14 ~ __traits(identifier
, func
)[1 .. $] // [1:$] to get rid of the leading _
15 ~ "(T...)(T args) {" // (Parameters!func).stringof
16 ~ (ReturnType
!func
.stringof
== "void" ?
"" : "return ")
17 ~ __traits(identifier
, func
) ~ " ? " // if the function exists, call it. Otherwise, do nothing (call pass)
18 ~ __traits(identifier
, func
) ~ "(this, args)"
19 ~ " : " ~ (ReturnType
!func
.stringof
== "void" ?
"pass" : (ReturnType
!func
.stringof
~ ".init")) ~ ";"
23 /*mixin template funcwrappers(funcs...) {
24 static foreach (func; funcs) {
25 mixin funcwrapper!func;
34 void delegate(ref Bla self) _func;
36 mixin funcwrapper!_func;
42 bla._func = (ref Bla self) {
43 writefln("I have %s", self.n);
51 class DException
: Exception
{
52 pragma(inline
, true) pure this(T
...)(T args
) {
57 class InternalError
: DException
{
58 pragma(inline
, true) pure this(T
...)(T args
) {
63 void exit(ubyte code
) {
64 import core
.runtime
: Runtime
;
65 static import core
.stdc
.stdlib
;
67 core
.stdc
.stdlib
.exit(code
);
70 pure string
fillstr(size_t length
, char ch
=' ') {
72 while (length
--> 0) {
80 // Taken directly from http://stackoverflow.com/a/41978310
81 /* It's supposed to be incredibly performant...but honestly I used it because
82 * I could copy-paste it easily.
84 alias get256colour
= memoize
!((RGBColour colour
) {
85 enum ubyte[6] i2cv
= [0, 0x5f, 0x87, 0xaf, 0xd7, 0xff];
86 pragma(inline
, true) {
87 auto v2ci
= (int v
) => v
< 48 ?
0 : v
< 115 ?
1 : (v
- 35) / 40;
88 auto colour_index
= (int r
, int g
, int b
) => 36*r
+ 6*g
+ b
;
89 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
);
92 int ir
= v2ci(colour
.r
), ig
= v2ci(colour
.g
), ib
= v2ci(colour
.b
);
93 int average
= (colour
.r
+ colour
.g
+ colour
.b
) / 3;
94 int igray
= average
> 238 ?
23 : (average
-3) / 10;
95 int cr
= i2cv
[ir
], cg
= i2cv
[ig
], cb
= i2cv
[ib
];
96 int gv
= 8 + 10 * igray
;
98 int colour_err
= distance(cr
, cg
, cb
, colour
.r
, colour
.g
, colour
.b
);
99 int gray_err
= distance(gv
, gv
, gv
, colour
.r
, colour
.g
, colour
.b
);
101 return cast(ubyte)(colour_err
<= gray_err ?
16 + colour_index(ir
, ig
, ib
) : 232 + igray
);
106 pragma(inline
, true) ubyte get256colour(ubyte r
, ubyte g
, ubyte b
) { return get256colour(RGBColour(r
, g
, b
)); }
107 pragma(inline
, true) ubyte get256colour(string colour
) { return get256colour(RGBColour(colour
)); }