The Array API

In the following presention, we use the SIDL int type; however, everything in this section applies to all types except where noted. The basic types are in the SIDL namespace. Table 5.2 shows the prefix for SIDL base types and the actual value type held by the array...


Table 5.2: SIDL types to array function prefixes
SIDL TYPE ARRAY FUNCTION PREFIX VALUE TYPE
bool sidl_bool sidl_bool
char sidl_char char
dcomplex sidl_dcomplex struct sidl_dcomplex
double sidl_double double
fcomplex sidl_fcomplex struct sidl_fcomplex
float sidl_float float
int sidl_int int32_t
long sidl_long int64_t
opaque sidl_opaque void *
string sidl_string char *

For arrays of interfaces or classes, the name of the array function prefix is derived from the fully qualified type name. For example, for the type sidl.BaseClass, the array functions all begin with sidl_BaseClass. For sidl.BaseInterface, they all begin with sidl_BaseInterface.

When you add an object or interface to an array, the reference count of the element being overwritten is decremented, and the reference count of the element being added is incremented. When you get an object or interface from an array, the caller owns the returned reference.

For arrays of strings when you add a string to any array, the array will store a copy of the string. When you retrieve a string from an array, you will receive a copy of the string. You should sidl_String_free the returned string when you are done with it.

When you create an array of interfaces, classes, or strings, all elements of the array are initialized to NULL. Other arrays are not initialized. When an array of interfaces, classes, or strings is destroyed, it releases any held references in the case of objects or interfaces. In the case of strings, it frees any non-NULL pointers.

The name of the data structure that holds the array if int is struct sidl_int__array. For some types, the data structure is an opaque type, and for others, it is defined in a public C header file.

Here are the functions one-by-one:


/* C */
struct sidl_int__array*
sidl_int__array_createCol(int32_t       dimen,
                          const int32_t lower[],
                          const int32_t upper[]);
//
// C++
static sidl::array<int32_t>
sidl::array<int32_t>::createCol(int32_t       dimen,
                                const int32_t lower[],
                                const int32_t upper[]);
C
C FORTRAN 77
       subroutine sidl_int__array_createCol_f(dimen, lower, upper, result)
       integer*4 dimen
       integer*4 lower(dimen), upper(dimen)
       integer*8 result
!
! FORTRAN 90
subroutine createCol(lower, upper, result)
  integer (selected_int_kind(9)), dimension(:), intent(in) :: lower, upper
  type (sidl_int_3d), intent(out) :: result ! type depends on dimension
! dimension of result is inferred from the size of lower

This method creates a column-major, multi-dimensional array in a contiguous block of memory. dimen should be strictly greater than zero, and lower and upper should have dimen elements. lower[i] must be less than or equal to upper[i]-1 for i $\geq$ 0 and i $<$ dimen. If this function fails for some reason, it returns NULL. lower[i] specifies the smallest valid index for dimension i, and upper[i] specifies the largest. Note this definition is somewhat un-C like where the upper bound is often one past the end. In SIDL, the size of dimension i is 1 + upper[i] - lower[i].

The function makes copies of the information provided by dimen, lower, and upper, so the caller is not obliged to maintain those values after the function call.

For FORTRAN, the new array is returned in the last parameter, result. A zero value in result indicates that the operation failed. For Fortran 90, you can use the function not_null to verify that result is a valid array.


/* C */
struct sidl_int__array*
sidl_int__array_createRow(int32_t       dimen,
                          const int32_t lower[],
                          const int32_t upper[]);
//
// C++
static sidl::array<int32_t>
sidl::array<int32_t>::createRow(int32_t       dimen,
                                const int32_t lower[],
                                const int32_t upper[]);
C
C FORTRAN 77
       subroutine sidl_int__array_createRow_f(dimen, lower, upper, result)
       integer*4 dimen
       integer*4 lower(dimen), upper(dimen)
       integer*8 result
!
! FORTRAN 90
subroutine createRow(lower, upper, result)
  integer (selected_int_kind(9)), dimension(:), intent(in) :: lower, upper
  type(sidl_int_3d), intent(out) :: result ! type depends on dimension
! dimension of result is inferred from the size of lower

This method creates a row-major, multi-dimensional array in a continguous block of memory. Other than the difference in the ordering of the array elements, this method is identical to createCol.


/* C */
struct sidl_int__array*
sidl_int__array_create1d(int32_t len);

// C++
static sidl::array<int32_t>
sidl::array<int32_t>::create1d(int32_t len);

C FORTRAN 77
       subroutine sidl_int__array_create1d_f(len, result)
       integer*4 len
       integer*8 result

