www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using allSatisfy with template that takes multiple type arguments

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
import std.typetuple;
import std.traits;

alias TypeTuple!(int, float) MyTypes;
template isCompatible(T)
{
    enum bool isCompatible = allSatisfy!(isImplicitlyConvertible!T, MyTypes);
}

This won't work since the compiler tries to instantiate
isImplicitlyConvertible with a single type (it takes two types).

The reason I'm doing this is to catch bad arguments inside of a static
assert so I can give out better error messages and optionally provide
a tip (based on a version switch). The above won't work, so do you
know of a workaround?
Sep 26 2011
next sibling parent reply David Nadlinger <see klickverbot.at> writes:
On 9/26/11 9:32 PM, Andrej Mitrovic wrote:
 alias TypeTuple!(int, float) MyTypes;
 template isCompatible(T)
 {
      enum bool isCompatible = allSatisfy!(isImplicitlyConvertible!T, MyTypes);
 }

template PApply(alias Target, T...) { template PApply(U...) { alias Target!(T, U) PApply; } } … enum isCompatible = allSatisfy!(PApply!(isImplicitlyConvertible, T), MyTypes); David
Sep 26 2011
next sibling parent travert phare.normalesup.org (Christophe) writes:
Andrej Mitrovic , dans le message (digitalmars.D.learn:29825), a écrit :
 Thanks for the tips guys. I have another similar issue now, I want to
 check whether a type passes any of the predicates I list. This would
 be similar to anySatisfy, however anySatisfy takes one predicate and
 multiple types, and what I need is one type and multiple predicates,
 e.g.:
 
 anyPredicateSatisfy!(int, isNumeric, isIntegral);
 
 I've tried copying anySatisfy's code and modifying it to work:
 
 template anyPredicateSatisfy(T, F...)
 {
     static if (F.length == 0)
     {
         enum bool anySatisfy = false;
     }
     else static if (F.length == 1)
     {
         enum bool anySatisfy = (F[0])!T;
     }
     else
     {
         enum bool anySatisfy = (F[0])!T) || anySatisfy!(T, F[1 .. $]);

     }
 }
 
 But the compiler thinks I'm doing C-style casts so this doesn't work. Any
clues?

Sep 28 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 But the compiler thinks I'm doing C-style casts so this doesn't work. Any
clues?

This seems to work (eye the base of the recursion): template satisfies(T, alias P) { enum satisfies = P!T; } template anyPredicateSatisfy(T, Preds...) { static if (Preds.length) //enum bool anyPredicateSatisfy = (Preds[0]!T) || anyPredicateSatisfy!(T, Preds[1 .. $]); enum bool anyPredicateSatisfy = satisfies!(T, Preds[0]) || anyPredicateSatisfy!(T, Preds[1 .. $]); else enum bool anyPredicateSatisfy = false; } template is4(T) { enum is4 = T.sizeof == 4; } template signed(T) { enum signed = T.min != 0; } static assert(anyPredicateSatisfy!(int, is4, signed)); void main() {} Maybe the error on (Preds[0]!T) is fodder for Bugzilla. Bye, bearophile
Sep 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Thanks for the tips guys. I have another similar issue now, I want to
check whether a type passes any of the predicates I list. This would
be similar to anySatisfy, however anySatisfy takes one predicate and
multiple types, and what I need is one type and multiple predicates,
e.g.:

anyPredicateSatisfy!(int, isNumeric, isIntegral);

I've tried copying anySatisfy's code and modifying it to work:

template anyPredicateSatisfy(T, F...)
{
    static if (F.length == 0)
    {
        enum bool anySatisfy = false;
    }
    else static if (F.length == 1)
    {
        enum bool anySatisfy = (F[0])!T;
    }
    else
    {
        enum bool anySatisfy = (F[0])!T) || anySatisfy!(T, F[1 .. $]);
    }
}

But the compiler thinks I'm doing C-style casts so this doesn't work. Any clues?
Sep 27 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Thanks, that works. I'll report the bug as well.
Sep 28 2011