Thread overview
Creating a template mixin for explicit casts.
May 17, 2018
Sjoerd Nijboer
May 17, 2018
Paul Backus
May 17, 2018
Sjoerd Nijboer
May 17, 2018
Sjoerd Nijboer
May 17, 2018
Meta
May 17, 2018
Given the following code
`struct Foo(T)
	if(isNumeric!T)
{
	T t;
	.. other code
}

struct Bar(T)
	if(isNumeric!T)
{
	T t;
	.. other code
}

Foo!float foo_float;

Foo!double foo_double;

Bar!float bar_float;
`

I want to make a template mixin that is able to cast one of these generic structs to the other explicitly. I have a bunch of these structs and therefore I thought it would make sense to do it by template mixin. I just don't know what language or library features I need to use and how to apply them.

`
fooDouble = cast (Foo!double) foo_float;		// case [1] if possible, done by
							// an implicit cast. Else by
							//explicit.

fooFloat = cast (Foo!float) foo_double;			// case [2]

barFloat = cast (Bar!float) foo_float;			// case [3]
`

How would I do this in D?
May 17, 2018
On Thursday, 17 May 2018 at 15:25:37 UTC, Sjoerd Nijboer wrote:
> I want to make a template mixin that is able to cast one of these generic structs to the other explicitly. I have a bunch of these structs and therefore I thought it would make sense to do it by template mixin. I just don't know what language or library features I need to use and how to apply them.

It sounds like you want to overload opCast:

https://dlang.org/spec/operatoroverloading.html#cast
May 17, 2018
On Thursday, 17 May 2018 at 15:25:37 UTC, Sjoerd Nijboer wrote:
> Given the following code
> `struct Foo(T)
> 	if(isNumeric!T)
> {
> 	T t;
> 	.. other code
> }
>
> struct Bar(T)
> 	if(isNumeric!T)
> {
> 	T t;
> 	.. other code
> }
>
> Foo!float foo_float;
>
> Foo!double foo_double;
>
> Bar!float bar_float;
> `
>
> I want to make a template mixin that is able to cast one of these generic structs to the other explicitly. I have a bunch of these structs and therefore I thought it would make sense to do it by template mixin. I just don't know what language or library features I need to use and how to apply them.
>
> `
> fooDouble = cast (Foo!double) foo_float;		// case [1] if possible, done by
> 							// an implicit cast. Else by
> 							//explicit.
>
> fooFloat = cast (Foo!float) foo_double;			// case [2]
>
> barFloat = cast (Bar!float) foo_float;			// case [3]
> `
>
> How would I do this in D?

Before you write anything yourself, check whether std.conv.castFrom does what you need:

https://dlang.org/phobos/std_conv.html#castFrom
May 17, 2018
On Thursday, 17 May 2018 at 16:27:48 UTC, Paul Backus wrote:
> On Thursday, 17 May 2018 at 15:25:37 UTC, Sjoerd Nijboer wrote:
>> I want to make a template mixin that is able to cast one of these generic structs to the other explicitly. I have a bunch of these structs and therefore I thought it would make sense to do it by template mixin. I just don't know what language or library features I need to use and how to apply them.
>
> It sounds like you want to overload opCast:
>
> https://dlang.org/spec/operatoroverloading.html#cast

Something like:
`
Foo!T opCast(U)(Foo!U old)
	if (isImplicitlyConvertible!(T, U))
	{
		return Foo!T(old.t);
	}

Foo!T opCast(UTemplate, U)(UTemplate!U old)
	if (isImplicitlyConvertible!(T, U) && isNumerical!U)
	{
		return Foo!T(old.t);
	}

`
But then how do you put this into a mixin template so I can write something like
`
struct Foo(T)
	if(isNumerical(T))
{
	mixin castingRules(typeof(this) T);
}
`
May 17, 2018
On Thursday, 17 May 2018 at 20:38:13 UTC, Sjoerd Nijboer wrote:
> But then how do you put this into a mixin template so I can ...
> 	mixin castingRules(typeof(this) T);

I guess I can refine my question to "How do you let a mixin template detect the template name it is instantiated with and return its type whitout the template arguments.