www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5719] New: [patch] std.conv.to should support structs with custom converters in addition to objects

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719

           Summary: [patch] std.conv.to should support structs with custom
                    converters in addition to objects
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: patch
          Severity: normal
          Priority: P3
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: sandford jhu.edu



Currently std.conv.to allows classes to define custom conversion routines to
non-class types, but doesn't provide structs with the same functionality. This
functionality can be extended to structs by a minor change in one of the toImpl
template constraints from
is(S : Object) && !is(T : Object)
to 
((is(S : Object) && !is(T : Object)) || is(S == struct))

The particular toImpl is currently located at Line 687 in git (line 680 in DMD
2.051) and has been reproduced in full below with the patch, along with an
updated unit test. The patch passes the unit tests below and the unit tests in
my current fork of std.variant and std.json, but I haven't tested it against
the entire phobos test suite.

/**
Object-_to-non-object conversions look for a method "to" of the source
object.

Example:
----
class Date
{
    T to(T)() if(is(T == long))
    {
        return timestamp;
    }
    ...
}

unittest
{
    debug(conv) scope(success) writeln("unittest  ", __FILE__, ":", __LINE__, "
succeeded.");
    auto d = new Date;
    auto ts = to!long(d); // same as d.to!long()
}
----
 */
T toImpl(T, S)(S value) if ( ((is(S : Object) && !is(T : Object)) || is(S ==
struct)) && !isSomeString!T
        && is(typeof(S.init.to!(T)()) : T))
{
    return value.to!T();
}

unittest
{
    debug(conv) scope(success) writeln("unittest  ", __FILE__, ":", __LINE__, "
succeeded.");
    class B { T to(T)() { return 43; } }
    auto b = new B;
    assert(to!int(b) == 43);
    struct C { T to(T)() { return 43; } }
    C c;
    assert(to!int(c) == 43);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 07 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719




I've noticed that with generic code that

Target toImpl(Target, Source)(Source value)
if (implicitlyConverts!(Source, Target))

can cause an error via multiple template matches with

T toImpl(T, S)(S value) if (is(S : Object) && is(T : Object))

and

T toImpl(T, S)(S value)
    if (((is(S : Object) && !is(T : Object)) || is(S == struct))
    && !isSomeString!T && is(typeof(S.init.to!(T)()) : T))

Both issues can be simply fixed by adding an additional template constraint:
    && !implicitlyConverts!(S,T)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 01 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719


Jonathan M Davis <jmdavisProg gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmdavisProg gmx.com
           Severity|normal                      |enhancement



PDT ---
There are several pull requests affect std.conv.to at the moment which will
change the situation and which will likely be merged in soon. Among other
things, they get rid of the member function to conversion and make std.conv.to
work with overloaded opCast.

https://github.com/D-Programming-Language/phobos/pull/118
https://github.com/D-Programming-Language/phobos/pull/119
https://github.com/D-Programming-Language/phobos/pull/122

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 01 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719





 https://github.com/D-Programming-Language/phobos/pull/118
 https://github.com/D-Programming-Language/phobos/pull/119
 https://github.com/D-Programming-Language/phobos/pull/122
The three pull requests are already merged, and now std.conv.to supports both two kinds of custom conversions: 1) object to non-object conversion with opCast to!T(s) --> s.opCast!T() 2) non-object to object conversion with construction to!T(s) --> new T(s) // if T is class T(s) // if T is struct Today, is this a closable issue? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 09 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719






 https://github.com/D-Programming-Language/phobos/pull/118
 https://github.com/D-Programming-Language/phobos/pull/119
 https://github.com/D-Programming-Language/phobos/pull/122
The three pull requests are already merged, and now std.conv.to supports both two kinds of custom conversions: 1) object to non-object conversion with opCast to!T(s) --> s.opCast!T() 2) non-object to object conversion with construction to!T(s) --> new T(s) // if T is class T(s) // if T is struct Today, is this a closable issue?
By 'object' do you mean both classes and structs? Specifically, these conversions seem to be missing: 3) non-object to non-object conversion with opCast to!T(s) --> s.opCast!T() 4) non-object to non-object conversion with construction to!T(s) T(s) // if T is struct But this might be a case of semantics, not implementation. (I generally don't refer to structs as 'objects') -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 09 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719




PDT ---
Structs are very much objects. Whether something is an object or not has
nothing to do with whether it's a reference type or a value type. Take C++ for
example. In C++, classes are generally value types rather than reference types,
but they're very much objects. The same goes for whether an object is
polymorphic or not. It's an object regardless of whether it's polymorphic. The
concept of an object in OO programming has nothing to do with the difference
between a struct and a class in D.

You're going to confuse people and generally be confused by others if you refer
to instances of structs as if they weren't objects. If you want to be clear
about the differences between structs and classes, you need to refer to structs
and classes and not try and use the term object to differentiate them.
Instances of both are objects.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 09 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719


Brad Roberts <braddr puremagic.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |braddr puremagic.com



---
Careful, given that the name of the entity at the root of the hierarchy of
classes is called 'Object', which structs have no relationship to, there is an
ambiguity in terminology.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 09 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719




PDT ---
True, there's a difference between something which is an instance of Object and
something which is an object. But D structs are still very much OO and are
definitely objects.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 09 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719




Created an attachment (id=1106)
Reduced test case for weird cast behavior.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 19 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5719


meh. <meh paranoici.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |meh paranoici.org



Sorry for that, bugzilla did something funny, I don't know why it attached that
to this bug.

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