overview
·
the Lua API
·
the C API
·
download
·
license
·
back
luaarray is a module that can serve as a C array to Lua table bridge. It allows the creation of C arrays of any dimensionality from within Lua and its subsequent treatment as if they were normal Lua tables. You can also use the C api to expose a C array from within the host application as a Lua table so it can be of use in the efficient representation and manipulation of structures which are array-like by nature, such as images, sounds or vectors and matrices.
luaarray works with Lua versions 5.1 and 5.2.
To use the module you must first require it as usual:
array = require "array"
You can explicitly create an array of some type like this:
a = array.doubles {{1, 2},
{3, 4}}
This creates an array encapsulating a C array of type double[2][2] and initializes it with the elements in a give table. The returned array is a userdata with suitable metamethods so that you can use it in almost any way you would use a normal Lua table, including indexing of specific elements and iteration via pairs and ipairs. You can create arrays of other types by using one of the following istead of array.doubles: array.floats, array.ulongs, array.longs, array.uints, array.ints, array.ushorts, array.shorts, array.uchars, array.chars. The table can also be of any dimensionality providing that its dimensions are consistent. You cannot convert this table to an array for example as it can't be directly and unambiguously mapped to a C array:
> a = array.doubles {{1, 2}, {1, 2, 3}}
Inconsistent array structure (subarray at depth 1 should have 2 elements but has 3).
stack traceback:
[C]: in function 'doubles'
stdin:1: in main chunk
[C]: in ?
In order to facilitate interoperation with modules which pass around arrays as binary data enclosed in strings or light userdata you can convert both of these types to arrays as well but in this case you must explicitly specify the dimensions. For example:
> s = "\010\020\030\040"
> a = array.chars (2, 2, s)
> =array.pretty (a)
{
{10, 20},
{30, 40}
}
You can ommit the dimensions in the case of strings. The returned array will have one dimension (it will be a vector) of size equal to the size of the array divided by the size in bytes of the data type.
Finally you can also use the most generic form of the array constructors with tables as well. If the dimensionality of the table doesn't match the dimensions specified you'll get an error so this allows easy type checking. For example:
> t = {1, 2, 3, 4}
> a = array.doubles (2, 2, t)
Initialization from incompatible table (dimensions don't match).
stack traceback:
[C]: in function 'doubles'
stdin:1: in main chunk
[C]: in ?
It is not always necessary to explicitly create an array. Most if not all functions operating on such arrays in this as well as other modules that will be built on this accept a normal table in the place of an array. The table is then implicitly promoted to an array of a suitable type. As an example the divide function which divides two arrays element by element can be used in any of the following ways.
-- Operate on two explicitly defined arrays.
a, b = array.floats {1, 2, 3}, array.floats {2, 2, 2}
c = array.divide (a, b)
-- Use a normal table in place of the second argument. This is
-- implicitly promoted to a float array.
a = array.floats {1, 2, 3}
b = array.divide (a, {2, 2, 2})
-- Specify both arguments as normal tables which are both implicitly
-- promoted to double arrays (since it's the only type guaranteed not
-- to lead to loss of precision.
a = array.divide ({1, 2, 3}, {2, 2, 2})
The result is always an array of the same type as the arguments, so a float array in the first two cases but a double array in the last.
Apart from division you can perform element-by-element
multiplication, addition, substraction, scaling by a constant and
raising to a power with array.multiply, array.add, array.subtract,
array.scale
and array.raise respectively.
The latter two accept the scalar as the second argument
so array.scale (a, 2)
doubles each element of array a, while
array.raise (a, 2)
squares it. In any case, operating on arrays of incompatible
types results in an error.
You can also copy an array with array.copy, which
creates an entirely separate copy of the array, allocating new
memory for it. To set all elements of an array to some number use
array.set. For example array.set (a, 0) initializes
the array a, which can be of any dimensionality, to all
zero elements.
An array can also be cast to some other dimensionality (in the C
sense) with array.cast. This creates a new array of
different dimensionality which references the same memory as the
initial array. Changing an element in either will be reflected in
the other. For example:
> a = array.doubles {1, 2, 3, 4}
> b = array.cast (2, 2, a)
> =array.pretty (a)
{1, 2, 3, 4}
> =array.pretty (b)
{
{1, 2},
{3, 4}
}
> b[2][2] = 5
> =array.pretty (a)
{1, 2, 3, 5}
You can also use array.slice to slice an array which creates a copy (so it won't reference the elements of the initial array) of the same dimensionality but with only a subrange within each dimension. The array is specified as the first argument and the lowest and highest index of each dimension should be specified in subsequent arguments. For example:
> a = array.doubles {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
> =array.pretty (a)
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}
> b = array.slice (a, 2, 3, 2, 3)
> =array.pretty (b)
{
{5, 6},
{8, 9}
}
This module can be used by a host application which embeds Lua as an extension and configuration language as well allowing efficient exporting of internal C arrays for manipulation by the Lua environment. The API is essentially the same as the Lua API outlined above:
void array_toarray (lua_State *L, int index,
array_Type type, int rank, ...);
void array_toarrayv (lua_State *L, int index,
array_Type type, int rank, int *size);
Push onto the stack an array of the given rank and type initialized by the value at location index in the stack which can be a table, string or light userdata. The rank is the number of dimensions of the array and the length along each dimension is given either as an array of integers (in the case of array_toarrayv or as additional arguments passed after rank. The type can be any of the following constants: ARRAY_TDOUBLE, ARRAY_TFLOAT, ARRAY_TULONG, ARRAY_TLONG, ARRAY_TUINT ARRAY_TINT, ARRAY_TUSHORT, ARRAY_TSHORT, ARRAY_TUCHAR, ARRAY_TCHAR.
void array_createarrayv (lua_State *L, array_Type type, void *values,
int rank, int *size);
void array_createarray (lua_State *L, array_Type type, void *values,
int rank, ...);
Push onto the stack a newly created array of the specified rank, type and size and initialize it with the C array (which must be of the same type and size) specified in values. If values is NULL memory is still allocated to hold the elements of the array but it is not initialized to anything.
void array_copy (lua_State *L, int index);
Push onto the stack a copy of the array at stack location index.
void array_set (lua_State *L, int index, lua_Number c);
Set all elements of the array at stack location index to the number c.
void array_cast (lua_State *L, int index, int rank, ...);
void array_castv (lua_State *L, int index, int rank, int *size);
Push onto the stack an new array which is a cast of the array at location index in the stack. The new array references the same memory as the original array but has different rank and lengths.
void array_slicev (lua_State *L, int index, int *slices);
Push onto the stack an new array which is a slice of the array at location index in the stack. The range of elements along each dimension of the slice is give in the array slices.
array_Array *array_testarray (lua_State *L, int index);
array_Array *array_checkarray (lua_State *L, int index);
array_Array *array_checktyped (lua_State *L, int index, array_Type type);
array_Array *array_testtyped (lua_State *L, int index, array_Type type);
array_Array *array_checkcompatible (lua_State *L, int index, array_Type type, int rank, ...);
array_Array *array_testcompatible (lua_State *L, int index, array_Type type, int rank, ...);
The latest release of luaarray is 0.1, released on April the 12th 2012. You can download the source here.
luaarray is released under the terms and conditions of the MIT/X11 license.