! FORTRAN 90
subroutine create1d(len, result)
  integer (selected_int_kind(9)), intent(in) :: len
  type(sidl_int_1d), intent(out) :: result

This method creates a dense, one-dimensional vector of ints with a lower index of 0 and an upper index of $len - 1$. This is defined primarily as a convenience for C and C++ programmers. If $len \leq 0$, this routine returns NULL.


/* C */
struct sidl_int__array*
sidl_int__array_create2dCol(int32_t m, int32_t n);

// C++
static sidl::array<int32_t>
sidl::array<int32_t>::create2dCol(int32_t m, int32_t n);

C FORTRAN 77
       subroutine sidl_int__array_create2dCol_f(m, n, result)
       integer*4 m, n
       integer*8 result

! FORTRAN 90
subroutine create2dCol(m, n, result)
  integer (selected_int_kind(9)), intent(in) :: m, n
  type(sidl_int_2d), intent(out) :: result

This method creates a dense, column-major, two-dimensional array of ints with a lower index of $(0, 0)$ and an upper index of $(m - 1, n -
1)$. If $m \leq 0$ or $n \leq 0$, this method returns NULL. This is defined primarily as a convenience for C and C++ programmers.


/* C */
struct sidl_int__array*
sidl_int__array_create2dRow(int32_t m, int32_t n);

// C++
static sidl::array<int32_t>
sidl::array<int32_t>::create2dRow(int32_t m, int32_t n);

C FORTRAN 77
       subroutine sidl_int__array_create2dRow_f(m, n, result)
       integer*4 m, n
       integer*8 result

! FORTRAN 90
subroutine create2dRow(m, n, result)
  integer (selected_int_kind(9)), intent(in) :: m, n
  type(sidl_int_2d), intent(out) :: result

This method creates a dense, row-major, two-dimensional array of ints with a lower index of $(0, 0)$ and an upper index of $(m - 1, n -
1)$. If $m \leq 0$ or $n \leq 0$, this method returns NULL. This is defined primarily as a convenience for C and C++ programmers.


/* C */
struct sidl_int__array *
sidl_int__array_slice(struct sidl_int__array *src,
                      int32_t       dimen,
                      const int32_t numElem[],
                      const int32_t *srcStart,
                      const int32_t *srcStride,
                      const int32_t *newStart);
//
// C++
array<int32_t>
sidl::array<int32_t>::slice(int dimen,
                            const int32_t newElem[],
                            const int32_t *srcStart = 0,
                            const int32_t *srcStride = 0,
                            const int32_t *newStart = 0);
C
C FORTRAN 77
       subroutine sidl_int__array_slice_f(src, dimen, numElem, srcStart,
      $                       srcStride, newStart)
       integer*8 src, result
       integer*4 dimen
       integer*4 numElem(srcDimen), srcStart(srcDimen)
       integer*4 srcStride(srcDimen),  newStart(dimen)
!
! FORTRAN 90
subroutine slice(src, dimen, numElem, srcStart, srcStride, newStart)
  type(sidl_int_3d), intent(in) :: src     ! type depends on dimension
  type(sidl_int_2d), intent(out) :: result ! type depends on dimension
  integer (selected_int_kind(9)), intent(in) :: dimen
  integer (selected_int_kind(9)), intent(in), dimension(:) :: &
     numElem, srcStart, srcStride, newStart

This method will create a sub-array of another array. The resulting array shares data with the original array. The new array can be of the same dimension or potentially less than the original array. If you are removing a dimension, indicate the dimensions to remove by setting numElem[i] to zero for any dimension i that should go away in the new array. The meaning of each argument is covered below.

src
the array to be created will be a subset of this array. If this argument is NULL, NULL will be returned. The returned array borrows data from src, so modifying one array modifies both. In C++, the this pointer takes the place of src.
dimen
this argument must be greater than zero and less than or equal to the dimension of src. An illegal value will cause a NULL return value.
numElem
this specifies how many elements from src should be in the new array in each dimension. A zero entry indicates that the dimension should not appear in the new array. This argument should be an array with an entry for each dimension of src. NULL will be returned for src if either
srcStart[i] + numElem[i] * srcStride[i] $>$ upper[i], or
srcStart[i] + numElem[i] * srcStride[i] $<$ lower[i]

srcStart
this parameter specifies which element of src will be the first element of the new array. If this argument is NULL, the first element of src will be the first element of the new array. If non-NULL, this argument provides the coordinates of an element of src, so it must have an entry for each dimension of src. NULL will be returned for src if either
srcStart[i] < lower[i], or srcStart[i] > upper[i].

