Struct that destroys its original handle on copy-by-value

Joseph Rushton Wakeling via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jul 26 04:29:49 PDT 2015


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


More information about the Digitalmars-d-learn mailing list