Hello all,

A design question that came up during the hackathon held during the last Berlin D Meetup.

I was trying to come up with a range that can be copied by value, but when this is done, destroys the original handle. The idea would be behaviour something like this:

    auto originalRange = myWeirdRange(whatever);
    originalRange.take(10).writeln;
    assert(originalRange.empty,
           "The original handle points to an empty range after copy-by-value.");

A very minimal prototype (missing out the details of front and popFront as irrelevant) would be something like:

    struct MyWeirdRange (R)
        if (isInputRange!R)
    {
      private:
        R* input_;   // Assumed to never be empty, FWIW.  I'm missing out
                     // a template check on that for brevity's sake.

      public:
        this (return ref R input)
        {
            /* return ref should guarantee the pointer
             * is safe for the lifetime of the struct,
             * right ... ?
             */
            this.input_ = &input;
        }

        bool empty () @property
        {
            return this.input_ is null;
        }

        auto front () @property { ... }

        void popFront () { ... }

        void opAssign (ref typeof(this) that)
        {
            /* copy the internal pointer, then
             * set that of the original to null
             */
            this.input_ = that.input_;
            that.input_ = null;
        }
    }

Basically, this is a range that would actively enforce the principle that its use is a one-shot. You copy it by value (whether by direct assignment or by passing it to another function), you leave the original handle an empty range.

However, the above doesn't work; even in the event of a direct assignment, i.e.

    newRange = originalRange;

... the opAssign is never called. I presume this is because of the ref-parameter input, but it's not obvious to me according to the description here why this should be: http://dlang.org/operatoroverloading.html#assignment Can anyone clarify what's going on here?

Anyway, my main question is: is this design idea even feasible in principle, or just a bad idea from the get-go? And if feasible -- how would I go about it?

Thanks & best wishes,

    -- Joe

Reply via email to