Skip to content

Commit a4f4b93

Browse files
committed
Make sorting functions with comparators type-safe
Now the function interface is part of the Fortran code.
1 parent 5496b62 commit a4f4b93

File tree

4 files changed

+108
-49
lines changed

4 files changed

+108
-49
lines changed

doc/modules/algorithm.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ target-qualified 1-D arrays.
1414

1515
Algorithms that take comparators (e.g. sorting and searching) are instantiated
1616
with function pointers that allow user functions to add arbitrary ordering by
17-
defining ``bind(C)`` functions and calling with ``c_funloc(my_comparator)``.
17+
defining ``bind(C)`` functions.
1818

1919
Wherever possible, array indices are returned as Fortran 1-offset native
2020
integers, with the value 0 indicating off-the-end (e.g. "not found").

src/flc_algorithm.i

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,31 @@ static RETURN_TYPE FUNCNAME ## _cmp(ARGS, bool (*cmp)(T, T)) {
3535

3636
%enddef
3737

38+
// >>> Create a native function pointer interface for the given comparator.
39+
%define %flc_cmp_funptr(CTYPE, FTYPE)
40+
41+
// Define an abstract interface that gets inserted into the module
42+
%fragment("SWIG_cmp_funptr_"{CTYPE}, "fdecl", noblock=1)
43+
{ abstract interface
44+
function SWIG_cmp_funptr_ ## CTYPE(left, right) bind(C) &
45+
result(fresult)
46+
use, intrinsic :: ISO_C_BINDING
47+
FTYPE, intent(in), value :: left, right
48+
logical(C_BOOL) :: fresult
49+
end function
50+
end interface}
51+
52+
%apply bool (*)(SWIGTYPE, SWIGTYPE) { bool (*)(CTYPE, CTYPE) };
53+
%typemap(ftype, in={procedure(SWIG_cmp_funptr_ ## CTYPE)}, fragment="SWIG_cmp_funptr_"{CTYPE}, noblock=1) bool (*)(CTYPE, CTYPE)
54+
{procedure(SWIG_cmp_funptr_ ## CTYPE), pointer}
55+
56+
%enddef
57+
3858
/******************************
3959
* Types
4060
******************************/
4161

62+
// >>> Index integer type
4263
%inline %{
4364
typedef int index_int;
4465
%}
@@ -49,6 +70,7 @@ typedef int index_int;
4970
%typemap(ftype, in={integer(INDEX_INT), intent(in)}) index_int
5071
%{integer(INDEX_INT)%}
5172

73+
// >>> Array types
5274
%apply (SWIGTYPE *DATA, size_t SIZE) { (index_int *IDX, size_t IDXSIZE) };
5375

5476
%apply (const SWIGTYPE *DATA, size_t SIZE) {
@@ -59,6 +81,20 @@ typedef int index_int;
5981
(const int64_t *DATA2, size_t DATASIZE2),
6082
(const double *DATA2, size_t DATASIZE2) };
6183

84+
85+
// >>> Function pointer types
86+
%typemap(fin) bool (*)(SWIGTYPE, SWIGTYPE)
87+
"$1 = c_funloc($input)"
88+
%typemap(findecl, match="fin") bool (*)(SWIGTYPE, SWIGTYPE) ""
89+
%typemap(fout) bool (*)(CTYPE, CTYPE)
90+
"call c_f_procpointer($1, $result)"
91+
%typemap(foutdecl, match="fout") bool (*)(SWIGTYPE, SWIGTYPE) ""
92+
93+
%flc_cmp_funptr(int32_t, integer(C_INT32_T))
94+
%flc_cmp_funptr(int64_t, integer(C_INT64_T))
95+
%flc_cmp_funptr(double, real(C_DOUBLE))
96+
%flc_cmp_funptr(index_int, integer(INDEX_INT))
97+
6298
/******************************
6399
* Sorting
64100
******************************/

0 commit comments

Comments
 (0)