Changeset 199

Show
Ignore:
Timestamp:
02/26/09 16:42:42 (3 years ago)
Author:
dhasenan
Message:

formatting improvements -- especially with floats

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • dunit/trunk/dunit/assertions/same.d

    r198 r199  
    1010    Result run(ConstraintRunner runner, Variant actual, Variant expected) 
    1111    { 
    12         auto result = new Result(true, "same as ", expected, actual); 
    13         // How are two variants the same? 
    14         // At the heart of a Variant is a giant union. 
    15         // It contains a ubyte. 
    16         // Look through that for the size of the typeinfo. 
    17         // Caveat: for large structs, Variant heap-allocates and stores a pointer. 
    18         auto type = actual.type; 
    19         auto b = actual.sizeof; 
    20         if (isStruct(type)) 
    21         { 
    22              
    23         } 
     12        auto result = new Result(expected.same(actual), "same as", expected, actual); 
    2413        return result; 
    2514    } 
  • dunit/trunk/dunit/assertions/variant.d

    r198 r199  
    33import reflect.RuntimeTraits; 
    44import tango.text.convert.Format; 
     5import tango.text.convert.Float; 
     6import tango.io.Stdout; 
    57 
    68const MaxInline = 16; // I'll store 16 bytes in the variant itself 
    79 
     10class VariantTypeMismatchException : Exception 
     11{ 
     12    this (char[] message) { super(message); } 
     13} 
     14 
    815struct Variant 
    916{ 
     17    uint size; 
    1018    /// Data, if I'm storing inline. 
    1119    ubyte[MaxInline] data; 
     
    3139            obj = cast(Object)value; 
    3240        } 
     41        size = T.sizeof; 
    3342        return *this; 
    3443    } 
     
    8190    int opCmp (Variant other) 
    8291    { 
    83         return type.compare (raw, other.raw); 
     92        if (obj && other.obj) 
     93        { 
     94            return obj.opCmp(other.obj); 
     95        } 
     96        else 
     97        { 
     98            return type.compare (raw, other.raw); 
     99        } 
    84100    } 
    85101 
     
    93109    { 
    94110        char[256] buffer; 
    95         return Format.convertOne(buffer, type, raw).dup; 
     111        char[] result; 
     112        if (isFloat(type)) 
     113        { 
     114            result = asFloat(buffer); 
     115        } 
     116        else  
     117        { 
     118            result = Format.convertOne(buffer, type, raw).dup; 
     119        } 
     120        return result; 
     121    } 
     122 
     123    private char[] asFloat(char[] dest) 
     124    { 
     125        const digits = 10; 
     126        const exp = 20; 
     127        char[] result; 
     128        // NOTE: these cannot go into a switch statement. 
     129        // Nothing will ever match! 
     130        if (size == double.sizeof) 
     131        { 
     132            result = tango.text.convert.Float.format(dest, force!(double), digits, exp); 
     133        } 
     134        else if (size == float.sizeof) 
     135        { 
     136            result = tango.text.convert.Float.format(dest, force!(float), digits, exp); 
     137        } 
     138        else if (size == real.sizeof) 
     139        { 
     140            result = tango.text.convert.Float.format(dest, force!(real), digits, exp); 
     141        } 
     142        else 
     143        { 
     144            throw new VariantTypeMismatchException("Type " ~ type.toString ~ ": is a floating point type, but not float, double, or real."); 
     145        } 
     146        return truncate(result); 
     147    } 
     148 
     149    bool safeCast(TypeInfo dest) 
     150    { 
     151        return isImplicitly(type, dest); 
     152    } 
     153 
     154    T to(T)() 
     155    { 
     156        if (!safeCast(typeid(T))) 
     157        { 
     158            throw new VariantTypeMismatchException("Cannot implicitly convert from type " ~ type.toString ~ " to type " ~ T.stringof); 
     159        } 
     160        return force!(T); 
     161    } 
     162 
     163    T force(T)() 
     164    { 
     165        static if (is (T == class) || is (T == interface)) 
     166        { 
     167            return cast(T)obj; 
     168        } 
     169        else 
     170        { 
     171            T t; 
     172            ubyte* ptr = cast(ubyte*)&t; 
     173            ptr[0..T.sizeof] = raw[0..T.sizeof]; 
     174            return t; 
     175        } 
    96176    } 
    97177} 
  • dunit/trunk/tests/variant.d

    r198 r199  
    1212        return bytes == other.bytes; 
    1313    } 
     14 
     15    char[] toString() 
     16    { 
     17        return "I am a Foo! Guar!"; 
     18    } 
    1419} 
    1520 
     
    2328    } 
    2429 
    25     int opEquals (Object other) 
     30    override int opEquals (Object other) 
    2631    { 
    2732        auto bar = cast(Bar) other; 
    2833        return (bar) && (name == bar.name); 
     34    } 
     35 
     36    override int opCmp (Object other) 
     37    { 
     38        auto bar = cast(Bar) other; 
     39        if (!bar) return -1; 
     40        return bar.name[0] - name[0]; 
    2941    } 
    3042 
     
    7688        }; 
    7789 
     90        tests["comparison, integer"] = 
     91        { 
     92            Variant v1 = Variant (5); 
     93            Variant v2 = Variant (7); 
     94            assert (v1 < v2, "less than fail"); 
     95            assert (v2 > v1, "greater than fail"); 
     96        }; 
     97 
     98        tests["set and get, object"] = 
     99        { 
     100            Bar foo = new Bar("strontium"); 
     101            Variant v = Variant (foo); 
     102            assert (v.to!(Bar)().name == "strontium", "wrong value"); 
     103        }; 
     104 
     105        tests["set and get, large struct"] = 
     106        { 
     107            Foo foo; 
     108            foo.bytes[17] = 92; 
     109            Variant v = Variant (foo); 
     110            assert (v.to!(Foo)().bytes[17] == 92, "wrong value"); 
     111        }; 
     112 
     113        tests["set and get, integer"] = 
     114        { 
     115            Variant v = Variant (5); 
     116            assert (v.to!(int) == 5, "wrong value"); 
     117        }; 
     118 
    78119        tests["set and toString, integer"] = 
    79120        { 
     
    110151            assert (!(v1.same (v2)), "same when they should not be"); 
    111152        }; 
     153 
     154        /* These toString tests aren't so essential -- I just use tango's formatting 
     155         * stuff. But this is a pretty important thing, so I want to spend some time on it. */ 
     156        tests["toString, bool"] = 
     157        { 
     158            assert (Variant(true).toString == "true", Variant(true).toString); 
     159            assert (Variant(false).toString == "false", Variant(false).toString); 
     160        }; 
     161 
     162        tests["toString, decimal, no trailing zeroes"] = 
     163        { 
     164            auto v = Variant(15.0); 
     165            assert (v.toString == "15", v.toString); 
     166        }; 
     167 
     168        tests["toString, decimal"] = 
     169        { 
     170            auto v = Variant(15.625); 
     171            assert (v.toString == "15.625", v.toString); 
     172        }; 
     173 
     174        tests["toString, class"] = 
     175        { 
     176            auto bar = new Bar("hihi"); 
     177            auto v = Variant(bar); 
     178            assert (v.toString == bar.toString, v.toString); 
     179        }; 
     180 
     181        tests["toString, struct"] = 
     182        { 
     183            Foo bar; 
     184            auto v = Variant(bar); 
     185            assert (v.toString == bar.toString, v.toString); 
     186        }; 
     187 
     188        tests["toString, integer"] = 
     189        { 
     190            assert (Variant(5).toString == "5", Variant(5).toString); 
     191            assert (Variant(-109).toString == "-109", Variant(-109).toString); 
     192        }; 
    112193    } 
    113194}