Differing levels of type-inference: Can D do this?
Simen Kjaeraas
simen.kjaras at gmail.com
Sun Jul 29 05:32:11 PDT 2012
On Sat, 28 Jul 2012 22:47:01 +0200, Chad J
<chadjoan at __spam.is.bad__gmail.com> wrote:
> isInputRange!___ r2 = [1,2,3].some.complex.expression();
>
> It doesn't make sense. isInputRange!() isn't a type, so how do I
> constrain what type is returned from some arbitrary expression?
>
> So far the only way I know how to do this is to pass it through a
> template and use template constraints:
>
> auto makeSureItsARange(T)(T arg) if ( isInputRange!T )
> {
> return arg;
> }
>
> auto r2 = makeSureItsARange([1,2,3].some.complex.expression());
>
> however, the above is unreasonably verbose and subject to naming whimsy.
import std.typetuple : allSatisfy;
template checkConstraint( T ) {
template checkConstraint( alias Constraint ) {
enum checkConstraint = Constraint!T;
}
}
template constrain( T... ) {
auto constrain( U, string file = __FILE__, int line = __LINE__ )( auto
ref U value ) {
static assert( allSatisfy!( checkConstraint!U, T ), "Type " ~
U.stringof ~ " does not fulfill the constraints " ~ T.stringof );
return value;
}
}
version (unittest) {
import std.range : isInputRange, ElementType;
template hasElementType( T ) {
template hasElementType( U ) {
enum hasElementType = is( ElementType!U == T );
}
}
}
unittest {
assert( __traits( compiles, { int[] a = constrain!isInputRange(
[1,2,3] ); } ) );
assert( !__traits( compiles, { int a = constrain!isInputRange( 2 );
} ) );
assert( __traits( compiles, { int[] a = constrain!(isInputRange,
hasElementType!int)( [1,2,3] ); } ) );
assert( __traits( compiles, { string a = constrain!(isInputRange,
hasElementType!dchar)( "abc" ); } ) );
assert( !__traits( compiles, { string a = constrain!(isInputRange,
hasElementType!dchar)( "abc"w ); } ) );
}
So there. Now, you simply use auto a = constrain!isInputRange( expression
);. Is this what you wanted?
--
Simen
More information about the Digitalmars-d-learn
mailing list