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