srcStride
this argument lets you specify the stride between elements of src for each dimension. For example with a stride of 2, you could create a sub-array with only the odd or even elements of src. If this argument is NULL, the stride is taken to be one in each dimension. If non-NULL, this argument should be an array with an entry for each dimension of src.
newLower
this argument is like the lower argument in a create method. It sets the coordinates for the first element in the new array. If this argument is NULL, the values indicated by srcStart will be used. If non-NULL, this should be an array with dimen elements.
Assuming the method is successful and the return value is named newArray, src[srcStart] refers to the same underlying element as newArray[newStart].

If src is not a borrowed array (i.e., it manages its own data), the returned array can manage its by keeping a reference to src. It is not considered a borrowed array for purposes of smartCopy.


/* C */
struct sidl_int__array*
sidl_int__array_borrow(int32_t*      firstElement,
                       int32_t       dimen,
                       const int32_t lower[],
                       const int32_t upper[],
                       const int32_t stride[]);
//
// C++
void
sidl::array<int32_t>::borrow(int32_t*      firstElement,
                             int32_t       dimen,
                             const int32_t lower[],
                             const int32_t upper[],
                             const int32_t stride[]);
C
C FORTRAN 77
       subroutine sidl_int__array_borrow_f(firstElement, dimen, lower, upper,
     $     stride, result)
       integer*4 firstElement(), dimen, lower(dimen), upper(dimen)
       integer*4 stride(dimen)
       integer*8 result
!
! FORTRAN 90
subroutine borrow(firstElement, dimen, lower, upper, stride, &
                                    result)
  integer (selected_int_kind(9)), intent(in) :: firstElement, dimen
  integer (selected_int_kind(9)), dimension(:), intent(in) :: lower, upper,&
                                              stride
  type(sidl_int_1d), intent(out) :: result ! type depends on array dimension

This method creates a proxy SIDL multi-dimensional array using data provided by a third party. In some cases, this routine can be used to avoid making a copy of the array data. dimen, lower, and upper have the same meaning and constraints as in SIDL_int__array_createCol. The firstElement argument should be a pointer to the first element of the array; in this context, the first element is the one whose index is lower.

stride[i] specifies the signed offset from one element in dimension i to the next element in dimension i. For a one dimensional array, the first element has the address firstElement, the second element has the address firstElement + stride[0], the third element has the address firstElement + 2 * stride[0], etc. The algorithm for determining the address of the element in a multi-dimensional array whose index is in array ind[] is as follows:


int32_t* addr = firstElement;
for(int i = 0; i < dimen; ++i) {
  addr += (ind[i] - lower[i])*stride[i];
}
/* now addr is the address of element ind */

Note elements of stride need not be positive.

The function makes copies of the information provided by dimen, lower, upper, and stride. The type of firstElement is changed depending on the array value type (see Table 5.2).


/* C */
struct sidl_int__array*
sidl_int__array_smartCopy(struct sidl_int__array *array);

// C++
void
sidl::array<int32_t>::smartCopy();

C FORTRAN 77
       subroutine sidl_int__array_smartCopy_f(array, result)
       integer*8 array, result

! FORTRAN 90
subroutine smartCopy(array, result)
  type(sidl_int_1d), intent(in) :: array   ! type depends on dimension
  type(sidl_int_1d), intent(out) :: result ! type depends on dimension

This method will copy a borrowed array or increment the reference count of an array that is able to manage its own data. This method is useful when you want to keep a copy of an incoming array. The C++ method operates on this.


/* C */
void
sidl_int__array_addRef(struct sidl_int__array* array);

// C++
void
sidl::array<int32_t>::addRef() throw ( NullIORException );

C FORTRAN 77
       subroutine sidl_int__array_addRef_f(array)
       integer*8 array

! FORTRAN 90
subroutine addRef(array)
  type(sidl_int_1d), intent(in) :: array ! type depends on array dimension

This increments the reference count by one. In C++, this method should be avoided because the C++ wrapper class manages the reference count for you.


/* C */
void
sidl_int__array_deleteRef(struct sidl_int__array* array);

// C++
void
sidl::array<int32_t>::deleteRef() throw ( NullIORException );

C FORTRAN 77
       subroutine sidl_int__array_deleteRef_f(array)
       integer*8 array

! FORTRAN 90
subroutine deleteRef(array)
  type(sidl_int_1d), intent(out) :: array ! type depends on dimension

This decreases the reference count by one. If this reduces the reference count to zero, the resources associated with the array are reclaimed. In C++, this method should be avoided because the C++ wrapper class manages the reference count for you.


/* C */
int32_t
sidl_int__array_get1(const struct sidl_int__array* array,
                     int32_t                       i1);

