## Arrays

### C Reference

#### Types and constants

C types, limits and enumerations

##### Constants and types

    ECL_ARRAY_RANK_LIMIT

    ECL_ARRAY_DIMENSION_LIMIT

    ECL_ARRAY_TOTAL_LIMIT

    typedef enum { ecl_aet_object, ...} cl_elttype;

- Lisp or C type
- Enumeration value
- Lisp or C type
- Enumeration value
- t
- ecl_aet_object
- (unsigned-byte 1)
- ecl_aet_bit
- cl_fixnum
- ecl_aet_fix
- cl_index
- ecl_aet_index
- (unsigned-byte 8)
- ecl_aet_b8
- (signed-byte 8)
- ecl_aet_i8
- (unsigned-byte 16)
- ecl_aet_b16
- (signed-byte 16)
- ecl_aet_i16
- (unsigned-byte 32)
- ecl_aet_b32
- (signed-byte 32)
- ecl_aet_i32
- (unsigned-byte 64)
- ecl_aet_b64
- (signed-byte 64)
- ecl_aet_i64
- ecl_character
- ecl_aet_ch
- ecl_base_char
- ecl_aet_bc
- single-float
- ecl_aet_sf
- double-float
- ecl_aet_df

##### Description

This list contains the constants that limit the rank of an array (`ECL_ARRAY_RANK_LIMIT`), the maximum size of each dimension (`ECL_ARRAY_DIMENSION_LIMIT`) and the maximum number of elements in an array (`ECL_ARRAY_TOTAL_LIMIT`).

&ECL; uses also internally a set of constants to describe the different specialized arrays. The constants form up the enumeration type cl_elttype. They are listed in the table above, which associates enumeration values with the corresponding Common Lisp element type.

#### `ecl_aet_to_symbol`, `ecl_symbol_to_aet`

To and from element types

##### Functions

    	  cl_object ecl_aet_to_symbol
    	  cl_elttype param

    	  cl_elttype ecl_symbol_to_aet
    	  cl_object type

##### Description

`ecl_aet_to_symbol` returns the Lisp type associated to the elements of that specialized array class. `ecl_symbol_to_aet` does the converse, computing the C constant that is associated to a Lisp elment type.

The functions may signal an error if any of the arguments is an invalid C or Lisp type.

#### Constructors

Creating arrays and vectors

##### Functions

    	  cl_object ecl_alloc_simple_vector
    	  cl_elttype element_type
    	  cl_index length

    	  cl_object si_make_vector
    	  cl_object element_type
    	  cl_object length
    	  cl_object adjustablep
    	  cl_object fill_pointerp
    	  cl_object displaced_to
    	  cl_object displacement

    	  cl_object si_make_array
    	  cl_object element_type
    	  cl_object dimensions
    	  cl_object adjustablep
    	  cl_object fill_pointerp
    	  cl_object displaced_to
    	  cl_object displacement

##### Description

The function `ecl_alloc_simple_vector` is the simplest constructor, creating a simple vector (i.e. non-adjustable and without a fill pointer), of the given size, preallocating the memory for the array data. The first argument, element_type, is a C constant that represents a valid array element type (See cl_elttype).

The function `si_make_vector` does the same job but allows creating an array with fill pointer, which is adjustable or displaced to another array.

- element_type is now a Common Lisp type descriptor, which is a symbol or list denoting a valid element type

- dimension is a non-negative fixnum with the vector size.

- fill_pointerp is either Cnil or a non-negative fixnum denoting the fill pointer value.

- displaced_to is either Cnil or a valid array to which the new array is displaced.

- displacement is either Cnil or a non-negative value with the array displacement.

Finally, the function `si_make_array` does a similar job to `si_make_function` but its second argument, dimension, can be a list of dimensions, to create a multidimensional array.

##### Example

Create one-dimensional base-string with room for 11 characters:

    cl_object s = ecl_alloc_simple_vector(ecl_aet_bc, 11);

Create a one-dimensional array with a fill pointer

    cl_object type = ecl_make_symbol("BYTE8","EXT");
    cl_object a = si_make_vector(ecl_make_fixnum(16), type, Cnil, /* adjustable */
                                 ecl_make_fixnum(0) /* fill-pointer */,
                                 Cnil /* displaced_to */,
                                 Cnil /* displacement */);

An alternative formulation

    cl_object type = ecl_make_symbol("BYTE8","EXT");
    cl_object a = si_make_array(ecl_make_fixnum(16), type, Cnil, /* adjustable */
                                ecl_make_fixnum(0) /* fill-pointer */,
                                Cnil /* displaced_to */,
                                Cnil /* displacement */);

Create a 2-by-3 two-dimensional array, specialized for an integer type:

    cl_object dims = cl_list(2, ecl_make_fixnum(2), ecl_make_fixnum(3));
    cl_object type = ecl_make_symbol("BYTE8","EXT");
    cl_object a = si_make_array(dims, type, Cnil, /* adjustable */
                                Cnil /* fill-pointer */,
                                Cnil /* displaced_to */,
                                Cnil /* displacement */);

#### Accessors

Reading and writing array elements

