Unstandard

Type casting functions.

Functions from this module are intended to be used instead of build-in cast as they provide safer and richer interface.

License
Boost License 1.0.
Authors
Denis Shelomovskij

template  typesDynamicCastable(To, From)
@trusted inout(To)  tryDynamicCast(To, From)(inout(From) o) if (typesDynamicCastable!(To, From));
@trusted bool  dynamicCastable(To, From)(inout(From) o) if (typesDynamicCastable!(To, From));
@trusted inout(To)  dynamicCast(To, From)(inout(From) o) if (typesDynamicCastable!(To, From));
template  typesDowncastable(To, From)
@trusted inout(To)  tryDowncast(To, From)(inout(From) o) if (typesDowncastable!(To, From));
@trusted bool  downcastable(To, From)(inout(From) o) if (typesDowncastable!(To, From));
@trusted inout(To)  downcast(To, From)(inout(From) o) if (typesDowncastable!(To, From));
template  typesUpcastable(To, From)
@trusted inout(To)  upcast(To, From)(inout(From) o) if (typesUpcastable!(To, From));
@trusted inout(void)*  toRawPtr(From)(inout(From) o) if (is(From == class) || is(From == interface));
@system inout(To)  fromRawPtr(To)(inout(void)* p) if (is(To == class) || is(To == interface));

Functions for class/interface dynamic casting.

These functions don't change type qualifier.

toRawPtr/fromRawPtr should be used to safely convert class instances to raw void* instead of viewAs because interface variables don't point to a beginning of a class instance.

Preconditions:
Passed object (pointer for fromRawPtr) is not null.
Note:
alias this isn't considered while casting in contrary to build-in cast.
Examples
class A { }
class B { }

A a = new A;
Object o = a;
assert(o.downcast!A is a);
assert(!o.downcastable!B);
static assert(!__traits(compiles, a.dynamicCast!B)); // cast impossible
Examples
interface I { }
class A : I { }

A a = new A;
I i = a;
void* p = a.toRawPtr;
// `i` doesn't point to a beginning of a class instance:
assert(i.viewAs!(void*) != p);
assert(i.toRawPtr == p);
assert(p.fromRawPtr!I is a); // `fromRawPtr` is `@system`

@system inout(To)  viewAs(To, From)(inout(From) val);
@system inout(To)  viewAs(To, From)(ref inout(From) val);

Function allowing "blind" casting to any type of the same size.

No operations on actial value performed. It is just treated as having different type.

These functions don't change type qualifier.

Note:
alias this isn't considered while casting in contrary to build-in cast.
Warning:
Resulting value may depend on target architecture.
Examples
int i = 0;
i.viewAs!(ubyte[4]) = 3;
assert(i == 0x03030303);