// C++
int32_t
sidl::array<int32_t>::get(int32_t i1);

C FORTRAN 77
       subroutine sidl_int__array_get1_f(array, i1, result)
       integer*8 array
       integer*4 i1, result

! FORTRAN 90
subroutine get(array, i1, result)
  type(sidl_int_1d), intent(in) :: array
  integer (selected_int_kind(9)), intent(in) :: i1
  integer (selected_int_kind(9)), intent(out) :: result

This method returns the element with index i1 for a one dimensional array. The return type of this method is the value type for the SIDL type being held (see Table 5.2). This method must only be called for one dimensional arrays. For objects and interfaces, the client owns the returned reference (i.e., the client is obliged to call deleteRef() when they are done with the reference unless it is NULL). For arrays of strings, the client owns the returned string (i.e., the client is obliged to call free on the returned pointer unless it is NULL). There is no reliable way to determine from the return value cases when i1 is out of bounds.


/* C */
int32_t
sidl_int__array_get2(const struct sidl_int__array* array,
                     int32_t                       i1,
                     int32_t                       i2);

// C++
int32_t
sidl::array<int32_t>::get(int32_t i1, int32_t i2);

C FORTRAN 77
       subroutine sidl_int__array_get2_f(array, i1, i2, result)
       integer*8 array
       integer*4 i1, i2, result

! FORTRAN 90
subroutine get(array, i1, i2, result)
  type(sidl_int_2d), intent(in) :: array
  integer (selected_int_kind(9)), intent(in) :: i1, i2
  integer (selected_int_kind(9)), intent(out) :: result

This method returns the element with indices (i1, i2) for a two dimensional array. The return type of this method is the value type for the SIDL type being held (see Table 5.2. This method must only be called for two dimensional arrays. For objects and interfaces, the client owns the returned reference (i.e., the client is obliged to call deleteRef when they are done with the reference unless it is NULL). For arrays of strings, the client owns the returned string (i.e., the client is obliged to call free on the returned pointer unless it is NULL). There is no reliable way to determine from the return value cases when i1, i2 are out of bounds.


/* C */
int32_t
sidl_int__array_get3(const struct sidl_int__array* array,
                     int32_t                       i1,
                     int32_t                       i2,
                     int32_t                       i3);
// C++
int32_t
sidl::array<int32_t>::get(int32_t i1, int32_t i2, int32_t i3);

C FORTRAN 77
       subroutine sidl_int__array_get3_f(array, i1, i2, i3, result)
       integer*8 array
       integer*4 i1, i2, i3, result

! FORTRAN 90
subroutine get(array, i1, i2, i3, result)
  type(sidl_int_3d), intent(in) :: array
  integer (selected_int_kind(9)), intent(in) :: i1, i2, i3
  integer (selected_int_kind(9)), intent(out) :: result

This method returns the element with indices (i1, i2, i3) for a three dimensional array. The return type of this method is the value type for the SIDL type being held (see Table 5.2). This method must only be called for three dimensional arrays. For objects and interfaces, the client owns the returned reference (i.e., the client is obliged to call deleteRef() when they are done with the reference unless it is NULL). For arrays of strings, the client owns the returned string (i.e., the client is obliged to call free() on the returned pointer unless it is NULL). There is no reliable way to determine from the return value cases when i1, i2, i3 are out of bounds.


/* C */
int32_t
sidl_int__array_get4(const struct sidl_int__array* array,
                     int32_t                       i1,
                     int32_t                       i2,
                     int32_t                       i3,
                     int32_t                       i4);
// C++
int32_t
sidl::array<int32_t>::get(int32_t i1, int32_t i2, int32_t i3, int32_t i4);

C FORTRAN 77
       subroutine sidl_int__array_get4_f(array, i1, i2, i3, i4, result)
       integer*8 array
       integer*4 i1, i2, i3, i4, result

! FORTRAN 90
subroutine get(array, i1, i2, i3, i4, result)
  type(sidl_int_4d), intent(in) :: array
  integer (selected_int_kind(9)), intent(in) :: i1, i2, i3, i4
  integer (selected_int_kind(9)), intent(out) :: result

This method returns the element with indices(i1, i2, i3, i4) for a four dimensional array. The return type of this method is the value type for the SIDL type being held (see Table 5.2). This method must only be called for four dimensional arrays. For objects and interfaces, the client owns the returned reference (i.e., the client is obliged to call deleteRef() when they are done with the reference unless it is NULL). For arrays of strings, the client owns the returned string (i.e., the client is obliged to call free() on the returned pointer unless it is NULL). There is no reliable way to determine from the return value cases when i1, i2, i3, or i4 are out of bounds.

Methods get5-get7 are defined in an analogous way.


/* C */
int32_t
sidl_int__array_get(const struct sidl_int__array* array,
                    const int32_t                 indices[]);

// C++
int32_t
sidl::array<int32_t>::get(const int32_t indices[]);

C FORTRAN 77
       subroutine sidl_int__array_get_f(array, indices, result)
       integer*8 array
       integer*4 indices(), result

! FORTRAN 90
subroutine get(array, indices, result)
  type(sidl_int_1d), intent(in) :: array ! type depends on dimension
  integer (selected_int_kind(9)), dimension(:), intent(in) ::indices
  integer (selected_int_kind(9)), intent(out) :: result

This method returns the element whose index is indices for an array of any dimension. The return type of this method is the value type for the SIDL type being held (see Table 5.2). This method can be called for any positively dimensioned array. For objects and interfaces, the client owns the returned reference (i.e., the client is obliged to call deleteRef() when they are done with the reference unless it is NULL). For arrays of strings, the client owns the returned string (i.e., the client is obliged to call free() on the returned pointer unless it is NULL). There is no reliable way to determine from the return value cases when indices has an element out of bounds.


/* C */
int32_t
sidl_int__array_set2(const struct sidl_int__array* array,
                     int32_t                       i1,
                     int32_t                       value));

