3 ! Check the fix for PR67779, in which array sections passed in the
4 ! recursive calls to 'quicksort' had an incorrect offset.
6 ! Contributed by Arjen Markus <arjen.markus895@gmail.com>
8 ! NOTE: This is the version of the testcase in comment #16 (from Thomas Koenig)
13 type, abstract
:: myclass
15 procedure(assign_object
), deferred
:: copy
16 procedure(one_lower_than_two
), deferred
:: lower
17 procedure(print_object
), deferred
:: print
18 procedure
, nopass
:: quicksort
! without nopass, it does not work
22 subroutine assign_object( left
, right
)
24 class(myclass
), intent(inout
) :: left
25 class(myclass
), intent(in
) :: right
26 end subroutine assign_object
30 logical function one_lower_than_two( op1
, op2
)
32 class(myclass
), intent(in
) :: op1
, op2
33 end function one_lower_than_two
37 subroutine print_object( obj
)
39 class(myclass
), intent(in
) :: obj
40 end subroutine print_object
44 ! Type containing a real
47 type, extends(myclass
) :: mysortable
50 procedure
:: copy
=> copy_sortable
51 procedure
:: lower
=> lower_sortable
52 procedure
:: print => print_sortable
59 recursive subroutine quicksort( array
)
60 class(myclass
), dimension(:) :: array
62 class(myclass
), allocatable
:: v
, tmp
70 allocate( v
, source
= array(1) )
71 allocate( tmp
, source
= array(1) )
73 call v
%copy( array((j
+i
)/2) ) ! Use the middle element
76 do while ( array(i
)%lower(v
) )
79 do while ( v
%lower(array(j
)) )
84 call tmp
%copy( array(i
) )
85 call array(i
)%copy( array(j
) )
86 call array(j
)%copy( tmp
)
97 call quicksort( array(1:j
) ) ! Problem here
100 if ( i
< size(array
) ) then
101 call quicksort( array(i
:) ) ! ....and here
103 end subroutine quicksort
108 subroutine copy_sortable( left
, right
)
109 class(mysortable
), intent(inout
) :: left
110 class(myclass
), intent(in
) :: right
119 end subroutine copy_sortable
121 logical function lower_sortable( op1
, op2
)
122 class(mysortable
), intent(in
) :: op1
123 class(myclass
), intent(in
) :: op2
127 lower_sortable
= op1
%value
< op2
%value
129 end function lower_sortable
131 subroutine print_sortable( obj
)
132 class(mysortable
), intent(in
) :: obj
134 write(*,'(G0," ")', advance
="no") obj
%value
135 end subroutine print_sortable
137 end module myclass_def
141 program test_quicksort
146 type(mysortable
), dimension(20) :: array
147 real, dimension(20) :: values
149 call random_number(values
)
151 array
%value
= int (1000000 * values
)
153 ! It would be pretty perverse if this failed!
154 if (check (array
)) call abort
156 call quicksort( array
)
158 ! Check the the array is correctly ordered
159 if (.not
.check (array
)) call abort
161 logical function check (arg
)
162 type(mysortable
), dimension(:) :: arg
165 check
= all (arg(2 : s
)%value
.ge
. arg(1 : s
- 1)%value
)
167 end program test_quicksort