Make your own free website on Tripod.com

MKoD - D Programming Language

D-Sourcery, variant thru boxer lite, a super-short version of std.boxer in D - code-name BoxerLite.d

Very Kool! A boxer super-short struct example:

/+
 ' Source   : BoxerLite.d
 ' Author   : Ben Hinkle  
 ' Created  : 06.May.05
 ' Modified : 22.Aug.06 David L 'SpottedTiger' Davis, changed the name from Box to BoxSS
 '          :           so the name doesn't crash with the std.boxer when both are being
 '          :           used...also compiled and tested with D v0.165.
 ' Ref      : http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=23294
 ' ------------------------------------------------------------------------------------------
 ' Note: A super-short variation of std.boxer using structs, and without the numeric casting.
 '
 ' To complie for a unittest:
 ' dmd boxerlite.d -debug=boxerlite -unittest
 '
 ' To compile a D program that uses boxerlite.d:
 ' dmd MySource.d boxerlite.d
 +/
module boxerlite;

struct BoxSS // Box Super-Short / SuperSport :)
{
    TypeInfo ti;
    private alias void[] _inline; // large enough to hold an array ref
    
    union 
    {
        void* ptr;
        void[_inline.sizeof] data;
    }
    
    BoxSS opIndex(size_t i) 
    {
        BoxSS[] b = unboxss!(BoxSS[])(*this); // throws if not ok
        return b[i];
    }
    
    BoxSS opIndexAssign(BoxSS val, size_t i) 
    {
        BoxSS[] b = unboxss!(BoxSS[])(*this); // throws if not ok
        b[i] = val;
        return val;
    }
}

BoxSS boxss(...) 
{
    BoxSS res;
    
    void doBoxSS(inout BoxSS b, void* argptr) 
    { 
        size_t s = b.ti.tsize();
        if (s <= b.data.length)
            b.data[0 .. s] = argptr[0 .. s];
        else
            b.ptr = argptr[0 .. s].dup.ptr;
    }
    
    if (_arguments.length > 1)
    {
        BoxSS[] b = new BoxSS[_arguments.length];
        
        foreach(int k, TypeInfo ti; _arguments) 
        {
            b[k].ti = ti;
            doBoxSS(b[k],_argptr);
            _argptr = _argptr + ((ti.tsize() + int.sizeof - 1) & ~(int.sizeof - 1));
        }
        
        res = boxss(b);
    } 
    else 
    {
        res.ti = _arguments[0];
        doBoxSS(res,_argptr);
    }
    
    return res;
}

template unboxss(T) 
{
    T unboxss(BoxSS b) 
    {
        if (typeid(T) is b.ti) 
        {
            size_t s = b.ti.tsize();
            
            if (s <= b.data.length)
                return *cast(T*)b.data.ptr;
            else
                return *cast(T*)b.ptr;
        } 
        else
            throw new Exception("Unbox error to type " ~ 
                  typeid(T).toString() ~
                  " from " ~ b.ti.toString());
    }
}

//-----------------------------------------------------------
debug(boxerlite)
{
private import std.stdio;
private import boxerlite;

class Tester
{
    private char[] s = "testme";	
    
    public char[] getvalue() { return s; }	
}

int main() 
{
    writefln("boxerlite unittest done.");
    return 0;	
}
}

unittest
{
    BoxSS b = boxss(40);
    int val = unboxss!(int)(b);
    BoxSS b2 = boxss("hello");
    char[] str = unboxss!(char[])(b2);
    assert(val == 40);
    assert(str == "hello");
    writefln("val=%d, str=\"%s\"", val, str);
    
    BoxSS b3 = boxss(123.0);
    double d = unboxss!(double)(b3);
    assert(d == 123.0);
    writefln("d=%f", d);
    
    Tester o1 = new Tester;
    Tester o2 = null;
    BoxSS b4 = boxss(o1);
    o2 = unboxss!(Tester)(b4);
    assert(o2.getvalue() == "testme");
    writefln("Object=\"%s\", s=\"%s"\", o2.toString(), o2.getvalue());
}
C:\dmd>dmd boxerlite.d -debug=boxerlite -unittest
C:\dmd\bin\..\..\dm\bin\link.exe boxerlite,,,user32+kernel32/noi;

C:\dmd>boxerlite
val=40, str="hello"
d=123.000000
Object="Tester", s="testme"
boxerlite unittest done.

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