@Read("public") int publicInt; @Read("package") int packageInt; @Read("protected") int protectedInt; @Read("private") int privateInt; @Read int defaultVisibleInt; @Read @Write("protected") int publicReadableProtectedWritableInt; static assert(getVisibility!(publicInt, Read) == "public"); static assert(getVisibility!(packageInt, Read) == "package"); static assert(getVisibility!(protectedInt, Read) == "protected"); static assert(getVisibility!(privateInt, Read) == "private"); static assert(getVisibility!(defaultVisibleInt, Read) == "public"); static assert(getVisibility!(publicReadableProtectedWritableInt, Read) == "public"); static assert(getVisibility!(publicReadableProtectedWritableInt, Write) == "protected");
Creates accessors for flags.
import std.typecons : Flag, No, Yes; class Test { @Read @Write public Flag!"someFlag" test_ = Yes.someFlag; mixin(GenerateFieldAccessors); } with (new Test) { assert(test == Yes.someFlag); test = No.someFlag; assert(test == No.someFlag); static assert(is(typeof(test) == Flag!"someFlag")); }
Creates accessors for Nullables.
import std.typecons : Nullable; class Test { @Read @Write public Nullable!string test_ = Nullable!string("X"); mixin(GenerateFieldAccessors); } with (new Test) { assert(!test.isNull); assert(test.get == "X"); static assert(is(typeof(test) == Nullable!string)); }
Creates non-const reader.
class Test { @Read int i_; mixin(GenerateFieldAccessors); } auto mutableObject = new Test; const constObject = mutableObject; mutableObject.i_ = 42; assert(mutableObject.i == 42); static assert(is(typeof(mutableObject.i) == int)); static assert(is(typeof(constObject.i) == const(int)));
Creates ref reader.
class Test { @RefRead int i_; mixin(GenerateFieldAccessors); } auto mutableTestObject = new Test; mutableTestObject.i = 42; assert(mutableTestObject.i == 42); static assert(is(typeof(mutableTestObject.i) == int));
Creates writer.
class Test { @Read @Write private int i_; mixin(GenerateFieldAccessors); } auto mutableTestObject = new Test; mutableTestObject.i = 42; assert(mutableTestObject.i == 42); static assert(!__traits(compiles, mutableTestObject.i += 1)); static assert(is(typeof(mutableTestObject.i) == int));
Checks whether hasUDA can be used for each member.
class Test { alias Z = int; @Read @Write private int i_; mixin(GenerateFieldAccessors); } auto mutableTestObject = new Test; mutableTestObject.i = 42; assert(mutableTestObject.i == 42); static assert(!__traits(compiles, mutableTestObject.i += 1));
Returns non const for PODs and structs.
import std.algorithm : map, sort; import std.array : array; class C { @Read string s_; mixin(GenerateFieldAccessors); } C[] a = null; static assert(__traits(compiles, a.map!(c => c.s).array.sort()));
Regression.
class C { @Read @Write string s_; mixin(GenerateFieldAccessors); } with (new C) { s = "foo"; assert(s == "foo"); static assert(is(typeof(s) == string)); }
Supports user-defined accessors.
class C { this() { str_ = "foo"; } @RefRead private string str_; public @property const(string) str() const { return this.str_.dup; } mixin(GenerateFieldAccessors); } with (new C) { str = "bar"; }
Creates accessor for locally defined types.
class X { } class Test { @Read public X x_; mixin(GenerateFieldAccessors); } with (new Test) { x_ = new X; assert(x == x_); static assert(is(typeof(x) == X)); }
Creates const reader for simple structs.
class Test { struct S { int i; } @Read S s_; mixin(GenerateFieldAccessors); } auto mutableObject = new Test; const constObject = mutableObject; mutableObject.s_.i = 42; assert(constObject.s.i == 42); static assert(is(typeof(mutableObject.s) == Test.S)); static assert(is(typeof(constObject.s) == const(Test.S)));
Reader for structs return copies.
class Test { struct S { int i; } @Read S s_; mixin(GenerateFieldAccessors); } auto mutableObject = new Test; mutableObject.s.i = 42; assert(mutableObject.s.i == int.init);
Creates reader for const arrays.
class X { } class C { @Read private const(X)[] foo_; mixin(GenerateFieldAccessors); } auto x = new X; with (new C) { foo_ = [x]; auto y = foo; static assert(is(typeof(y) == const(X)[])); static assert(is(typeof(foo) == const(X)[])); }
Property has correct type.
class C { @Read private int foo_; mixin(GenerateFieldAccessors); } with (new C) { static assert(is(typeof(foo) == int)); }
Inheritance (https://github.com/funkwerk/accessors/issues/5).
class A { @Read string foo_; mixin(GenerateFieldAccessors); } class B : A { @Read string bar_; mixin(GenerateFieldAccessors); }
Transfers struct attributes.
struct S { this(this) { } void opAssign(S s) { } } class A { @Read S[] foo_; @ConstRead S bar_; @Write S baz_; mixin(GenerateFieldAccessors); }
@Read property returns array with mutable elements.
struct Field { } struct S { @Read Field[] foo_; mixin(GenerateFieldAccessors); } with (S()) { Field[] arr = foo; }
Static properties are generated for static members.
class MyStaticTest { @Read static int stuff_ = 8; mixin(GenerateFieldAccessors); } assert(MyStaticTest.stuff == 8);
Returns a string with the value of the field "visibility" if the field is annotated with an UDA of type A. The default visibility is "public".