// C++
int32_t
sidl::array<int32_t>::set(int32_t i1, int32_t value);

C FORTRAN 77
       subroutine sidl_int__array_set1_f(array, i1, value)
       integer*8 array
       integer*4 i1, value

! FORTRAN 90
subroutine set(array, i1, value)
  type(sidl_int_1d), intent(in) :: array
  integer (selected_int_kind(9)), intent(in) :: i1, value

This method sets the value in index i1 of a one dimensional array to value. The type of the argument value is the value type for the SIDL type being held (see Table 5.2). This method must only be called for one dimensional arrays. For arrays of objects and interfaces, the array will make its own reference by calling addRef() on value, so the client retains its reference to value. For arrays of strings, the array will make a copy of the string, so the client retains ownership of the value pointer.


/* C */
int32_t
sidl_int__array_set2(const struct sidl_int__array* array,
                     int32_t                       i1,
                     int32_t                       i2,
                     int32_t                       value));

// C++
int32_t
sidl::array<int32_t>::set(int32_t i1, int32_t i2, int32_t value);

C FORTRAN 77
       subroutine sidl_int__array_set2_f(array, i1, i2, value)
       integer*8 array
       integer*4 i1, i2, value

! FORTRAN 90
subroutine set(array, i1, i2, value)
  type(sidl_int_2d), intent(in) :: array
  integer (selected_int_kind(9)), intent(in) :: i1, i2, value

This method sets the value in index (i1, i2) of a two dimensional array to value. The type of the argument value is the value type for the SIDL type being held (see table 5.2). This method must only be called for two dimensional arrays. For arrays of objects and interfaces, the array will make its own reference by calling addRef() on value, so the client retains its reference to value. For arrays of strings, the array will make a copy of the string, so the client retains ownership of the value pointer.


/* C */
int32_t
sidl_int__array_set3(const struct sidl_int__array* array,
                     int32_t                       i1,
                     int32_t                       i2,
                     int32_t                       i3,
                     int32_t                       value));

// C++
int32_t
sidl::array<int32_t>::set(int32_t i1, int32_t i2, int32_t i3, int32_t value);

C FORTRAN 77
       subroutine sidl_int__array_set3_f(array, i1, i2, i3, value)
       integer*8 array
       integer*4 i1, i2, i3, value

! FORTRAN 90
subroutine set(array, i1, i2, i3, value)
  type(sidl_int_3d), intent(in) :: array
  integer (selected_int_kind(9)), intent(in) :: i1, i2, i3, value

This method sets the value in index (i1, i2, i3) of a three dimensional array to value. The type of the argument value is the value type for the SIDL type being held (see table 5.2). This method must only be called for three dimensional arrays. For arrays of objects and interfaces, the array will make its own reference by calling addRef() on value, so the client retains its reference to value. For arrays of strings, the array will make a copy of the string, so the client retains ownership of the value pointer.


/* C */
int32_t
sidl_int__array_set4(const struct sidl_int__array* array,
                     int32_t                       i1,
                     int32_t                       i2,
                     int32_t                       i3,
                     int32_t                       i4,
                     int32_t                       value));
//
// C++
int32_t
sidl::array<int32_t>::set(int32_t i1, int32_t i2, 
                      int32_t i3, int32_t i4, int32_t value);
