# Copyright (C) 2001-2014, Parrot Foundation.

=pod

=head1 NAME

docs/pmc/array.pod - Virtual base class Array

=head1 SYNOPSIS

=begin PIR_FRAGMENT

  new $P0, 'ResizablePMCArray' # initialize P0 as an resizable array for PMC items

  $P0 = 2             # set the size of the array in P0 to 2
  $I0 = $P0           # get the size of the array in P0 into I0

  set $P0[0], "foo "  # put "foo" into the array at position 0
  set $I1, $P0[1]     # get an integer value from the entry 
                      # at array position 1

  defined $I2, $P0[1] # is the value at position 1 defined?
  exists  $I3, $P0[0] # is there an element at position 0?

=end PIR_FRAGMENT

=head1 DESCRIPTION

This pod file documents the virtual base Array base class usage. For
implementation details you should look inside the class files, found
at F<src/pmc/{Fixed,Resizable}{PMC,Integer,Float,String,Boolean}Array.pmc> in
the parrot source code.

=head2 Creation

As with any other PMC, the following line creates an array PMC in register 
C<P0>:

=begin PIR_FRAGMENT

  $S0 = 'ResizablePMCArray' # or any other array type
  new $P0, $S0

=end PIR_FRAGMENT

The virtual 'Array' class itself cannot be instantiated.

=head2 Array sizes

You can retrieve the size of the array using

=begin PIR_FRAGMENT

  set $I0, $P0
  # or
  $I0 = $P0

=end PIR_FRAGMENT

This will put the size of the array in register C<P0> into C<I0>. In the same
way, assigning an integer directly to the array sets the size of the array.
For instance:

=begin PIR_FRAGMENT

  new $P0, 'FixedPMCArray'
  set $P0, 2

  # or faster

  new $P0, 'FixedPMCArray', 2

=end PIR_FRAGMENT

creates a new fixed size array for PMCs (with default size 0) and then
expands the size of the array to two, or with the second integer argument
initializes the size immediately.

Fixed arrays do not automatically resize themselves when you access
out-of-bounds elements. This means that you must remember to size a
fixed array appropriately before storing anything in it, or use a
resiable array instead.

=head2 Accessing elements

Elements are accessed using indexes, as in any programming language.

The following code initializes an array in C<P0> with size two, and
sets the first position to the integer C<-8> and second position to
the floating point number C<3.1415>.

=begin PIR_FRAGMENT

  new $P0, 'FixedPMCArray', 2

  set $P0[0], -8
  set $P0[1], 3.1415

=end PIR_FRAGMENT

You can also assign indirectly via registers; for instance:

=begin PIR_FRAGMENT

  new $P0, 'FixedPMCArray', 2

  set $I0, -8
  set $N0, 3.1415

  set $P0[0], $I0
  set $P0[1], $N0

=end PIR_FRAGMENT

leaves P0 in the same state as in the previous code snippet.

To retrieve elements, we use the same syntax:

=begin PIR_FRAGMENT

  set $N1, $P0[1]
  set $I1, $P0[0]

=end PIR_FRAGMENT

Those two lines retrieve the values from the array back into registers.

The value stored at a given position is not fixed; it can be changed simply by
assigning a new value:

=begin PIR_FRAGMENT

  set $P0[1], "A string"

=end PIR_FRAGMENT

Accessing an out-of-bounds array element raises an exception; if you want an
array that will automatically resize use a B<resizable array>.

You can test if there is a defined element at an array position by using

=begin PIR_FRAGMENT

  defined $I0, $P0[1]

=end PIR_FRAGMENT

for the position you want to test. On the other hand, if you only want to test
whether a given element exists (rather than whether it is defined),  then use
the C<exists> op instead:

=begin PIR_FRAGMENT

  exists $I0, $P0[0]

=end PIR_FRAGMENT

With exists you are safe to check even out of bounds indices.

=head2 Resizable vs Fixed

There exist two array types, B<Resizable> and B<Fixed> size for all
base types: PMC, Integer, String, Float and Boolean.  With resizable
arrays you can explicitly or implicitly grow an array by setting a
value at an index C<< >= >> size, but not with fixed arrays.

All methods throw an out of bounds exception on invalid
index or size arguments, just not on C<exists>.

Using negative indices is supported to count the index from the back.
E.g index C<-1> accesses the last element of an array.

Common non-vtable array methods are sort and reverse, which are
destructive. They do not return a copy.

Resizable arrays additionally support the shift, unshift, push, pull
methods.

=cut
