scoped classes

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Apr 27 10:39:42 PDT 2017


On 04/27/2017 05:47 PM, Alex wrote:
> void main()
> {
>     S[] arr;
>     S s = S(42);
>     arr = [s]; // this doesn't work :(
> }
>
> struct S
> {
>     @disable this();
>     @disable this(this);
>     this(size_t dummy){}
> }

1) Construct the S instance directly in the array literal:

----
arr = [S(42]);
----

But I guess that's besides the point. So ...

2) Use std.algorithm.mutation.move [1]:

----
import std.algorithm.mutation: move;
S s = S(42);
arr = [move(s)];
----

`move` makes a "destructive copy" here; i.e, it resets `s` to `S.init`.

You probably want to append to that array at some point. That's going to 
be more tricky, because appending potentially involves copying the whole 
array.

This might work:

----
import std.algorithm.mutation: moveEmplace;
import std.array: uninitializedArray;

/* Make a new, larger array: */
S[] new_arr = uninitializedArray!(S[])(arr.length + 1);

/* Copy existing elements; destroy old array: */
foreach (size_t i; 0 .. arr.length) moveEmplace(arr[i], new_arr[i]);

/* Copy new element; destroy s: */
moveEmplace(s, new_arr[$ - 1]);

/* Replace old array with new one: */
arr = new_arr;
----

Notes:

* `moveEmplace` and `uninitializedArray` are completely unsafe. You must 
ensure safety yourself.

* I'm not entirely sure that the code is completely correct. It might be 
invalid and break some language rule.

* I'm pretty sure that the code is going to be invalid when you're 
dealing with const/immutable data.

* The code destroys the old array. References to it (slices of it, 
pointers into it) will show .init values.

* Maybe one can make use of `.capacity` somehow. As it is, the code 
makes a copy of the whole array every time.

* If this "moveAppend" functionality can be done in a valid manner, it 
might be a worthwhile addition to the "move" function family.



[1] http://dlang.org/phobos/std_algorithm_mutation.html#.move


More information about the Digitalmars-d-learn mailing list