Make your own free website on Tripod.com

MKoD - D Programming Language

D-Sourcery, property implementation done with mixins in D - code-name Attr_Mixin.d

Very Kool! Property mixin in D example:

/+
 ' Source  : Attr_Mixin.d
 ' Author  : Derek Parnell 
 ' Created : 03.Jul.06
 ' Ref     : http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=39535
 ' -----------------------------------------------------------------------
 ' A starting point for better property implementation (done with mixins). 
 '
 ' To unittest : dmd attr_mixin.d -unittest -debug=attr_mixin
 ' To compile  : dmd yourcode.d attr_mixin.d
 +/
module attr_mixin;

debug( attr_mixin ) private import std.stdio;
debug( attr_mixin ) private import std.string;

// Read and Write Attribute, without a function call.
template AttributeRW(T)
{
    private T _xRW;
    public  T get() { return _xRW; }
    public  T set(T d) { _xRW = d; return d; }
}

// Read and Write Attribute, with a function call.
template AttributeRW(T, alias F)
{
    private T _xRWF;
    public  T get() { return F(_xRWF, true); }
    public  T set(T d) { _xRWF = F(d, false); return F(_xRWF, true); }
}

// Read Only Attribute, without a function call.
template AttributeRO(T)
{
    private T _xRO;
    public  T get() { return _xRO; }
}

// Read Only Attribute, with a function call.
template AttributeRO(T, alias F)
{
    private T _xROF;
    public  T get() { return F(_xROF, true); }
}

// Write Only Attribute, without a function call.
template AttributeWO(T)
{
    private T _xWO;
    public  T set(T d) { _xWO = d; return _xWO; }
}

// Write Only Attribute, with a function call.
template AttributeWO(T, alias F)
{
    private T _xWOF;
    public  T set(T d) { _xWOF = F(d, false); return F(_xWOF, true); }
}

debug( attr_mixin )
{   
    int main()
    {
        writefln("attr_mixin unittest done!"c);
        return 0;
    } 
}

// Derek Parnell's example with a few minor changes:
unittest
{
    class Car
    {
        mixin attr_mixin.AttributeRW!(int, QA_Colour)  Colour;
        mixin attr_mixin.AttributeRW!(real)            Speed;
        mixin attr_mixin.AttributeRO!(real)            Torque;
        mixin attr_mixin.AttributeWO!(real, QA_Accel)  Accel;
        mixin attr_mixin.AttributeRO!(char[])          Name;
        
        this(in char[] sCarName)
        {
            Name._xRO = sCarName;
        }
        
        // Set torque on acceleration
        private real QA_Accel(real v, bool act)
        {
            if (act == false)
                Torque._xRO = v * 17 / 3;
        
            return v;
        }

        // Validate Colour
        private int QA_Colour(int v, bool act)
        {
            if (act == false)
                if (v >= 0 && v < 256)
                    Colour._xRWF = v;
                else 
                    throw new Error("Bad colour value."c);
        
            return v;
        }
    }	
    
    auto oCar = new Car("Furary"c);

    oCar.Colour.set = 4;
    oCar.Speed.set = 6.4455;
    oCar.Accel.set = 1.2;

    writefln("%s ...\n  Colour %s, Speed %s, and Torque %s"c,
                oCar.Name.get,
                oCar.Colour.get,
                oCar.Speed.get,
                oCar.Torque.get
            );	
    
    assert(oCar.Name.get == "Furary"c);
    assert(oCar.Colour.get == 4);
    assert(oCar.Speed.get == 6.4455);
    assert(toString(oCar.Torque.get) == "6.8"c);            
}
C:\dmd>dmd attr_mixin.d -unittest -debug=attr_mixin
C:\dmd\bin\..\..\dm\bin\link.exe attr_mixin,,,user32+kernel32/noi;

C:\dmd>attr_mixin
Furary ...
  Colour 4, Speed 6.4455, and Torque 6.8
attr_mixin unittest done!

C:\dmd>
Mars: fourth Rock from the Sun.