C
C FORTRAN 77
       subroutine sidl_int__array_set4_f(array, i1, i2, i3, i4, value)
       integer*8 array
       integer*4 i1, i2, i3, i4, value
!
! FORTRAN 90
subroutine set(array, i1, i2, i3, i4, value)
  type(sidl_int_4d), intent(in) :: array
  integer (selected_int_kind(9)), intent(in) :: i1, i2, i3, i4, value

This method sets the value in index (i1, i2, i3, i4) of a four dimensional array to value. The type of the argument value is the value type for the SIDL type being held (see table 5.2). This method must only be called for four dimensional arrays. For arrays of objects and interfaces, the array will make its own reference by calling addRef() on value, so the client retains its reference to value. For arrays of strings, the array will make a copy of the string, so the client retains ownership of the value pointer.

Methods set5-set7 are defined in an analogous way.


/* C */
void
sidl_int__array_set(struct sidl_int__array* array,
                    const int32_t           indices[],
                    int32_t                 value);

// C++
void
sidl::array<int32_t>::set(const int32_t indices[], int32_t value);

C FORTRAN 77
       subroutine sidl_int__array_set_f(array, indices, value)
       integer*8 array
       integer*4 indices()

! FORTRAN 90
subroutine set(array, indices, value)
  type(sidl_int_1d), intent(in) :: array ! type depends on dimension
  integer (selected_int_kind(9)), intent(in), dimension(:) :: indices
  integer (selected_int_kind(9)), intent(in) :: value

This method sets the value in index indices for an array of any dimension to value. The type of the argument value is the value type for the SIDL type being held (see table 5.2). For arrays of objects and interfaces, the array will make its own reference by calling addRef() on value, so the client retains its reference to value. For arrays of strings, the array will make a copy of the string, so the client retains ownership of the value pointer.


/* C */
int32_t
sidl_int__array_dimen(const struct sidl_int__array *array);

// C++
int32_t
sidl::array<int32_t>::dimen() const;

C FORTRAN 77
       subroutine sidl_int__array_dimen_f(array, result)
       integer*8 array
       integer*4 result

! FORTRAN 90
integer (selected_int_kind(9)) dimen(array)
  type(sidl_int_1d) :: array ! type depends on dimension

This method returns the dimension of the array.


/* C */
int32_t
sidl_int__array_lower(const struct sidl_int__array *array, int32_t ind);

// C++
int32_t
sidl::array<int32_t>::lower(int32_t ind) const;

C FORTRAN 77
       subroutine sidl_int__array_lower_f(array, ind, result)
       integer*8 array
       integer*4 ind, result

! FORTRAN 90
integer (selected_int_kind(9)) function lower(array, ind)
  type(sidl_int_1d), intent(in) :: array ! type depends on dimension
  integer (selected_int_kind(9)) :: ind

This method returns the lower bound on the index for dimension ind of array.


/* C */
int32_t
sidl_int__array_upper(const struct sidl_int__array *array, int32_t ind);

// C++
int32_t
sidl::array<int32_t>::upper(int32_t ind) const;

C FORTRAN 77
       subroutine sidl_int__array_upper_f(array, ind, result)
       integer*8 array
       integer*4 ind, result

! FORTRAN 90
integer (selected_int_kind(9)) function upper(array, ind)
  type(sidl_int_1d), intent(in) :: array ! type depends on dimension
  integer (selected_int_kind(9)), intent(in) :: ind

This method returns the upper bound on the index for dimension ind of array. If the upper bound is greater than or equal to the lower bound, the upper bound is a valid index (i.e., it is not one past the end).


/* C */
int32_t
sidl_int__array_stride(const struct sidl_int__array *array, int32_t ind);

// C++
int32_t
sidl::array<int32_t>::stride(int32_t ind) const;

C FORTRAN 77
       subroutine sidl_int__array_stride_f(array, ind, result)
       integer*8 array
       integer*4 ind, result

! FORTRAN 90
integer (selected_int_kind(9)) function stride(array, ind)
  type(sidl_int_1d), intent(in) :: array ! type depends on dimension
  integer (selected_int_kind(9)) :: ind

This method returns the stride for a particular dimension. This stride indicates how much to add to a pointer to get for the current element this the particular dimension to the next.


/* C */
sidl_bool
sidl_int__array_isColumnOrder(const struct sidl_int__array *array);

// C++
bool
sidl::array<int32_t>::isColumnOrder() const;

C FORTRAN 77
       subroutine sidl_int__array_isColumnOrder_f(array, result)
       integer*8 array
       logical   result

! FORTRAN 90
logical function isColumnOrder(array)
  type(sidl_int_2d), intent(in) :: array ! type depends on dimension

