Thread overview
Re: Is there a standard way to define to for user-defined types?
Jun 20, 2011
Andrej Mitrovic
Jun 20, 2011
Andrej Mitrovic
Jun 20, 2011
Jonathan M Davis
Jun 20, 2011
kenji hara
Jun 23, 2011
kenji hara
June 20, 2011
I thought std.conv.to already looks for to member functions, at least for structs? I'm sure I've seen it in std.conv.
June 20, 2011
Ah, this is what I did found:

Line 665 in std.conv:

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

So I guess this can be expanded upon to cover object-to-object conversions, maybe?
June 20, 2011
On 2011-06-19 20:40, Andrej Mitrovic wrote:
> Ah, this is what I did found:
> 
> Line 665 in std.conv:
> 
> /**
> Object-_to-non-object conversions look for a method "to" of the source
> object.
> */
> 
> So I guess this can be expanded upon to cover object-to-object conversions, maybe?

Hmmm. I wonder why it's restricted to converting to primitive types. I can't think of any reason why it would, but presumably whoever wrote it had a good reason for doing so. Seeing that though, my first reaction would be to make it work with object-to-object conversions as well.

- Jonathan M Davis
June 20, 2011
I have tried to conversion test.
----
import std.conv;

void main()
{
    tests1();
    tests2();
    testc1();
    testc2();
}

struct SS1{ ST1 opCast(T:ST1)(){ return ST1(); } }
struct ST1{  }
void tests1()
{
    SS1 s1;
    auto t1a = cast(ST1)(s1);       // -> s1.opCast!ST1()
//  auto t1b = to!ST1(s1);          // NG
}

struct SS2{  }
struct ST2{ this(SS2 source){} }
void tests2()
{
    SS2 s2;
    auto t2a = cast(ST2)(s2);       // -> ST2(s2) == ctor call
//  auto t2b = to!ST2(s2);          // NG
}

class CS1{ CT1 opCast(T:CT1)(){ return new CT1(); } }
class CT1{  }
void testc1()
{
    CS1 s1 = new CS1();
    auto t1a = cast(CT1)(s1);       // -> s1.opCast!CT1()
    auto t1b = to!CT1(s1);
        // T toImpl(T, S)(S value) if (is(S : Object) && is(T : Object))
        // -> cast(CT1)(s1)
        // -> s1.opCast!CT1()
}

class CS2{  }
class CT2{ static CT2 opCall(CS2 source){ return new CT2(); } }
//class CT2{ this(CS2 source){} }   // Unfortunately, ctor is not
called by CastExp.
void testc2()
{
    CS2 s2 = new CS2();
    auto t2a = cast(CT2)(s2);       // -> CT2(s2) == CT2.opCall(s2)
//  auto t2b = to!CT2(s2);          // compiled, but runtime error occurs
        // T toImpl(T, S)(S value) if (is(S : Object) && is(T : Object))
        // -> cast(CT1)(s1)
        // -> null
}
----

Some of thoughts of me:
1. std.conv.to should support built-in casting behavior, at least on
struct object.
   This feature was recently fixed. See bug5897.
2. Using to!T() member function by std.conv.to is unnecessary feature,
because it can be replaced by opCast!T.
3. For class object, I guess that is need to support 'Conversion
Interface that Intrude into TargetType'.
   I think 'conversion constructor call' is good fit to it.

Kenji
June 20, 2011
On 6/20/11 7:14 AM, kenji hara wrote:
> I have tried to conversion test.
> ----
> import std.conv;
>
> void main()
> {
>      tests1();
>      tests2();
>      testc1();
>      testc2();
> }
>
> struct SS1{ ST1 opCast(T:ST1)(){ return ST1(); } }
> struct ST1{  }
> void tests1()
> {
>      SS1 s1;
>      auto t1a = cast(ST1)(s1);       // ->  s1.opCast!ST1()
> //  auto t1b = to!ST1(s1);          // NG
> }
>
> struct SS2{  }
> struct ST2{ this(SS2 source){} }
> void tests2()
> {
>      SS2 s2;
>      auto t2a = cast(ST2)(s2);       // ->  ST2(s2) == ctor call
> //  auto t2b = to!ST2(s2);          // NG
> }
>
> class CS1{ CT1 opCast(T:CT1)(){ return new CT1(); } }
> class CT1{  }
> void testc1()
> {
>      CS1 s1 = new CS1();
>      auto t1a = cast(CT1)(s1);       // ->  s1.opCast!CT1()
>      auto t1b = to!CT1(s1);
>          // T toImpl(T, S)(S value) if (is(S : Object)&&  is(T : Object))
>          // ->  cast(CT1)(s1)
>          // ->  s1.opCast!CT1()
> }
>
> class CS2{  }
> class CT2{ static CT2 opCall(CS2 source){ return new CT2(); } }
> //class CT2{ this(CS2 source){} }   // Unfortunately, ctor is not
> called by CastExp.
> void testc2()
> {
>      CS2 s2 = new CS2();
>      auto t2a = cast(CT2)(s2);       // ->  CT2(s2) == CT2.opCall(s2)
> //  auto t2b = to!CT2(s2);          // compiled, but runtime error occurs
>          // T toImpl(T, S)(S value) if (is(S : Object)&&  is(T : Object))
>          // ->  cast(CT1)(s1)
>          // ->  null
> }
> ----
>
> Some of thoughts of me:
> 1. std.conv.to should support built-in casting behavior, at least on
> struct object.
>     This feature was recently fixed. See bug5897.

Agreed. I simply forgot about that.

> 2. Using to!T() member function by std.conv.to is unnecessary feature,
> because it can be replaced by opCast!T.

I think that's fine too.

> 3. For class object, I guess that is need to support 'Conversion
> Interface that Intrude into TargetType'.
>     I think 'conversion constructor call' is good fit to it.

Not sure I understand that.

Kenji, you may want to package your 1 and 2 into a pull request, and 3 in a separate pull request so we all can take a look.


Thanks,

Andrei

June 23, 2011
2011/6/21 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:
> Kenji, you may want to package your 1 and 2 into a pull request, and 3 in a separate pull request so we all can take a look.

Just now I sent pull request #118 and #119.

BTW, the functions are included in std.conv have odd order. This is what was intended?

Kenji
June 23, 2011
On 6/23/11 5:19 PM, kenji hara wrote:
> 2011/6/21 Andrei Alexandrescu<SeeWebsiteForEmail@erdani.org>:
>> Kenji, you may want to package your 1 and 2 into a pull request, and 3 in a
>> separate pull request so we all can take a look.
>
> Just now I sent pull request #118 and #119.

Perfect.

> BTW, the functions are included in std.conv have odd order.
> This is what was intended?

If you find any way to improve the order, please have at it.

Thanks

Andrei