@@ -36,6 +36,9 @@ subroutine %fortrantm(fout, bool)(imout, fout)
36
36
end subroutine
37
37
}
38
38
39
+ //////////////////////////////////////////////////////////////////////////////////////////////////
40
+ // Structure to hold a reference to a 1D array
41
+
39
42
#ifdef __cplusplus
40
43
%fragment("SwigArrayWrapper", "header", fragment="<stdlib.h>") %{
41
44
struct SwigArrayWrapper {
@@ -68,6 +71,45 @@ SWIGINTERN SwigArrayWrapper SwigArrayWrapper_uninitialized() {
68
71
integer(C_SIZE_T), public :: size = 0
69
72
end type}
70
73
74
+ //////////////////////////////////////////////////////////////////////////////////////////////////
75
+ // Structure to hold a reference to a 2D array in contiguous memory
76
+
77
+ #ifdef __cplusplus
78
+ %fragment("Swig2DArrayWrapper", "header", fragment="<stdlib.h>") %{
79
+ struct Swig2DArrayWrapper {
80
+ void* data;
81
+ size_t rows;
82
+ size_t cols;
83
+ };
84
+ %}
85
+ #else
86
+ %fragment("Swig2DArrayWrapper", "header", fragment="<stdlib.h>") %{
87
+ typedef struct {
88
+ void* data;
89
+ size_t rows;
90
+ size_t cols;
91
+ } Swig2DArrayWrapper;
92
+ %}
93
+ #endif
94
+
95
+ %fragment("Swig2DArrayWrapper_uninitialized", "header", fragment="Swig2DArrayWrapper") %{
96
+ SWIGINTERN Swig2DArrayWrapper Swig2DArrayWrapper_uninitialized() {
97
+ Swig2DArrayWrapper result;
98
+ result.data = NULL;
99
+ result.rows = 0;
100
+ result.cols = 0;
101
+ return result;
102
+ }
103
+ %}
104
+
105
+ // Add 2D array wrapper to Fortran types when used
106
+ %fragment("Swig2DArrayWrapper_f", "fdecl", noblock=1)
107
+ { type, bind(C) :: Swig2DArrayWrapper
108
+ type(C_PTR), public :: data = C_NULL_PTR
109
+ integer(C_SIZE_T), public :: rows = 0
110
+ integer(C_SIZE_T), public :: cols = 0
111
+ end type}
112
+
71
113
72
114
/* -------------------------------------------------------------------------
73
115
* MACROS
@@ -155,6 +197,9 @@ SWIGINTERN SwigArrayWrapper SwigArrayWrapper_uninitialized() {
155
197
156
198
%typemap(bindc) CTYPE* = FORTRAN_INTRINSIC_TYPE*;
157
199
200
+ ////////////////////////////////////////////////////////////////////////////////////////////////
201
+ // 1D Arrays
202
+
158
203
// 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
159
204
// ISO C.
160
205
%fragment("SWIG_fin"{CTYPE[]}, "fsubprograms", fragment="SwigArrayWrapper_f", noblock=1)
@@ -195,6 +240,54 @@ end subroutine}
195
240
call %fortrantm(fout, CTYPE[])($1, $input)
196
241
}
197
242
%typemap(fargout) CTYPE const ARRAY[] = CTYPE ARRAY[];
243
+
244
+ ////////////////////////////////////////////////////////////////////////////////////////////////
245
+ // 2D Arrays
246
+
247
+ // 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
248
+ // ISO C.
249
+ %fragment("SWIG_fin"{CTYPE[][]}, "fsubprograms", fragment="Swig2DArrayWrapper_f", noblock=1)
250
+ {subroutine %fortrantm(fin, CTYPE[][])(finp, iminp)
251
+ use, intrinsic :: ISO_C_BINDING
252
+ FTYPE(FKIND), dimension(:,:), intent(in), target :: finp
253
+ type(Swig2DArrayWrapper), intent(out) :: iminp
254
+ integer(C_SIZE_T) :: sz
255
+ FTYPE(FKIND), pointer :: imtemp
256
+
257
+ sz = size(finp, kind=C_SIZE_T)
258
+ if (sz > 0_c_size_t) then
259
+ imtemp => finp(1,1)
260
+ iminp%data = c_loc(imtemp)
261
+ iminp%rows = size(finp, 1, kind=C_SIZE_T)
262
+ iminp%cols = size(finp, 2, kind=C_SIZE_T)
263
+ else
264
+ iminp%data = c_null_ptr
265
+ iminp%rows = 0
266
+ iminp%cols = 0
267
+ end if
268
+ end subroutine}
269
+
270
+ // Fragment for converting 2D array wrapper to a Fortran 2D array
271
+ %fragment("SWIG_fout"{CTYPE[][]}, "fsubprograms", noblock=1)
272
+ {subroutine %fortrantm(fout, CTYPE[][])(imout, fout)
273
+ use, intrinsic :: ISO_C_BINDING
274
+ type(Swig2DArrayWrapper), intent(in) :: imout
275
+ FTYPE(FKIND), dimension(:,:), pointer, intent(out) :: fout
276
+
277
+ if (imout%size > 0) then
278
+ call c_f_pointer(imout%data, fout, [imout%rows, imout%cols])
279
+ else
280
+ fout => NULL()
281
+ endif
282
+ end subroutine}
283
+
284
+ // Define proxy code typemaps for a 2D array of this type
285
+ %fortran_typemap_finout(CTYPE[][], CTYPE ARRAY[][])
286
+ %typemap(fargout, fragment="SWIG_fout"{CTYPE[][]}, noblock=1) CTYPE ARRAY[][] {
287
+ call %fortrantm(fout, CTYPE[][])($1, $input)
288
+ }
289
+ %typemap(fargout) CTYPE const ARRAY[][] = CTYPE ARRAY[][];
290
+
198
291
%enddef
199
292
200
293
/*!
0 commit comments