Keeping a mutable reference to a struct with immutable members

pineapple via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun May 29 13:34:38 PDT 2016


On Sunday, 29 May 2016 at 19:52:37 UTC, Basile B. wrote:
> Do yo have a simple, concise runnable example to show ?

This is the example I was using to test solutions, it's similar 
to where I encountered the problem in the first place

     import core.stdc.stdlib : malloc, free;
     import std.stdio;
     import std.range;
     import std.traits;

     struct RepeatRange(Range) if(isForwardRange!Range){
         Range* source;
         Range original;

         this(Range original){
             this.original = original;
             this.repeat(original.save);
         }

         @property auto ref front(){
             return this.source.front;
         }
         void popFront(){
             this.source.popFront();
             if(this.source.empty) this.repeat(this.original.save);
         }

         @nogc void repeat(Range from){
             if(this.source) free(this.source);
             ubyte* newptr = cast(ubyte*) malloc(Range.sizeof);
             assert(newptr !is null, "Failed to allocate memory.");

             ubyte* fromptr = cast(ubyte*) &from;
             for(size_t i; i < Range.sizeof; i++) newptr[i] = 
fromptr[i];
             this.source = cast(Range*) newptr;
         }

         this(this){
             auto source = *this.source;
             this.source = null;
             this.repeat(source);
         }
         ~this(){
             if(this.source) free(this.source);
         }

         enum bool empty = false;
     }

     struct SomeForwardRange{
         int value = 0;
         const int other = 1; // Immutable member

         enum bool empty = false;
         @property auto ref save(){
             return SomeForwardRange(this.value);
         }
         @property auto ref front(){
             return this.value;
         }
         void popFront(){
             this.value++;
         }
     }

     void main(){
         auto range = 
RepeatRange!SomeForwardRange(SomeForwardRange(0));
         foreach(item; range.take(10)){
             writeln(item);
         }
     }



More information about the Digitalmars-d-learn mailing list