This method returns a true value if and only if array is dense, column-major ordered array. It does not modify the array at all.


/* C */
sidl_bool
sidl_int__array_isRowOrder(const struct sidl_int__array *array);

// C++
bool
sidl::array<int32_t>::isRowOrder() const;

C FORTRAN 77
       subroutine sidl_int__array_isRowOrder_f(array, result)
       integer*8 array
       logical   result

! FORTRAN 90
logical function isRowOrder(array)
  type(sidl_int_1d), intent(int) :: array ! type depends on dimension

This method returns a true value if and only if array is dense, row-major ordered array. It does not modify the array at all.


/* C */
void
sidl_int__array_copy(const struct sidl_int__array *src,
                           struct sidl_int__array *dest);

// C++
void
sidl::array<int32_t>::copy(const sidl::array<int32_t> &src);

C FORTRAN 77
       subroutine sidl_int__array_copy_f(array, dest)
       integer*8 array, dest

! FORTRAN 90
subroutine copy(array, dest)
  type(sidl_int_1d), intent(in) :: array ! type depends on array dimension
  type(sidl_int_1d), intent(in) :: dest  ! type depends on array dimension

This method copies the contents of src to dest. For the copy to take place, both arrays must exist and be of the same dimension. This method will not modify dest's size, index bounds, or stride; only the array element values of dest may be changed by this function. No part of src is changed by this method.

If dest has different index bounds than src, this method only copies the elements where the two arrays overlap. If dest and src have no indices in common, nothing is copied. For example, if src is a 1-d array with elements 0-5 and dest is a 1-d array with element 2-3, this function will copy element 2 and 3 from src to dest. If dest had elements 4-10, this method could copy elements 4 and 5.


/* C */
struct sidl_int__array *
sidl_int__array_ensure(const struct sidl_int__array *src,
                       int32_t                       dimen,
                       int                           ordering);

// C++
void
sidl::array<int32_t>::ensure(int32_t dimen, int ordering);

C FORTRAN 77
       subroutine sidl_int__array_ensure_f(src, dimen, ordering, result)
       integer*8 src, result
       integer*4 dimen, ordering

! FORTRAN 90
subroutine ensure(src, dimen, ordering, result)
   type(sidl_int_1d), intent(in) :: src    ! type depends on array dimension
   type(sidl_int_1d), intent(out) :: result! type depends on array dimension
   integer (selected_int_kind(9)) :: dimen, ordering

This method is used to obtain a matrix with a guaranteed ordering and dimension from an array with uncertain properties. If the incoming array has the required ordering and dimension, its reference count is incremented, and it is returned. If it doesn't, a copy with the correct ordering is created and returned. In either case, the caller knows that the returned matrix (if not NULL) has the desired properties.

This method is used internally to enforce the array ordering constraints in SIDL. Clients can use it in similar ways.

The ordering parameter should be one of the constants defined in enum sidl_array_ordering (e.g. sidl_general_order, sidl_column_major_order, or sidl_row_major_order). If you pass in sidl_general_order, this routine will only check the dimension of the matrix.


/* C */
int32_t *
sidl_int__array_first(const struct sidl_int__array *src);

// C++...Is there an equivalent here?

C FORTRAN 77
      subroutine sidl_int__array_access_f(array, ref, lower, upper,
     $   stride, index)
      integer*8 array
      integer*4 lower(), upper(), stride(), index
      integer*4 ref()

This method provides direct access to the element data. Using this pointer and the stride information, you can perform your own array accesses without function calls. This method isn't available for arrays of strings, interface and objects because of memory/reference management issues.

The FORTRAN versions of the method return the lower, upper and stride information in three arrays, each with enough elements to hold an entry for each dimension of array. Because FORTRAN 77 does not have pointers, you must pass in a reference array, array. Upon exit, ref(index) is the first element of the array. The type of ref depends on the type of the array.

WARNING:While calling the FORTRAN direct access routines, there is a possibility of an alignment error between your reference pointer, ref. The problem is more likely with arrays of double or dcomplex; although, it could occur with any type on some future platform. If index is zero on return, an alignment error occured. If an alignment error occurs, you may be able to solve it by recompiling your FORTRAN files with flags to force doubles to be aligned on 8 byte boundaries. For example, the -malign-double flag for g77 forces doubles to be aligned on 64-bit boundaries. An alignment error occurs when (char *)ref minus (char *)sidl_int__array_first(array) is not integer divisible by sizeof(datatype) where ref refers to the address of the reference array.

Here is an example FORTRAN 77 subroutine to output each element of a 1-dimensional array of doubles using the direct access routine. FORTRAN 90 has a pointer in the array derived type when direct access is possible.


