On Friday, 17 July 2015 at 07:42:09 UTC, Roland Hadinger wrote:
Here's how I would implement the basic behaviour (could be extended to also forward bidirectional and random access functions):

---
    auto cushion(R)(R r)
        if (isInputRange!R)
    {
        static if (isInfinite!R) { return r; } else {

            struct _Cushion(R)
            {
                R r;

                alias E = ElementType!R;
                alias NE = Nullable!E;

                @property bool empty() { return false; }

                @property NE front()
                {
                    return !r.empty ? NE(r.front) : NE();
                }

                void popFront()
                {
                    if (!r.empty) r.popFront();
                }
            }

            return _Cushion!R(r);
        }
    }

---

I didn't find anything like this Phobos. Did I miss something?

The building blocks are there. You're `map`ping the original range to `Nullable`, and then you're `chain`ing an infinite range (`cycle`) of nulls behind.

----
import std.range: isInputRange;

auto cushion(R)(R r)
    if (isInputRange!R)
{
    import std.algorithm: map;
    import std.range: chain, cycle, ElementType, only;
    import std.typecons: Nullable;

    alias E = ElementType!R;
    alias NE = Nullable!E;

    return chain(r.map!NE, NE().only.cycle);
}
----

Reply via email to