On Wednesday, August 24, 2011 11:00 Timon Gehr wrote: > On 08/24/2011 07:54 PM, Steven Schveighoffer wrote: > > On Wed, 24 Aug 2011 13:40:38 -0400, Andrej Mitrovic > > > > <[email protected]> wrote: > >> Here's what I can do with a variadic function: > >> > >> void main() > >> { > >> int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5]; > >> > >> process(a[a.countUntil(7) .. $]); > >> process(1); > >> } > >> > >> void process(int[] vals...) > >> { > >> foreach (val; vals) > >> { > >> } > >> } > >> > >> Very simple, pass one or multiple arguments. But then I thought about > >> using the `until` template instead of countUntil. However `until` > >> returns a range. So my next guess was to write: > >> > >> void main() > >> { > >> int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5]; > >> > >> process(a.until(7)); // ok > >> process(4); // error since 4 is not a range > >> } > >> > >> void process(Range)(Range vals) if (isInputRange!Range && > >> is(ElementType!Range == int)) > >> { > >> foreach (val; vals) > >> { > >> } > >> } > >> > >> Is it somehow possible to automatically convert a literal to a range? > >> I really miss the convenience of variadic functions. I thought about > >> making an overload that only takes an int and constructing a simple > >> input range around it so it can be passed to process(), e.g.: > >> > >> void process(Range)(Range vals) if (isInputRange!Range && > >> is(ElementType!Range == int)) > >> { > >> foreach (val; vals) > >> { > >> } > >> } > >> > >> void process(int arg) > >> { > >> process(makeInputRange(arg)); // make an input range, pass to > >> above process() > >> } > >> > >> But I can't overload templated and non-templated functions, I think > >> this is one of those old-standing bugs. > > > > maybe: > > > > void process(Range)(Range vals) if (isInputRange!Range && > > is(ElementType!Range == int)) > > { > > ... > > } > > > > void process(Vals...)(Vals vals) if (allValsElementsAreInt) > > { > > ... > > } > > > > Note that I'm not sure what to put for allValsElementsAreInt... > > > > -Steve > > This should do (although it would probably be even better to have a > forAll template and a predicate template). > > template allElementsAreInt(T...){ > static if(T.length==0) enum allElementsAreInt=true; > else enum allElementsAreInt=is(typeof(T[0])==int) > && allElementsAreInt!(T[1..$]); > }
std.typetuple has anySatisfy and allSatisfy (though that's a rather bizarre place to put them IMHO). - Jonathan M Davis
