www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is it possible to filter variadics?

reply maik klein <maikklein googlemail.com> writes:
Is it possible to filter variadics for example if I would call

void printSumIntFloats(Ts...)(Ts ts){...}

printSumIntFloats(1,1.0f,2,2.0f);

I want to print the sum of all integers and the sum of all floats.


//Pseudo code
void printSumIntFloats(Ts...)(Ts ts){
     auto sumOfInts = ts
                       .filter!(isInteger)
                       .reduce(a => a + b);
     writeln(sumOfInts);
     ...
}

Is something like this possible?
Nov 03 2015
next sibling parent TheFlyingFiddle <borin.lukas gmail.com> writes:
On Tuesday, 3 November 2015 at 23:41:10 UTC, maik klein wrote:
 Is it possible to filter variadics for example if I would call

 void printSumIntFloats(Ts...)(Ts ts){...}

 printSumIntFloats(1,1.0f,2,2.0f);

 I want to print the sum of all integers and the sum of all 
 floats.


 //Pseudo code
 void printSumIntFloats(Ts...)(Ts ts){
     auto sumOfInts = ts
                       .filter!(isInteger)
                       .reduce(a => a + b);
     writeln(sumOfInts);
     ...
 }

 Is something like this possible?
It is possible: I don't think that reduce works on tuples but you could do something like this. import std.traits, std.meta; void printsumIntFloats(Ts...)(Ts ts) { alias integers = Filter!(isInteger, Ts); alias floats = Filter!(isFloatingPoint, Ts); alias int_t = CommonType!(integers); alias float_t = CommonType!(floats); int_t intres = 0; float_t floatres = 0; foreach(i, arg; ts) { static if(isInteger!(Ts[i])) intres += arg; else floatres += arg; } writeln(intres); writeln(floatres); }
Nov 03 2015
prev sibling parent reply Jakob Ovrum <jakobovrum gmail.com> writes:
On Tuesday, 3 November 2015 at 23:41:10 UTC, maik klein wrote:
 Is it possible to filter variadics for example if I would call

 void printSumIntFloats(Ts...)(Ts ts){...}

 printSumIntFloats(1,1.0f,2,2.0f);

 I want to print the sum of all integers and the sum of all 
 floats.


 //Pseudo code
 void printSumIntFloats(Ts...)(Ts ts){
     auto sumOfInts = ts
                       .filter!(isInteger)
                       .reduce(a => a + b);
     writeln(sumOfInts);
     ...
 }

 Is something like this possible?
import std.algorithm.iteration : sum; import std.meta : allSatisfy, Filter; import std.traits; import std.typecons : tuple; import std.range : only; // These two are necessary since the ones in std.traits // don't accept non-types enum isIntegral(alias i) = std.traits.isIntegral!(typeof(i)); enum isFloatingPoint(alias f) = std.traits.isFloatingPoint!(typeof(f)); auto separateSum(T...)(T args) if(allSatisfy!(isNumeric, T)) { return tuple(only(Filter!(isIntegral, args)).sum(), only(Filter!(isFloatingPoint, args)).sum()); } pure nothrow safe unittest { assert(separateSum(2, 2.0) == tuple(2, 2.0)); assert(separateSum(3, 2.0, 5, 1.0, 1.0) == tuple(8, 4.0)); }
Nov 03 2015
parent reply maik klein <maikklein googlemail.com> writes:
On Wednesday, 4 November 2015 at 06:20:30 UTC, Jakob Ovrum wrote:
 On Tuesday, 3 November 2015 at 23:41:10 UTC, maik klein wrote:
 [...]
import std.algorithm.iteration : sum; import std.meta : allSatisfy, Filter; import std.traits; import std.typecons : tuple; import std.range : only; // These two are necessary since the ones in std.traits // don't accept non-types enum isIntegral(alias i) = std.traits.isIntegral!(typeof(i)); enum isFloatingPoint(alias f) = std.traits.isFloatingPoint!(typeof(f)); auto separateSum(T...)(T args) if(allSatisfy!(isNumeric, T)) { return tuple(only(Filter!(isIntegral, args)).sum(), only(Filter!(isFloatingPoint, args)).sum()); } pure nothrow safe unittest { assert(separateSum(2, 2.0) == tuple(2, 2.0)); assert(separateSum(3, 2.0, 5, 1.0, 1.0) == tuple(8, 4.0)); }
Thanks, that is exactly what I wanted to achieve. What is the performance implication of 'only' in this context? Will it copy all arguments?
Nov 04 2015
parent Jakob Ovrum <jakobovrum gmail.com> writes:
On Wednesday, 4 November 2015 at 09:48:40 UTC, maik klein wrote:
 Thanks, that is exactly what I wanted to achieve. What is the 
 performance implication of 'only' in this context? Will it copy 
 all arguments?
Yes, it will, but just from the stack to a different location on stack.
Nov 04 2015