Skip to content

Commit 5c78d55

Browse files
authored
[spec] Improve array capacity docs (#3906)
Clarify that capacity is only for GC allocated *array* memory. Explain `reserve`. The runtime uses the last element in a slice rather than just the number of appended elements. Link to Appender.
1 parent cf49126 commit 5c78d55

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

spec/arrays.dd

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -826,18 +826,20 @@ void fun()
826826
$(H3 $(LNAME2 capacity-reserve, `capacity` and `reserve`))
827827

828828
$(P The $(D capacity) property gives the maximum length a dynamic array
829-
can grow to without reallocating. If the array does not point to
830-
GC-allocated memory, the capacity will be zero.
831-
The spare capacity for an array *a* is `a.capacity - a.length`.)
829+
can grow to without reallocating.
830+
The spare capacity for an array *a* is `a.capacity - a.length`.
831+
The capacity for a slice is zero:)
832832

833-
$(P By default, `capacity` will be zero if an element has been stored after the slice.)
833+
* If it does not point to GC-allocated dynamic array memory.
834+
* By default, when an element has been stored after the slice.
834835

835836
$(SPEC_RUNNABLE_EXAMPLE_RUN
836837
---
837838
int[] a;
838839
assert(a.capacity == 0);
839840
a.length = 3; // may allocate spare capacity too
840841
assert(a.capacity >= 3);
842+
841843
auto b = a[1..3];
842844
assert(b.capacity >= 2); // either a or b can append into any spare capacity
843845
b = a[0..2];
@@ -849,8 +851,9 @@ $(H3 $(LNAME2 capacity-reserve, `capacity` and `reserve`))
849851
elements in another slice. It is also necessary to protect immutable
850852
elements from being overwritten.)
851853

852-
$(P The $(D reserve)
853-
function expands an array's capacity for use by the
854+
$(P The $(REF1 reserve, object) function requests a minimum capacity for an array.
855+
It returns the new capacity, which may be more than requested.
856+
Any spare capacity can be used by the
854857
$(RELATIVE_LINK2 array-appending, append operator) or `.length` assignment.)
855858

856859
$(SPEC_RUNNABLE_EXAMPLE_RUN
@@ -859,15 +862,17 @@ int[] array;
859862
const size_t cap = array.reserve(10); // request
860863
assert(cap >= 10); // allocated may be more than request
861864
assert(array.ptr != null);
865+
assert(array.length == 0);
862866

863867
int[] copy = array;
864868
assert(copy.capacity == cap); // array and copy have same capacity
865869
array ~= [1, 2, 3, 4, 5]; // grow in place
866870
assert(cap == array.capacity); // array memory was not reallocated
867871
assert(copy.ptr == array.ptr);
868872
assert(copy.capacity == 0);
869-
copy ~= 0; // new allocation
873+
copy ~= 0; // allocates a new array
870874
assert(copy.ptr != array.ptr);
875+
assert(array[0] == 1);
871876
---------
872877
)
873878
$(P Above, `copy`'s length remains zero but it points to the same
@@ -876,7 +881,7 @@ assert(copy.ptr != array.ptr);
876881
is the address of `array[0]`. So `copy.capacity` will be zero to
877882
prevent any appending to `copy` from overwriting elements in `array`.)
878883

879-
$(NOTE The runtime uses the number of appended elements to track the
884+
$(NOTE The runtime uses the last element of a slice to track the
880885
start of the spare capacity for the memory allocation.)
881886

882887
$(P When an array with spare capacity has its length reduced, or is
@@ -885,7 +890,7 @@ assert(copy.ptr != array.ptr);
885890

886891
$(P The `@system` function $(REF1 assumeSafeAppend, object) allows the
887892
capacity to be regained, but care must be taken not to overwrite
888-
immutable elements that may exist in a longer slice.)
893+
immutable elements that may exist in another slice.)
889894

890895
$(SPEC_RUNNABLE_EXAMPLE_RUN
891896
---
@@ -901,7 +906,8 @@ assert(copy.ptr != array.ptr);
901906
acquire a global lock and perform a cache lookup.)
902907

903908
$(BEST_PRACTICE Avoid intensive use of `.capacity` in performance-sensitive code.
904-
Instead, track the capacity locally when building an array via a unique reference.)
909+
Instead, track the capacity locally when building an array via a unique reference.
910+
E.g. $(REF Appender, std,array).)
905911

906912

907913
$(H3 $(LNAME2 func-as-property, Functions as Array Properties))

0 commit comments

Comments
 (0)