On Wednesday, 12 June 2013 at 09:16:30 UTC, Timothee Cour wrote:
Why not use a castConstSafe function that'll transform A!T into
A!(const
T), generically:
auto ref castSafe(T,S)(auto ref S a){...}
S a; T b=castSafe!T(a); //same as T b=cast(T)(a) except that it
only
compiles if S=>T only involves nonconst=>const conversions
(works
recursively):
example: A!(double) => A!(const double) is allowed but not
other direction.
More specifically:
auto ref castConstSafe(S)(auto ref S a){...} //transforms A!T
into A!(const
T), generically
then:
void foo(B a) if (is(ElementType!B == const)){...}
A!(const double) a1;
A!(double) a2;
foo(a1.castConstSafe); //works
foo(a2.castConstSafe); //works
All it requires is to pass a.castConstSafe instead of a.
Because Foo!T and Foo!(const T) are completely unrelated types.
Casting from one to the other gives 0 guarantees it actually
works. For example:
//----
struct Foo(T)
{
static if (is(T == const int))
{
void do_it()const{writeln("this");}
}
else
{
void do_it()const{writeln("that");}
}
}
void main()
{
Foo!int a;
const(Foo!int)* pa = &a;
Foo!(const int)* pb = cast(Foo!(const int)*) &a;
pa.do_it(); //prints "that"
pb.do_it(); //prints "this"
}
//----
Of course, I could have also changed the members, making memory
mapping incompatible, amongst others...