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...
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 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 . This is defined primarily
as a convenience for C and C++ programmers. If
, 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 and an upper index of
. If
or
, 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 and an upper index of
.
If
or
, 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.
srcStart[i] + numElem[i] * srcStride[i] | ![]() |
upper[i], or |
srcStart[i] + numElem[i] * srcStride[i] | ![]() |
lower[i] |
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