Contiguous same-schema storage with explicit size and reserve management.


Storage and reserve model


Reference stability and invalidation


makeArrayObject (Item memoryDebugObject -- emptyArray)

Constructs an empty array object whose schema is Array<Item>, for the supplied item schema and memory-debug selection.


Array

Methods

Array method ordinals, offsets, item counts and reserve counts have schema Int32. at and erase reject a key of any other schema at compile time (the error names ONLY_I32_ALLOWED); the size methods reject a non-Int32 size when comparing it with the current size.

append

(item/span/iter --) Appends item(s) to the end.

Remarks

Appending data may cause reallocation if the reserve is insufficient, potentially invalidating obtained Refs. If the reserve is already sufficient, reallocation does not occur. If the source is a span or an iteration source with a size method, the storage is enlarged once before the items are stored.

The single-item form stores the item with set: an immutable view (s @a.append) is copied; a mutable view (@s @a.append) is moved and its source is left freshly constructed (an owned String becomes empty); a direct value (10 @a.append, a temporary) is moved into the new element.

Known issue: the single-item form grows the storage before it reads the item, so an item that references an element of this array is read from the released buffer when the append triggers a reallocation; the invalid read has no defined value. For a copyable item, copy first: 0 a.at new @a.append.

Examples

"Array"     use
"algorithm" use
"control"   use

# "algorithm" supplies = between an Array and a Tuple
{} () {} [
  numbers: Int32 Array;

  # Append single items
  10 @numbers.append
  20 @numbers.append
  [numbers (10 20) =] "[.append] produced wrong result" ensure

  # Append multiple items
  (30 40 50) @numbers.append
  [numbers (10 20 30 40 50) =] "[.append] produced wrong result" ensure

  "Done.\n" print
] "main" exportFunction

Expected Output

Done.

assign

(span/iter/array --) Replaces the array's contents with the source items.
  • The source's item schema is Item; another item schema fails compilation (for example Inconsistent schemas).
  • If the source reports a size, it is a nonnegative Int32 count.

Remarks

An Array of the same schema is copied when reached through an immutable view and moved when reached through a mutable view, which leaves the source empty.

at

(key -- ref) Returns Ref to the item at key.
  • key in [0..current item count - 1].
  • Runtime bounds checks require DEBUG; a failed check reports Index is out of range!, and with DEBUG disabled runtime bounds are the caller's responsibility.

clear

(--) Removes all items and preserves capacity.

data

(-- ref) Returns the stored Ref to the first item.

enlarge

(newSize --) Grows array size to newSize (≥ old size).
  • newSize ≥ current item count.

erase

(key --) Removes the item at key and fills that position with the last item.
  • key in [0..current item count - 1].

eraseIf

(predicate --) Removes all items for which predicate reports TRUE.
  • predicate accepts one item and reports a Cond.

iter

(-- iter) Returns an iteration source over the current items.

last

(-- ref) Returns Ref to the last item.
  • current item count > 0.

popBack

(--) Removes the last item.
  • current item count > 0.
  • Reserved capacity is unchanged.

release

(--) Clears and frees all array memory.

reserve

(-- count) Returns the current reserved capacity.

Examples

"Array"   use
"control" use

{} () {} [
  numbers: Int32 Array;
  numbers.reserve printStack _:;
  4 @numbers.setReserve
  numbers.reserve printStack _:;
] "main" exportFunction

Expected Output During Compilation

0
4

resize

(newSize --) Changes size; can shrink or grow array.
  • newSize ≥ 0.

setReserve

(newReserve --) Raises reserved capacity to newReserve.
  • newReserve ≥ current reserve.

shrink

(newSize --) Reduces size to newSize without changing reserve.
  • 0 ≤ newSize ≤ current size.

size

(-- count) Returns the current number of items.

slice

(offset size -- theSpan) Returns a span over the selected subrange.
  • offset in [0..current item count].
  • size (the argument) in [0..current item count - offset].

Runtime example

"Array"   use
"String"  use
"control" use

{} Int32 {} [
  numbers: Int32 Array;
  (10 20 30 40) @numbers.assign

  part: 1 2 @numbers.slice;
  ("size=" part.size LF
    "first=" 0 @part.at new LF
    "second=" 1 @part.at new LF) printList
  0
] "main" exportFunction

Expected Output

size=2
first=20
second=30

span

(-- theSpan) Returns a span over [0..size-1].

Runtime example: append, last and erase

"Array"   use
"String"  use
"control" use

{} Int32 {} [
  numbers: Int32 Array;
  10 @numbers.append
  20 @numbers.append
  30 @numbers.append
  ("size=" numbers.size LF
    "last=" @numbers.last new LF) printList
  1 @numbers.erase
  ("size2=" numbers.size LF
    "item1=" 1 @numbers.at new LF) printList
  0
] "main" exportFunction

Expected Output

size=3
last=30
size2=2
item1=30

Runtime example: eraseIf preserves retained order

"Array"   use
"String"  use
"control" use

{} Int32 {} [
  numbers: Int32 Array;
  (10 20 30 15) @numbers.assign
  [15 >] @numbers.eraseIf
  ("size=" numbers.size LF
    "first=" 0 @numbers.at new LF
    "last=" @numbers.last new LF) printList
  0
] "main" exportFunction

Expected Output

size=2
first=10
last=15

Struct Item Example

"Array"   use
"control" use

Point: [{x: Int32; y: Int32;}];

{} () {} [
  points: Point Array;

  {x: 10; y: 20;} @points.append
  {x: 30; y: 40;} @points.append

  0 @points.at .x printStack _:;
] "main" exportFunction

Expected Output During Compilation

Int32 Cref

MemoryDebugArray

Variant of Array with memory-debug instrumentation enabled.

Known issue: the instrumented allocation paths write to memoryDebugEnabled, a name that no module defines, so any allocation through MemoryDebugArray (or TRUE makeArrayObject) fails with Name was not found. Array is unaffected.


getHeapUsedSize (array -- size)

Returns total heap usage of the Array as Natx.

Known issue: getHeapUsedSize reads the private field arrayReserve from outside the array Dict, so every call fails to compile with «.arrayReserve», Argument (dict) has a private field; the function is unusable until the library is fixed.


toArray (source -- array)

Creates a new Array from a span, iteration source, or existing Array.

Runtime example

"Array"   use
"String"  use
"control" use

{} Int32 {} [
  numbers: (10 20 30) toArray;
  copy: numbers toArray;
  moved: @numbers toArray;
  ("size=" copy.size LF "moved=" moved.size LF "left=" numbers.size LF) printList
  0
] "main" exportFunction

Expected Output

size=3
moved=3
left=0

See also