##### Functions

    	  cl_object ecl_aref
    	  cl_object array
    	  cl_index row_major_index

    	  cl_object ecl_aset
    	  cl_object array
    	  cl_index row_major_index
    	  cl_object new_value

    	  cl_object ecl_aref1
    	  cl_object vector
    	  cl_index row_major_index

    	  cl_object ecl_aset1
    	  cl_object vector
    	  cl_index row_major_index
    	  cl_object new_value

##### Description

`ecl_aref` accesses an array using the supplied row_major_index, checking the array bounds and returning a Lisp object for the value at that position. `ecl_aset` does the converse, storing a Lisp value at the given row_major_index.

The first argument to `ecl_aref` or `ecl_aset` is an array of any number of dimensions. For an array of rank N and dimensions d1, d2 ... up to dN, the row major index associated to the indices (i1,i2,...iN) is computed using the formula `i1+d1*(i2+d3*(i3+...))`.

`ecl_aref1` and `ecl_aset1` are specialized versions that only work with one-dimensional arrays or vectors. They verify that the first argument is indeed a vector.

All functions above check that the index does not exceed the array bounds, that the values match the array element type and that the argument is an array (or a vector). If these conditions are not met, a type error is signaled.

#### Array properties

Array size, fill pointer, etc

    	  cl_elttype ecl_array_elttype
    	  cl_object array

    	  cl_index ecl_array_rank
    	  cl_object array

    	  cl_index ecl_array_dimension
    	  cl_object array
    	  cl_index index

##### Description

These functions query various properties of the arrays. Some of them belong to the list of functions in the Common Lisp package, without any need for specialized versions. More precisely

- `ecl_array_elttype` returns the array element type, with the encoding found in the enumeration cl_elttype.

- `ecl_array_rank` returns the number of dimensions of the vector or array.

- `ecl_array_dimension` queries the dimension of an array, where index is a non-negative integer between 0 and `ecl_array_dimension(array)-1`.

#### ANSI Dictionary

&ANSI-C-Dict;

- Lisp symbol
- C function
- make-array
- `cl_object cl_make_array(cl_narg narg, cl_object dimension...)`
- adjust-array
- `cl_object cl_adjust_array(cl_narg narg, cl_object array, cl_object dimensions, ...)`
- adjustable-array-p
- `cl_object cl_adjustable_array_p(cl_object array)`
- aref
- `cl_object cl_aref(cl_narg narg, cl_object array, ...)`
- array-dimension
- `cl_object cl_array_dimension(cl_object array, cl_object index)`
- array-dimensions
- `cl_object cl_array_dimension(cl_object array)`
- array-element-type
- `cl_object cl_array_element_type(cl_object array)`
- array-has-fill-pointer-p
- `cl_object cl_array_has_fill_pointer_p(cl_object array)`
- array-displacement
- `cl_object cl_array_displacement(cl_object array)`
- array-in-bounds-p
- `cl_object cl_array_in_bounds_p(cl_narg narg, cl_object array, ...)`
- array-rank
- `cl_object cl_array_rank(cl_object array)`
- array-row-major-index
- `cl_object cl_array_row_major_index(cl_narg narg, cl_object array, ...)`
- array-total-size
- `cl_object cl_array_total_size(cl_object array)`
- arrayp
- `cl_object cl_arrayp(cl_object array)`
- fill-pointer
- `cl_object cl_fill_pointer(cl_object array)`
- row-major-aref
- `cl_object cl_row_major_aref(cl_object array, cl_object index)`
- upgraded-array-element-type
- `cl_object cl_upgraded_array_element_type(cl_narg narg, cl_object typespec, ...)`
- simple-vector-p
- `cl_object cl_simple_vector_p(cl_object object)`
- svref
- `cl_object cl_svref(cl_object simple_vector, cl_object index)`
- vector
- `cl_object cl_vector(cl_narg narg, ...)`
- vector-pop
- `cl_object cl_vector_pop(cl_object vector)`
- vector-push
- `cl_object cl_vector_push(cl_object new_element, cl_object vector)`
- vector-push-extend
- `cl_object cl_vector_push_extend(cl_narg narg, cl_object new_element, cl_object vector, ...)`
- vectorp
- `cl_object cl_vectorp(cl_object object)`
- bit
- `cl_object cl_bit(cl_narg narg, cl_object bit_array, ...)`
- sbit
- `cl_object cl_sbit(cl_narg narg, cl_object bit_array, ...)`
- bit-and
- `cl_object cl_bit_and(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-andc1
- `cl_object cl_bit_andc1(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-andc2
- `cl_object cl_bit_andc2(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-eqv
- `cl_object cl_bit_eqv(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-ior
- `cl_object cl_bit_ior(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-nand
- `cl_object cl_bit_nand(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-nor
- `cl_object cl_bit_nor(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-orc1
- `cl_object cl_bit_orc1(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-orc2
- `cl_object cl_bit_orc1(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-xor
- `cl_object cl_bit_xor(cl_narg narg, cl_object array1, cl_object array2, ...)`
- bit-not
- `cl_object cl_bit_not(cl_narg narg, cl_object array, ...)`

##### Description