@@ -11,6 +11,7 @@ module fortran_comparators
11
11
implicit none
12
12
public
13
13
contains
14
+
14
15
function compare_ge (left , right ) bind(C) &
15
16
result(fresult)
16
17
use , intrinsic :: ISO_C_BINDING
@@ -20,12 +21,39 @@ function compare_ge(left, right) bind(C) &
20
21
21
22
fresult = (left >= right)
22
23
end function
24
+
25
+ function compare_ptr (lcptr , rcptr ) bind(C) &
26
+ result(fresult)
27
+ use , intrinsic :: ISO_C_BINDING
28
+ type (C_PTR), intent (in ), value :: lcptr
29
+ type (C_PTR), intent (in ), value :: rcptr
30
+ logical (C_BOOL) :: fresult
31
+ integer (C_INT), pointer :: lval
32
+ integer (C_INT), pointer :: rval
33
+
34
+ ! First check association: null => "less than"
35
+ if (.not. c_associated(lcptr)) then
36
+ fresult = .true.
37
+ return
38
+ elseif (.not. c_associated(rcptr)) then
39
+ fresult = .false.
40
+ return
41
+ endif
42
+
43
+ ! Convert from C to Fortran pointers
44
+ call c_f_pointer(cptr= lcptr, fptr= lval)
45
+ call c_f_pointer(cptr= rcptr, fptr= rval)
46
+
47
+ ! Compare the values
48
+ fresult = (lval < rval)
49
+ end function
23
50
end module
24
51
25
52
program test_algorithm
26
53
implicit none
27
54
call test_sort()
28
55
call test_sort_compare()
56
+ call test_sort_generic()
29
57
call test_argsort()
30
58
31
59
call test_binary_search()
@@ -71,12 +99,48 @@ subroutine test_sort_compare()
71
99
write (* ,outfmt) " Result:" , arr
72
100
end subroutine
73
101
102
+ !- ----------------------------------------------------------------------------!
103
+ subroutine test_sort_generic ()
104
+ use , intrinsic :: ISO_C_BINDING
105
+ use fortran_comparators
106
+ use flc_algorithm, only : sort
107
+ implicit none
108
+ integer (C_INT), dimension (:), allocatable , target :: arr, sorted, expected
109
+ type (c_ptr), dimension (:), allocatable :: ptrs
110
+ integer (C_INT), pointer :: fptr
111
+ integer :: i
112
+
113
+ ! Allcoate the test array
114
+ allocate (arr(5 ), source= [ 200 , 1 , 3 , - 10 , 0 ])
115
+
116
+ ! Create array of pointers
117
+ allocate (ptrs(size (arr)))
118
+ do i = 1 , size (arr)
119
+ ptrs(i) = c_loc(arr(i))
120
+ enddo
121
+
122
+ ! Sort the pointers
123
+ call sort(ptrs, compare_ptr)
124
+
125
+ ! Copy pointers back to an array
126
+ allocate (sorted(size (ptrs)))
127
+ do i = 1 , size (sorted)
128
+ call c_f_pointer(ptrs(i), fptr)
129
+ sorted(i) = fptr
130
+ enddo
131
+
132
+ expected = [- 10 , 0 , 1 , 3 , 200 ]
133
+ do i = 1 , size (sorted)
134
+ ASSERT(sorted(i) == expected(i))
135
+ enddo
136
+ end subroutine
137
+
74
138
!- ----------------------------------------------------------------------------!
75
139
subroutine test_argsort ()
76
140
use flc_algorithm, only : argsort, INDEX_INT
77
141
implicit none
78
142
integer , dimension (5 ) :: iarr = [ 2 , 5 , - 2 , 3 , - 10000 ]
79
- integer (INDEX_INT), dimension (5 ) :: idx
143
+ integer (INDEX_INT), dimension (size (iarr) ) :: idx
80
144
character (len=* ), parameter :: outfmt = " (A12,(8I6))"
81
145
82
146
! Call correctly, with size(idx) == size(iarr)
0 commit comments