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);

Reply via email to