Last active
September 25, 2018 01:35
-
-
Save rikkimax/5f5893231bccb3264b230e74a1571c0b to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import std.stdio; | |
void main() | |
{ | |
auto a = HeadConst!(int*)(new int); | |
a = 3; | |
assert(a == 3); | |
auto b = HeadConst!(int[])(new int[3]); | |
b[0] = 1; | |
b[1] = 2; | |
b[2] = 3; | |
assert(b[0] == 1); | |
assert(b[1] == 2); | |
assert(b[2] == 3); | |
assert(b[1 .. 2][0] == 2); | |
assert(b[1 .. 2].length == 1); | |
enum C = (int[2]).init; | |
auto c = HeadConst!(int[2])(C); | |
c[0] = 1; | |
c[1] = 2; | |
assert(c.ptr !is null); | |
assert(c.ptr[0] == 1); | |
assert(c[0] == 1); | |
assert(c[1] == 2); | |
assert(c[0 .. 1][0] == 1); | |
assert(c[0 .. 1].length == 1); | |
auto d = HeadConst!MyClass(new MyClass); | |
assert(d.func(2) == 4); | |
d.field = 3; | |
assert(d.field == 3); | |
(cast(MyClass)d).writeln; | |
} | |
import std.traits; | |
struct HeadConst(T) if (isPointer!T) | |
{ | |
private T _value; | |
this(T value) | |
{ | |
this._value = value; | |
} | |
ref auto _getter() | |
{ | |
return *_value; | |
} | |
alias _getter this; | |
} | |
struct HeadConst(T) if (isArray!T) | |
{ | |
private T _value; | |
this(T value) | |
{ | |
this._value = value; | |
} | |
@property size_t length() | |
{ | |
return _value.length; | |
} | |
ref auto opIndex(size_t index) | |
{ | |
return _value[index]; | |
} | |
const(ForeachType!T*) ptr() { | |
return _value.ptr; | |
} | |
static if (isDynamicArray!T) | |
{ | |
HeadConst!T opSlice(size_t a, size_t b) | |
{ | |
return HeadConst!T(_value[a .. b]); | |
} | |
} | |
else static if (isStaticArray!T) | |
{ | |
scope HeadConst!(ForeachType!T[]) opSlice(size_t a, size_t b) | |
{ | |
return HeadConst!(ForeachType!T[])(_value[a .. b]); | |
} | |
} | |
} | |
class MyClass | |
{ | |
int field; | |
int func(int v) | |
{ | |
return v * 2; | |
} | |
} | |
struct HeadConst(T) if (is(T == class)) | |
{ | |
private T _value; | |
this(T value) | |
{ | |
this._value = value; | |
} | |
@property ref auto opDispatch(string name)() if (!isMethod!(T, name)) | |
{ | |
return mixin("_value." ~ name); | |
} | |
auto opDispatch(string name, U...)(U args) if (isMethod!(T, name)) | |
{ | |
return mixin("_value." ~ name ~ "(args)"); | |
} | |
scope T _getter() { | |
return _value; | |
} | |
alias _getter this; | |
} | |
private: | |
bool isMethod(T, string name)() pure | |
{ | |
foreach (_; __traits(getOverloads, T, name)) | |
{ | |
return true; | |
} | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment