www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Keeping a mutable reference to a struct with immutable members

reply pineapple <meapineapple gmail.com> writes:
I found another post on this subject and the advice there was 
"don't put const members in your structs" - 
http://forum.dlang.org/thread/m87ln2$idv$1 digitalmars.com

This doesn't work out so well when the templated struct is 
referring to what happens to be a const array.

I thought I could get it done with pointers, but then I realized 
my data was going out-of-scope. I tried using `Unqual!T 
thing_i_need_to_reassign_sometimes` where T was immutable but 
that didn't solve anything, either.

What's the best way to handle something like this?
May 29 2016
parent reply pineapple <meapineapple gmail.com> writes:
On Sunday, 29 May 2016 at 18:52:36 UTC, pineapple wrote:
 What's the best way to handle something like this?
Well I did get something to work but it's ugly and I refuse to believe there isn't a better way to handle this. Where `Range` is an alias to a struct with an immutable member, and `this.source` is the attribute that I need to be able to re-assign to a locally scoped return value: import core.stdc.stdlib : malloc, free; if(this.source) free(source); ubyte* newptr = cast(ubyte*) malloc(Range.sizeof); assert(newptr !is null, "Failed to allocate memory."); Range saved = this.original.save; ubyte* savedptr = cast(ubyte*) &saved; for(size_t i; i < Range.sizeof; i++){ newptr[i] = savedptr[i]; } this.source = cast(Range*) newptr;
May 29 2016
parent reply Basile B. <b2.temp gmx.com> writes:
On Sunday, 29 May 2016 at 19:09:13 UTC, pineapple wrote:
 On Sunday, 29 May 2016 at 18:52:36 UTC, pineapple wrote:
 What's the best way to handle something like this?
Well I did get something to work but it's ugly and I refuse to believe there isn't a better way to handle this. Where `Range` is an alias to a struct with an immutable member, and `this.source` is the attribute that I need to be able to re-assign to a locally scoped return value: this.source = cast(Range*) newptr;
Do yo have a simple, concise runnable example to show ?
May 29 2016
parent pineapple <meapineapple gmail.com> writes:
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); } }
May 29 2016