Skip to content

Commit 0e1dd54

Browse files
committed
Add test of fully generic sorting algorithm
1 parent 3270666 commit 0e1dd54

File tree

1 file changed

+65
-1
lines changed

1 file changed

+65
-1
lines changed

test/test_algorithm.F90

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module fortran_comparators
1111
implicit none
1212
public
1313
contains
14+
1415
function compare_ge(left, right) bind(C) &
1516
result(fresult)
1617
use, intrinsic :: ISO_C_BINDING
@@ -20,12 +21,39 @@ function compare_ge(left, right) bind(C) &
2021

2122
fresult = (left >= right)
2223
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
2350
end module
2451

2552
program test_algorithm
2653
implicit none
2754
call test_sort()
2855
call test_sort_compare()
56+
call test_sort_generic()
2957
call test_argsort()
3058

3159
call test_binary_search()
@@ -71,12 +99,48 @@ subroutine test_sort_compare()
7199
write(*,outfmt) "Result:", arr
72100
end subroutine
73101

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+
74138
!-----------------------------------------------------------------------------!
75139
subroutine test_argsort()
76140
use flc_algorithm, only : argsort, INDEX_INT
77141
implicit none
78142
integer, dimension(5) :: iarr = [ 2, 5, -2, 3, -10000]
79-
integer(INDEX_INT), dimension(5) :: idx
143+
integer(INDEX_INT), dimension(size(iarr)) :: idx
80144
character(len=*), parameter :: outfmt = "(A12,(8I6))"
81145

82146
! Call correctly, with size(idx) == size(iarr)

0 commit comments

Comments
 (0)