Re: Using allSatisfy with template that takes multiple type arguments
Thanks, that works. I'll report the bug as well.
Re: Using allSatisfy with template that takes multiple type arguments
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
Re: Using allSatisfy with template that takes multiple type arguments
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 .. $]); ^ you mean anyPredicateSatisfy > } > } > > But the compiler thinks I'm doing C-style casts so this doesn't work. Any > clues?
Re: Using allSatisfy with template that takes multiple type arguments
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?
Re: Using allSatisfy with template that takes multiple type arguments
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
Re: Using allSatisfy with template that takes multiple type arguments
On Mon, Sep 26, 2011 at 21:40, Andrej Mitrovic wrote: > Actually now that I think about it, isOneOf!() is more to my liking. > isImplicitlyConvertible allows too much, e.g. implicit casting of > unsigned to signed. Even though that might be perfectly valid, I want > to optionally allow a warning via a version switch. So I'll be using > isOneOf. In any case, concerning your initial question, a possibility is to curry the template: template isCompatible(T) { enum isCompatible = allSatisfy!(isIC!T, MyTypes); } template isIC(First) { template isIC(Second) { enum isIC = isImplicitlyConvertible!(First, Second); } } So, isIC!T yields *another* template (also named isIC), that will accept one type and be mapped on MyTypes by allSatisfy. What's cool is that the second-level template remembers First. It's a bit like a closure, but on types.
Re: Using allSatisfy with template that takes multiple type arguments
Actually now that I think about it, isOneOf!() is more to my liking. isImplicitlyConvertible allows too much, e.g. implicit casting of unsigned to signed. Even though that might be perfectly valid, I want to optionally allow a warning via a version switch. So I'll be using isOneOf.
Using allSatisfy with template that takes multiple type arguments
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?