Generic Arrays

The design of the (normal) array data structure enables the concept of a generic array, an array whose data type and dimension are unspecified. In SIDL, a generic array is indicated with the type array$<$ $>$. There is no type or dimension information between the $<$ and $>$.

Generic arrays are useful for making interfaces that are very flexible without requiring numerous methods to be defined. For example, if you were writing an interface to serialize an array, you could write one method void serialize(in array$<$ $>$ array); to handle an array of any type or dimension. Without generic arrays, you would have to define 77 different serialize methods to handle each possible array type and dimension.

In C, you can use the macro API to determine the dimension, bounds on each dimension and stride for a generic array. All other languages except Python provide a function API to determine the same information for a generic array.

Starting with Babel 1.1.0, Babel's Python binding now uses either the Python NumPy or Numeric Python array API. This switch in Babel follows a switch in the Python community where the Python community has deprecated Numeric Python and appointed NumPy as its successor. If you need examples about how to write code that can work with either Python array API look at Babel's array regression tests, arrays and ordering.

The function API for generic arrays includes the following methods: addRef, smartCopy, deleteRef, dimen, lower, upper, length, stride, isColumnOrder, isRowOrder, and type. With the exception of type, these methods have all been presented above. The name of the method has the type left empty. Where the name for addRef in C on a double array is sidl_double_array_addRef, its name is sidl__array_addRef for a generic array. Note, there are two underscores between sidl and array in the generic array case.

The type method is defined as follows in the case of C.

/**
 * Return an integer indicating the type of elements held by the
 * array. Zero is returned if array is NULL.
 */
int32_t
sidl__array_type(const struct sidl__array* array);
It returns a value that indicates what the underlying type of the array actually is. The return value is either zero or one of the values in sidl_array_type.
enum sidl_array_type {
  /* these values must match values used in F77 & F90 too */
  sidl_bool_array      = 1,
  sidl_char_array      = 2,
  sidl_dcomplex_array  = 3,
  sidl_double_array    = 4,
  sidl_fcomplex_array  = 5,
  sidl_float_array     = 6,
  sidl_int_array       = 7,
  sidl_long_array      = 8,
  sidl_opaque_array    = 9,
  sidl_string_array    = 10,
  sidl_interface_array = 11 /* an array of sidl.BaseInterface's */
};
Once you've discovered the underlying type of the generic array, you can safely cast its pointer to the actual pointer type (in languages like C). Each language binding provides a way to cast generic array pointers to specific types and vice versa.

In the case of a sidl_interface_array, you can case the array to an array of sidl.BaseInterface interface references. Your code should treat it as such. You can downcast individual elements of the array as you need. Your code should consider the possibility that downcasting may fail. Babel can only guarantee that the elements of the array are sidl.BaseInterface's.



babel-1.4.0
users_guide Last Modified 2008-10-16

http://www.llnl.gov/CASC/components
components@llnl.gov