2.13 Arrays


2.13.1 Array limits

ECL arrays can have up to 64 dimensions. Common-Lisp constants related to arrays have the following values in ECL.

ConstantValue
array-rank-limit64
array-dimension-limitmost-positive-fixnum
array-total-size-limitarray-dimension-limit

2.13.2 Specializations

When the elements of an array are declared to have some precise type, such as a small or large integer, a character or a floating point number, ECL has means to store those elements in a more compact form, known as a specialized array. The list of types for which ECL specializes arrays is platform dependent, but is summarized in the following table, together with the C type which is used internally and the expected size.

Specialized typeElement C typeSize
bit-1 bit
characterunsigned char or uint32_tDepends on character range
base-charunsigned char
fixnumcl_fixnumMachine word (32 or 64 bits)
ext:cl-indexcl_indexMachine word (32 or 64 bits)
(signed-byte 8)int8_t8 bits
(unsigned-byte 8)uint8_t8 bits
(signed-byte 16)int16_t16 bits
(unsigned-byte 16)uint16_t16 bits
(signed-byte 32)int32_t32 bits
(unsigned-byte 32)uint32_t32 bits
(signed-byte 64)int64_t64 bits
(unsigned-byte 64)uint64_t64 bits
single-float or short-floatfloat32-bits IEEE float
double-floatdouble64-bits IEEE float
long-floatlong doubleBetween 96 and 128 bits
(complex single-float)float _Complex64 bits
(complex double-float)double _Complex128 bits
(complex long-float)long double _ComplexBetween 192 and 256 bits
tcl_objectSize of a pointer.

Let us remark that some of these specialized types might not exist in your platform. This is detected using conditional reading and features (See Numbers).


2.13.3 C Reference

2.13.3.1 Types and constants

C types, limits and enumerations

Constants and types

Constant: ECL_ARRAY_RANK_LIMIT
Constant: ECL_ARRAY_DIMENSION_LIMIT
Constant: ECL_ARRAY_TOTAL_LIMIT
enum: cl_elttype {ecl_aet_object, ...}
Lisp or C typeEnumeration valueLisp or C typeEnumeration value
tecl_aet_object(unsigned-byte 1)ecl_aet_bit
cl_fixnumecl_aet_fixcl_indexecl_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_characterecl_aet_checl_base_charecl_aet_bc
single-floatecl_aet_sfdouble-floatecl_aet_df
long-floatecl_aet_lf(complex long-float)ecl_aet_clf
(complex single-float)ecl_aet_csf(complex double-float)ecl_aet_cdf

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.

2.13.3.2 ecl_aet_to_symbol, ecl_symbol_to_aet

To and from element types

Functions

Function: cl_object ecl_aet_to_symbol (cl_elttype param)
Function: 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 element type.

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

2.13.3.3 Constructors

Creating array and vectors

Functions

Function: cl_object ecl_alloc_simple_vector (cl_index length, cl_elttype element_type);
Function: 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);
Function: 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);
Function: cl_object si_adjust_vector (cl_object vector, cl_object length);

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 ECL_NIL or a non-negative fixnum denoting the fill pointer value.
  • displaced_to is either ECL_NIL or a valid array to which the new array is displaced.
  • displacement is either ECL_NIL or a non-negative value with the array displacement.

Adjustable vector may be adjusted with the function si_adjust_vector.

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

Examples

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

cl_object s = ecl_alloc_simple_vector(11, ecl_aet_bc);

Create a one-dimensional array with a fill pointer

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

An alternative formulation

cl_object type = ecl_make_symbol("BYTE8","EXT");
cl_object a = si_make_array(type, ecl_make_fixnum(16), ECL_NIL, /* adjustable */
                            ecl_make_fixnum(0) /* fill-pointer */,
                            ECL_NIL /* displaced_to */,
                            ECL_NIL /* 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, ECL_NIL, /* adjustable */
                            ECL_NIL /* fill-pointer */,
                            ECL_NIL /* displaced_to */,
                            ECL_NIL /* displacement */);

2.13.3.4 Accessors