C This subroutine will print each element of an array of doubles
      subroutine print_array(dblarray)
      implicit none
      integer*8 dblarray
      real*8 refarray(1)
      integer*4 lower(1), upper(1), stride(1), index, dimen, i
      if (dblarray .ne. 0) then
         call sidl_double__array_dimen_f(dblarray, dimen)
         if (dimen .eq. 1) then
            call sidl_double__array_access_f(dblarray, refarray,
     $           lower, upper, stride, index)
            if (index .ne. 0) then
               do i = lower(1), upper(1)
                  write(*,*) refarray(index + (i-lower(1))*stride(1))
               enddo
            else
               write(*,*) 'Alignment error occured'
            endif
         endif
      endif
      end

For a 2-dimensional array, the loop and array access is


      do i = lower(1), upper(1)
         do j = lower(2), upper(2)
            write(*,*) refarray(index+(i-lower(1))*stride(1)+
     $           (j - lower(2))*stride(2))
         enddo
      enddo

Suppose you are wrapping a legacy FORTRAN application and you need to pass a SIDL array to a FORTRAN subroutine. Further suppose there is a FORTRAN 77 and FORTRAN 90 version of the subroutine. For example, the FORTRAN 77 subroutine has a signature such as:


      subroutine TriedAndTrue(x, n)
      integer n
      real*8 x(n)
C insert wonderful, efficient, debugged code here
      end

The FORTRAN 90 subroutine has basically the same signature as follows:


subroutine TriedAndTrue(x, n)
  integer (selected_int_kind(9))     :: n
  real (selected_real_kind(17, 308)) :: x(n)

  ! insert wonderful, efficient, debugged code here
end subroutine TriedAndTrue

Here is one way to wrap this method using SIDL. First of all, the SIDL method definition specifies that the array must be a 1-dimensional, column-major ordered array. This forces the incoming array to be a dense column.


    static void TriedAndTrue(inout array<double,1,column-major> arg);

Given that method definition in a class named Class and a package named Pkg, the implementation of the wrapper should look something like the following for FORTRAN 77:


        subroutine Pkg_Class_TriedAndTrue_fi(arg)
        implicit none
        integer*8 arg
C       DO-NOT-DELETE splicer.begin(Pkg.Class.TriedAndTrue)
        real*8 refarray(1)
        integer*4 lower(1), upper(1), stride(1), index
        integer n
        call sidl_double__array_access_f(arg, refarray,
     $       lower, upper, stride, index)
        if (index .ne. 0) then
c we can assume stride(1) = 1 because of column-major specification
           n = 1 + upper(1) - lower(1)
           call TriedAndTrue(refarray(index), n)
        else
           write(*,*) 'ERROR: array alignment'
        endif
C       DO-NOT-DELETE splicer.end(Pkg.Class.TriedAndTrue)
        end

Similarly, it should look something like the following for FORTRAN 90, where the include statements are required at the top of the Impl file to ensure proper handling of subroutine names that have automatically been mangled by the Babel compiler:


#include "Pkg_Class_fAbbrev.h"
#include "sidl_BaseClass_fAbbrev.h"
#include "sidl_BaseInterface_fAbbrev.h"
! DO-NOT-DELETE splicer.begin(_miscellaneous_code_start)
#include "sidl_double_fAbbrev.h"
! DO-NOT-DELETE splicer.end(_miscellaneous_code_start)
.
.
.
subroutine Pkg_Class_TriedAndTrue_mi(arg)
  ! DO-NOT-DELETE splicer.begin(Pkg.Class.TriedAndTrue.use)
  use SIDL_double_array
  ! DO-NOT-DELETE splicer.end(Pkg.Class.TriedAndTrue.use)
  implicit none
  type(sidl_double_a) :: arg

! DO-NOT-DELETE splicer.begin(Pkg.Class.TriedAndTrue)
  real (selected_real_kind(17,308)), dimension(1) :: refarray
  integer (selected_int_kind(8)), dimension(1)    :: low, up, str
  integer (selected_int_kind(8))    :: index, n
  call access(arg, refarray, low, up, str, index)
  if (index .ne. 0) then
    ! We can assume stride(1) = 1 because of column-major specification
    n = 1 + upper(1) - lower(1)
    call TriedAndTrue(refarray(index), n)
  else
    write(*,*) 'ERROR: array alignment'
  endif
! DO-NOT-DELETE splicer.end(Pkg.Class.TriedAndTrue)
end subroutine Pkg_Class_TriedAndTrue_mi



babel-0.9.4
users_guide Last Modified 2004-08-17

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