Skip to content

Commit c902cfa

Browse files
authored
Merge pull request #3403 from ntrel/arr-resize
[spec/arrays] Improve resizing section Signed-off-by: Dennis <dkorpel@users.noreply.github.com> Merged-on-behalf-of: Dennis <dkorpel@users.noreply.github.com>
2 parents ce76a64 + cb1b8f9 commit c902cfa

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed

spec/arrays.dd

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ a.length; // runtime value
579579

580580
p.dup; // error, length not known
581581
s.dup; // creates an array of 3 elements, copies
582-
// elements s into it
582+
// elements of s into it
583583
a.dup; // creates an array of a.length elements, copies
584584
// elements of a into it
585585
---------
@@ -604,16 +604,22 @@ array.length = 7;
604604
array = array[0..7];
605605
---------
606606

607-
$(P If the new array length is longer, the remainder is filled out with the
607+
$(P If the new array length is longer, the array is reallocated if necessary,
608+
preserving the existing elements. The new elements are filled out with the
608609
default initializer.
609610
)
610611

612+
$(H4 $(LNAME2 growing, Growing an Array))
613+
611614
$(P To maximize efficiency, the runtime always tries to resize the array
612-
in place to avoid extra copying. It will always do a copy if the new
613-
size is larger and the array was not allocated via the new operator or
614-
resizing in place would overwrite valid data in the array. For example:)
615+
in place to avoid extra copying. It will do a copy if the new size
616+
is larger and either:)
615617

616-
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
618+
* The array was not $(DDSUBLINK spec/garbage, op_involving_gc, allocated by the GC).
619+
* There is no spare $(RELATIVE_LINK2 capacity-reserve, capacity) in the array.
620+
* Resizing in place would overwrite valid data still accessible in another slice.
621+
622+
$(SPEC_RUNNABLE_EXAMPLE_RUN
617623
---------
618624
char[] a = new char[20];
619625
char[] b = a[0..10];
@@ -623,10 +629,13 @@ char[] d = a;
623629
b.length = 15; // always reallocates because extending in place would
624630
// overwrite other data in a.
625631
b[11] = 'x'; // a[11] and c[1] are not affected
632+
assert(a[11] == char.init);
626633

627634
d.length = 1;
628-
d.length = 20; // also reallocates, because doing this will overwrite a and
629-
// c
635+
assert(d.ptr == a.ptr); // unchanged
636+
637+
d.length = 20; // also reallocates, because doing this will overwrite a and c
638+
assert(d.ptr != a.ptr);
630639

631640
c.length = 12; // may reallocate in place if space allows, because nothing
632641
// was allocated after c.
@@ -642,14 +651,13 @@ a[15] = 'z'; // does not affect c, because either a or c has reallocated.
642651
)
643652

644653

645-
$(P To guarantee copying behavior, use the .dup property to ensure
646-
a unique array that can be resized. Also, one may use the
647-
$(D .capacity) property to determine how many elements can be appended
648-
to the array without reallocating.
654+
$(P To guarantee copying behavior, use the `.dup` property to ensure
655+
a unique array that can be resized.
649656
)
650657

651-
$(P These issues also apply to appending arrays with the ~= operator.
652-
Concatenation using the ~ operator is not affected since it always
658+
$(NOTE These issues also apply to
659+
$(RELATIVE_LINK2 array-appending, appending arrays) with the `~=` operator.
660+
Concatenation using the `~` operator is not affected since it always
653661
reallocates.
654662
)
655663

@@ -701,16 +709,24 @@ array.length = i;
701709
input from the console - it's unlikely to be longer than 80.
702710
)
703711

712+
$(H3 $(LNAME2 capacity-reserve, `capacity` and `reserve`))
713+
714+
$(P The $(D capacity) property gives the maximum length the array
715+
can grow to without reallocating. The spare capacity for array *a*
716+
is `a.capacity - a.length`.)
704717
$(P The $(D reserve)
705718
function expands an array's capacity for use by the append operator.)
706719

707720
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
708721
---------
709722
int[] array;
710723
size_t cap = array.reserve(10); // request
711-
array ~= [1, 2, 3, 4, 5];
712724
assert(cap >= 10); // allocated may be more than request
725+
726+
int[] copy = array;
727+
array ~= [1, 2, 3, 4, 5]; // grow in place
713728
assert(cap == array.capacity);
729+
assert(copy.ptr == array.ptr);
714730
---------
715731
)
716732

0 commit comments

Comments
 (0)