Skip to content

Instantly share code, notes, and snippets.

@rikkimax
Last active September 25, 2018 01:35
Show Gist options
  • Save rikkimax/5f5893231bccb3264b230e74a1571c0b to your computer and use it in GitHub Desktop.
Save rikkimax/5f5893231bccb3264b230e74a1571c0b to your computer and use it in GitHub Desktop.
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