How to obtain certain traits of delegates returned by functions in template constraints?
DoctorCaptain
garble at harble.com
Sat Dec 14 14:38:19 PST 2013
>
> Most uses of the 'is expression' allows using a specifier to
> name the entity that matched. So, inserting ReturnedDelegate in
> your '== delegate' line gives the name ReturnedDelegate to the
> delegate.
>
> That name can be used further:
>
> template exT(T, alias nextGen)
> if (
> // Ensure nextGen is a callable entity
> isCallable!nextGen == true
> // Ensure nextGen returns a delegate
> && is(ReturnType!nextGen ReturnedDelegate == delegate)
> // <--
> // Ensure nextGen takes one argument
> && arity!nextGen == 1
> // Ensure that argument is of type T
> && is(ParameterTypeTuple!nextGen[0] == T)
> // Ensure the returned delegate returns type T
> && is(ReturnType!ReturnedDelegate == T)
> // Ensure the arity and parameter type of the delegate
> // && arity!ReturnedDelegate == 1
> && ParameterTypeTuple!ReturnedDelegate.length == 1 //
> <--
> && is(ParameterTypeTuple!ReturnedDelegate[0] == int) //
> <--
> )
> {
> // ...
> }
>
> However, since arity() takes an alias but ReturnedDelegate is a
> type, I could not make it work. So, I use the length of the
> parameter type tuple instead.
>
> You can put all of those checks into a template and pass T and
> nextGen to it:
>
> template exT(T, alias nextGen)
> if SatisfiesMyConditions!(T, nextGen)
> {
> // ...
> }
>
> I haven't attempted writing it but it will be similar to the
> following syntax:
>
> template canFlyAndLand(T)
> {
> enum canFlyAndLand = is (typeof(
> {
> T object;
> object.prepare(); // should be preparable for flight
> object.fly(1); // should be flyable for a certain
> distance
> object.land(); // should be landable
> }()));
> }
>
> I've copied that example from under the "Named constraints"
> section at
>
> http://ddili.org/ders/d.en/templates_more.html
>
> Phobos implementation has many examples of that as well.
>
> Ali
Thank you! This is excellent, and I'll make great use of your
suggestions.
> I would think you can check the delegate signature directly
> without decomposing it. Something like this:
>
> is(ReturnType!nextGen == T delegate (int))
This is a very concise way to do what I want to do, but this
check cares about other attributes of the function/delegate, i.e.
if the function or delegate is designated as pure or nothrow and
those don't show up in the check, it will fail. As in:
auto nextGen()
{
T genFunc(int x) nothrow
{
return 0;
}
return &genFunc;
}
genFunc will fail the is() check because the is check cares
whether the delegate is nothrow or not. Since I want folks to be
able to use my algorithm without caring about the implementation
details, I need to provide constraints for the parameter lists
and return types of their functions, but no constraints on
whatever attributes they want to slap onto their functions. I
will keep this in my toolbox, but I'll have to take the more
long-winded approach this time around.
Thank you both!
More information about the Digitalmars-d-learn
mailing list