-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathphobos_example.d
69 lines (61 loc) · 2.88 KB
/
phobos_example.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// example copied from std.bitmanip
private string myToString(ulong n)
{
import core.internal.string : UnsignedStringBuf, unsignedToTempString;
UnsignedStringBuf buf;
auto s = unsignedToTempString(n, buf);
return cast(string) s ~ (n > uint.max ? "UL" : "U");
}
// CURRENT IMPLEMENTATION
private template createReferenceAccessor(string store, T, ulong bits, string name)
{
enum storage = "private void* " ~ store ~ "_ptr;\n";
enum storage_accessor = "@property ref size_t " ~ store ~ "() return @trusted pure nothrow @nogc const { "
~ "return *cast(size_t*) &" ~ store ~ "_ptr;}\n"
~ "@property void " ~ store ~ "(size_t v) @trusted pure nothrow @nogc { "
~ "" ~ store ~ "_ptr = cast(void*) v;}\n";
enum mask = (1UL << bits) - 1;
// getter
enum ref_accessor = "@property "~T.stringof~" "~name~"() @trusted pure nothrow @nogc const { auto result = "
~ "("~store~" & "~myToString(~mask)~"); "
~ "return cast("~T.stringof~") cast(void*) result;}\n"
// setter
~"@property void "~name~"("~T.stringof~" v) @trusted pure nothrow @nogc { "
~"assert(((cast(typeof("~store~")) cast(void*) v) & "~myToString(mask)
~`) == 0, "Value not properly aligned for '`~name~`'"); `
~store~" = cast(typeof("~store~"))"
~" (("~store~" & (cast(typeof("~store~")) "~myToString(mask)~"))"
~" | ((cast(typeof("~store~")) cast(void*) v) & (cast(typeof("~store~")) "~myToString(~mask)~")));}\n";
enum result = storage ~ storage_accessor ~ ref_accessor;
}
// IMPLEMENTATION WITH STRING INTERPOLATION
private template createReferenceAccessor(string store, T, ulong bits, string name)
{
enum storage = text(i"private void* $(store)_ptr;\n");
enum storage_accessor = text(iq{
@property ref size_t $store() return @trusted pure nothrow @nogc const {
return *cast(size_t*) & $(store)_ptr;}
@property void $store(size_t v) @trusted pure nothrow @nogc { $(store)_ptr = cast(void*) v;}
});
enum mask = (1UL << bits) - 1;
// getter
enum ref_accessor = text(iq{
@property $(T.stringof) $name() @trusted pure nothrow @nogc const { auto result =
($store & $(myToString(~mask)));
return cast("~T.stringof~") cast(void*) result;}
// setter
@property void $name($(T.stringof) v) @trusted pure nothrow @nogc {
assert(((cast(typeof($store)) cast(void*) v) & $(myToString(mask))
) == 0, "Value not properly aligned for '$name'");
$store = cast(typeof($store))
(($store & (cast(typeof($store)) $(myToString(mask))))
| ((cast(typeof($store)) cast(void*) v) & (cast(typeof($store)) $(myToString(mask)))));}
});
enum result = storage ~ storage_accessor ~ ref_accessor;
}
void main()
{
import std.stdio;
alias a = createReferenceAccessor!("uint", ubyte, 10, "foo");
writeln(a.result);
}