[Issue 2073] Variant.coerce!() fails

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sat Feb 6 19:27:05 PST 2010


http://d.puremagic.com/issues/show_bug.cgi?id=2073


Michael Rynn <y0uf00bar at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |y0uf00bar at gmail.com


--- Comment #1 from Michael Rynn <y0uf00bar at gmail.com> 2010-02-06 19:27:01 PST ---
I looked at coerce because I was trying to make the std.variant pass some of
the tango.core.Variant unit tests. 

coerce needs runtime type checking, and must thereby incur a small runtime
penalty.

As well as the this, there is a failure of cast coercions for object and
interface.


T coerce(T)()
{
   // coerce is awkward because it also depends on the runtime type
    static string coerceMsg(TypeInfo t1, TypeInfo t2)
    {
        return format("Coerce from %s to %s", t1.toString, t2.toString);
    }

    static if (isNumeric!(T))
    {
      // coercive conversions will have a time penalty
      if (type == typeid(immutable(char)[]))
      {
        return to!(T)(*cast(string*)&store);
      } 
      // also do wstring and dstring ?     
      return to!(T)(get!(real));
    }
    else static if( is(T : Object) )
    {

         if (cast(TypeInfo_Class)type)
            {
                return to!(T) (( *cast(Object*) &store ));
            }
            if (cast(TypeInfo_Interface)type)
            {
                // ugly magic borrowed from object.d, to get the original
object and recast
                // why is there no direct facility for this?  like
interface.objectof property?
                // the not quite the same ugliness in _d_toObject in cast_.d
does not work
                void* p = &store;
                Interface* pi = **cast(Interface ***)*cast(void**)p;
                Object o = cast(Object)(*cast(void**)p - pi.offset);
                return to!(T)(o);
            } 
            throw new VariantException(coerceMsg(type, typeid(T)));    

         }
         else static if (is (T == interface ))
         {
            if (cast(TypeInfo_Class)type)
            {    
                return to!(T) (( *cast(Object*) &store ));
            }
            if (cast(TypeInfo_Interface)type)
            {

                void* p = &store;
                Interface* pi = **cast(Interface ***)*cast(void**)p;
                Object o = cast(Object)(*cast(void**)p - pi.offset);

                return to!(T)(o); 
            }
            throw new VariantException(coerceMsg(type, typeid(T)));    
         }
         else static if (isSomeString!(T))
        {
            return to!(T)(toString);
        }
        else
        {
            // Fix for bug 1649
            static assert(false, "unsupported type for coercion");
        }
    }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list