Thread overview
Is it possible to filter variadics?
Nov 03, 2015
maik klein
Nov 04, 2015
TheFlyingFiddle
Nov 04, 2015
Jakob Ovrum
Nov 04, 2015
maik klein
Nov 04, 2015
Jakob Ovrum
November 03, 2015
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?

November 04, 2015
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);
}








November 04, 2015
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));
}

November 04, 2015
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?
November 04, 2015
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.