Reading and writing array elements

Functions

Function: cl_object ecl_aref (cl_object array, cl_index row_major_index);
Function: cl_object ecl_aset (cl_object array, cl_index row_major_index, cl_object new_value);
Function: cl_object ecl_aref1 (cl_object vector, cl_index row_major_index);
Function: 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.

2.13.3.5 Array properties

Array size, fill pointer, etc.

Functions

Function: cl_elttype ecl_array_elttype (cl_object array);
Function: cl_index ecl_array_rank (cl_object array);
Function: 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.

2.13.3.6 ANSI Dictionary

Common Lisp and C equivalence

Lisp symbolC function
make-arraycl_object cl_make_array(cl_narg narg, cl_object dimension...)
adjust-arraycl_object cl_adjust_array(cl_narg narg, cl_object array, cl_object dimensions, ...)
adjustable-array-pcl_object cl_adjustable_array_p(cl_object array)
arefcl_object cl_aref(cl_narg narg, cl_object array, ...)
(setf aref)cl_object si_aset(cl_narg narg, cl_object array, ...)
array-dimensioncl_object cl_array_dimension(cl_object array, cl_object index)
array-dimensionscl_object cl_array_dimensions(cl_object array)
array-element-typecl_object cl_array_element_type(cl_object array)
array-has-fill-pointer-pcl_object cl_array_has_fill_pointer_p(cl_object array)
array-displacementcl_object cl_array_displacement(cl_object array)
array-in-bounds-pcl_object cl_array_in_bounds_p(cl_narg narg, cl_object array, ...)
array-rankcl_object cl_array_rank(cl_object array)
array-row-major-indexcl_object cl_array_row_major_index(cl_narg narg, cl_object array, ...)
array-total-sizecl_object cl_array_total_size(cl_object array)
arraypcl_object cl_arrayp(cl_object array)
fill-pointercl_object cl_fill_pointer(cl_object array)
(setf fill-pointer)cl_object si_fill_pointer_set(cl_object array, cl_object fill_pointer)
row-major-arefcl_object cl_row_major_aref(cl_object array, cl_object index)
(setf row-major-aref)cl_object si_row_major_aset(cl_object array, cl_object index, cl_object value)
upgraded-array-element-typecl_object cl_upgraded_array_element_type(cl_narg narg, cl_object typespec, ...)
simple-vector-pcl_object cl_simple_vector_p(cl_object object)
svrefcl_object cl_svref(cl_object simple_vector, cl_object index)
(setf svref)cl_object si_svset(cl_object simple_vector, cl_object index, cl_object value)
vectorcl_object cl_vector(cl_narg narg, ...)
vector-popcl_object cl_vector_pop(cl_object vector)
vector-pushcl_object cl_vector_push(cl_object new_element, cl_object vector)
vector-push-extendcl_object cl_vector_push_extend(cl_narg narg, cl_object new_element, cl_object vector, ...)
vectorpcl_object cl_vectorp(cl_object object)
bitcl_object cl_bit(cl_narg narg, cl_object bit_array, ...)
(setf bit)cl_object si_aset(cl_narg narg, cl_object array, ...)
sbitcl_object cl_sbit(cl_narg narg, cl_object bit_array, ...)
(setf sbit)cl_object si_aset(cl_narg narg, cl_object array, ...)
bit-andcl_object cl_bit_and(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-andc1cl_object cl_bit_andc1(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-andc2cl_object cl_bit_andc2(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-eqvcl_object cl_bit_eqv(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-iorcl_object cl_bit_ior(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-nandcl_object cl_bit_nand(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-norcl_object cl_bit_nor(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-orc1cl_object cl_bit_orc1(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-orc2cl_object cl_bit_orc1(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-xorcl_object cl_bit_xor(cl_narg narg, cl_object array1, cl_object array2, ...)
bit-notcl_object cl_bit_not(cl_narg narg, cl_object array, ...)
bit-vector-pcl_object cl_bit_vector_p(cl_object object)
simple-bit-vector-pcl_object cl_simple_bit_vector_p(cl_object object)