Unionize range types

TheFlyingFiddle via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Nov 2 20:31:00 PST 2015


On Tuesday, 3 November 2015 at 01:55:27 UTC, Freddy wrote:
> Is there any way I can Unionize range Types?
> ---
> auto primeFactors(T)(T t, T div = 2)
> {
>     if (t % div == 0)
>     {
>         return t.only.chain(primeFactors(t / div, div));
>     }
>     if (div > t)
>     {
>         return [];
>     }
>     else
>     {
>         return primeFactors(t, div + 1);
>     }
> }
> ---

Simplest way would be to go with a polymorphic approach.
import std.range;

interface IInputRange(T)
{
     T front();
     bool empty();
     void popFront();
}

class InputRange(Range) : IInputRange(ElementType!Range)
{
    Range inner;
    T front() { return inner.front; }
    bool empty() { return inner.empty; }
    void popFront() { inner.popFront; }
}

Simply wrap the ranges in the InputRange!Range class template. 
And return an IInputRange!T. This will require allocation though 
and is not really the way I would tackle the problem.

Or you could use Algebraic from std.variant which is probably 
more what you were looking for. But it's kind of awkward to use 
in the example you posted since it's not really clear what the 
specific range types are.

I would suggest creating a new range for prime-factors instead of 
trying to mix several ranges together. Something like this should 
do the trick. (if i am understanding the problem correctly)

auto primeFactors(T)(T t) if(isIntegral!T)
{
    struct Factors
    {
       T value;
       T front;
       bool empty() { return value == 1; }
       void popFront()
       {
          while(true)
          {
             if(value % front == 0)
             {
                value /= front;
                break;
             }
             if(front > value)
             {
                value = 1;
                break;
             }
             else
             {
                front = front + 1;
             }
          }
       }
    }

    auto f = Factors(t, 2);
    f.popFront();
    return f;
}









More information about the Digitalmars-d-learn mailing list