Generic Property Implementation

bauss jj_1337 at live.dk
Tue Feb 20 14:34:53 UTC 2018


Would there be a reason why this wouldn't be a good 
implementation?

If so what and how could it be improved?

Are there flaws in an implementation like this?

struct Property(T, bool readOnly = false)
{
     import std.traits : isScalarType, isArray, 
isAssociativeArray, isSomeString;

     private T _value;

     T __GET() { return _value; }

     static if (readOnly)
     {
     	private
         {
             void __SET(T newValue) { _value = newValue; }

             void opAssign(T newValue)
             {
                 __SET(newValue);
             }
         }
     }
     else
     {
     	void __SET(T newValue) { _value = newValue; }

         void opAssign(T newValue)
         {
             __SET(newValue);
         }
     }

     bool opEquals(T other)
     {
         static if (isScalarType!T || isArray!T || 
isAssociativeArray!T)
         {
             return _value == other;
         }
         else
         {
             if (_value is other) return true;
             if (_value is null || other is null) return false;
             if (typeid(_value) == typeid(other)) return 
_value.opEquals(other);
             return _value.opEquals(other) && 
other.opEquals(_value);
         }
     }

     static if (!(isArray!T) && !(isAssociativeArray!T))
     {
         int opCmp(T other)
         {
             static if (isScalarType!T)
             {
                 if (_value < other) return -1;
                 if (_value > other) return 1;

                 return 0;
             }
             else
             {
                 return _value.opCmp(other);
             }
         }
     }

     string toString()
     {
         static if (isArray!T && isSomeString!T)
         {
             return _value;
         }
         else static if (__traits(hasMember, T, "toString"))
         {
             return _value.toString();
         }
         else
         {
             import std.conv : to;

             return to!string(_value);
         }
     }

     alias __GET this;
}

alias ReadOnlyProperty(T) = Property!(T, true);

---

This would allow something like this:

class Foo
{
     ReadOnlyProperty!int bar;

     Property!string baz;

     Property!int faz;

     Property!Bar bar2;
}

class Bar
{
     int boo;
}

Which can be used like:

     auto foo = new Foo;
     foo.baz = "Hello";
     foo.baz = foo.baz ~ " World!";
     foo.faz = 250 + foo.bar;

     foo.bar2 = new Bar;
     foo.bar2.boo = 200;

     import std.stdio;

     writeln(foo.bar);
     writeln(foo.baz);
     writeln(foo.faz);
     writeln(foo.bar2.boo);



More information about the Digitalmars-d-learn mailing list