@@ -48,6 +48,9 @@ subroutine %fortrantm(fout, bool)(imout, fout)
48
48
end subroutine
49
49
}
50
50
51
+ //////////////////////////////////////////////////////////////////////////////////////////////////
52
+ // Structure to hold a reference to a 1D array
53
+
51
54
#ifdef __cplusplus
52
55
%fragment("SwigArrayWrapper", "header", fragment="<stdlib.h>") %{
53
56
struct SwigArrayWrapper {
@@ -80,6 +83,45 @@ SWIGINTERN SwigArrayWrapper SwigArrayWrapper_uninitialized() {
80
83
integer(C_SIZE_T), public :: size = 0
81
84
end type}
82
85
86
+ //////////////////////////////////////////////////////////////////////////////////////////////////
87
+ // Structure to hold a reference to a 2D array in contiguous memory
88
+
89
+ #ifdef __cplusplus
90
+ %fragment("Swig2DArrayWrapper", "header", fragment="<stdlib.h>") %{
91
+ struct Swig2DArrayWrapper {
92
+ void* data;
93
+ size_t rows;
94
+ size_t cols;
95
+ };
96
+ %}
97
+ #else
98
+ %fragment("Swig2DArrayWrapper", "header", fragment="<stdlib.h>") %{
99
+ typedef struct {
100
+ void* data;
101
+ size_t rows;
102
+ size_t cols;
103
+ } Swig2DArrayWrapper;
104
+ %}
105
+ #endif
106
+
107
+ %fragment("Swig2DArrayWrapper_uninitialized", "header", fragment="Swig2DArrayWrapper") %{
108
+ SWIGINTERN Swig2DArrayWrapper Swig2DArrayWrapper_uninitialized() {
109
+ Swig2DArrayWrapper result;
110
+ result.data = NULL;
111
+ result.rows = 0;
112
+ result.cols = 0;
113
+ return result;
114
+ }
115
+ %}
116
+
117
+ // Add 2D array wrapper to Fortran types when used
118
+ %fragment("Swig2DArrayWrapper_f", "fdecl", noblock=1)
119
+ { type, bind(C) :: Swig2DArrayWrapper
120
+ type(C_PTR), public :: data = C_NULL_PTR
121
+ integer(C_SIZE_T), public :: rows = 0
122
+ integer(C_SIZE_T), public :: cols = 0
123
+ end type}
124
+
83
125
84
126
/* -------------------------------------------------------------------------
85
127
* MACROS
@@ -167,6 +209,9 @@ SWIGINTERN SwigArrayWrapper SwigArrayWrapper_uninitialized() {
167
209
168
210
%typemap(bindc) CTYPE* = FORTRAN_INTRINSIC_TYPE*;
169
211
212
+ ////////////////////////////////////////////////////////////////////////////////////////////////
213
+ // 1D Arrays
214
+
170
215
// Fragment for converting array to array wrapper. This needs the intermediate step of assigning the first element to an array pointer to be compatible with
171
216
// ISO C.
172
217
%fragment("SWIG_fin"{CTYPE[]}, "fsubprograms", fragment="SwigArrayWrapper_f", noblock=1)
@@ -207,6 +252,54 @@ end subroutine}
207
252
call %fortrantm(fout, CTYPE[])($1, $input)
208
253
}
209
254
%typemap(fargout) CTYPE const ARRAY[] = CTYPE ARRAY[];
255
+
256
+ ////////////////////////////////////////////////////////////////////////////////////////////////
257
+ // 2D Arrays
258
+
259
+ // Fragment for converting a 2D array to a 2D array wrapper. This needs the intermediate step of assigning the first element to an array pointer to be compatible with
260
+ // ISO C.
261
+ %fragment("SWIG_fin"{CTYPE[][]}, "fsubprograms", fragment="Swig2DArrayWrapper_f", noblock=1)
262
+ {subroutine %fortrantm(fin, CTYPE[][])(finp, iminp)
263
+ use, intrinsic :: ISO_C_BINDING
264
+ FTYPE(FKIND), dimension(:,:), intent(in), target :: finp
265
+ type(Swig2DArrayWrapper), intent(out) :: iminp
266
+ integer(C_SIZE_T) :: sz
267
+ FTYPE(FKIND), pointer :: imtemp
268
+
269
+ sz = size(finp, kind=C_SIZE_T)
270
+ if (sz > 0_c_size_t) then
271
+ imtemp => finp(1,1)
272
+ iminp%data = c_loc(imtemp)
273
+ iminp%rows = size(finp, 1, kind=C_SIZE_T)
274
+ iminp%cols = size(finp, 2, kind=C_SIZE_T)
275
+ else
276
+ iminp%data = c_null_ptr
277
+ iminp%rows = 0
278
+ iminp%cols = 0
279
+ end if
280
+ end subroutine}
281
+
282
+ // Fragment for converting 2D array wrapper to a Fortran 2D array
283
+ %fragment("SWIG_fout"{CTYPE[][]}, "fsubprograms", noblock=1)
284
+ {subroutine %fortrantm(fout, CTYPE[][])(imout, fout)
285
+ use, intrinsic :: ISO_C_BINDING
286
+ type(Swig2DArrayWrapper), intent(in) :: imout
287
+ FTYPE(FKIND), dimension(:,:), pointer, intent(out) :: fout
288
+
289
+ if (imout%size > 0) then
290
+ call c_f_pointer(imout%data, fout, [imout%rows, imout%cols])
291
+ else
292
+ fout => NULL()
293
+ endif
294
+ end subroutine}
295
+
296
+ // Define proxy code typemaps for a 2D array of this type
297
+ %fortran_typemap_finout(CTYPE[][], CTYPE ARRAY[][])
298
+ %typemap(fargout, fragment="SWIG_fout"{CTYPE[][]}, noblock=1) CTYPE ARRAY[][] {
299
+ call %fortrantm(fout, CTYPE[][])($1, $input)
300
+ }
301
+ %typemap(fargout) CTYPE const ARRAY[][] = CTYPE ARRAY[][];
302
+
210
303
%enddef
211
304
212
305
/*!
0 commit comments