1
1
#:include "common.fypp"
2
2
#:set IRS_KINDS_TYPES = INT_KINDS_TYPES + REAL_KINDS_TYPES + STRING_KINDS_TYPES
3
3
4
+ #:set SIGN_NAME = ["increase", "decrease"]
5
+ #:set SIGN_TYPE = [">", "<"]
6
+ #:set SIGN_OPP_TYPE = ["<", ">"]
7
+ #:set SIGN_NAME_TYPE = list(zip(SIGN_NAME, SIGN_TYPE, SIGN_OPP_TYPE))
8
+
4
9
!! Licensing:
5
10
!!
6
11
!! This file is subjec† both to the Fortran Standard Library license, and
@@ -60,10 +65,28 @@ submodule(stdlib_sorting) stdlib_sorting_sort
60
65
61
66
contains
62
67
68
+ #:for k1, t1 in IRS_KINDS_TYPES
69
+ pure module subroutine ${k1}$_sort( array, reverse )
70
+ ${t1}$, intent(inout) :: array(0:)
71
+ logical, intent(in), optional :: reverse
72
+
73
+ logical :: reverse_
74
+
75
+ reverse_ = .false.
76
+ if(present(reverse)) reverse_ = reverse
63
77
78
+ if(reverse_)then
79
+ call ${k1}$_decrease_sort(array)
80
+ else
81
+ call ${k1}$_increase_sort(array)
82
+ endif
83
+ end subroutine ${k1}$_sort
84
+ #:endfor
85
+
86
+ #:for sname, signt, signoppt in SIGN_NAME_TYPE
64
87
#:for k1, t1 in IRS_KINDS_TYPES
65
88
66
- pure module subroutine ${k1}$_sort( array )
89
+ pure module subroutine ${k1}$_${sname}$ _sort( array )
67
90
! `${k1}$_sort( array )` sorts the input `ARRAY` of type `${t1}$`
68
91
! using a hybrid sort based on the `introsort` of David Musser. As with
69
92
! `introsort`, `${k1}$_sort( array )` is an unstable hybrid comparison
@@ -126,12 +149,12 @@ contains
126
149
u = array( 0 )
127
150
v = array( size(array, kind=int_size)/2-1 )
128
151
w = array( size(array, kind=int_size)-1 )
129
- if ( (u > v) .neqv. (u > w) ) then
152
+ if ( (u ${signt}$ v) .neqv. (u ${signt}$ w) ) then
130
153
x = u
131
154
y = array(0)
132
155
array(0) = array( size( array, kind=int_size ) - 1 )
133
156
array( size( array, kind=int_size ) - 1 ) = y
134
- else if ( (v < u) .neqv. (v < w) ) then
157
+ else if ( (v ${signoppt}$ u) .neqv. (v ${signoppt}$ w) ) then
135
158
x = v
136
159
y = array(size( array, kind=int_size )/2-1)
137
160
array( size( array, kind=int_size )/2-1 ) = &
@@ -143,7 +166,7 @@ contains
143
166
! Partition the array.
144
167
i = -1_int_size
145
168
do j = 0_int_size, size(array, kind=int_size)-2
146
- if ( array(j) < = x ) then
169
+ if ( array(j) ${signoppt}$ = x ) then
147
170
i = i + 1
148
171
y = array(i)
149
172
array(i) = array(j)
@@ -168,7 +191,7 @@ contains
168
191
key = array(j)
169
192
i = j - 1
170
193
do while( i >= 0 )
171
- if ( array(i) < = key ) exit
194
+ if ( array(i) ${signoppt}$ = key ) exit
172
195
array(i+1) = array(i)
173
196
i = i - 1
174
197
end do
@@ -212,10 +235,10 @@ contains
212
235
l = 2_int_size * i + 1_int_size
213
236
r = l + 1_int_size
214
237
if ( l < heap_size ) then
215
- if ( array(l) > array(largest) ) largest = l
238
+ if ( array(l) ${signt}$ array(largest) ) largest = l
216
239
end if
217
240
if ( r < heap_size ) then
218
- if ( array(r) > array(largest) ) largest = r
241
+ if ( array(r) ${signt}$ array(largest) ) largest = r
219
242
end if
220
243
if ( largest /= i ) then
221
244
y = array(i)
@@ -226,14 +249,32 @@ contains
226
249
227
250
end subroutine max_heapify
228
251
229
- end subroutine ${k1}$_sort
252
+ end subroutine ${k1}$_${sname}$ _sort
230
253
231
254
#:endfor
255
+ #:endfor
256
+
232
257
258
+ pure module subroutine char_sort( array, reverse )
259
+ character(len=*), intent(inout) :: array(0:)
260
+ logical, intent(in), optional :: reverse
233
261
262
+ logical :: reverse_
234
263
264
+ reverse_ = .false.
265
+ if(present(reverse)) reverse_ = reverse
266
+
267
+ if(reverse_)then
268
+ call char_decrease_sort(array)
269
+ else
270
+ call char_increase_sort(array)
271
+ endif
272
+ end subroutine char_sort
235
273
236
- pure module subroutine char_sort( array )
274
+
275
+
276
+ #:for sname, signt, signoppt in SIGN_NAME_TYPE
277
+ pure module subroutine char_${sname}$_sort( array )
237
278
! `char_sort( array )` sorts the input `ARRAY` of type `CHARACTER(*)`
238
279
! using a hybrid sort based on the `introsort` of David Musser. As with
239
280
! `introsort`, `char_sort( array )` is an unstable hybrid comparison
@@ -296,12 +337,12 @@ contains
296
337
u = array( 0 )
297
338
v = array( size(array, kind=int_size)/2-1 )
298
339
w = array( size(array, kind=int_size)-1 )
299
- if ( (u > v) .neqv. (u > w) ) then
340
+ if ( (u ${signt}$ v) .neqv. (u ${signt}$ w) ) then
300
341
x = u
301
342
y = array(0)
302
343
array(0) = array( size( array, kind=int_size ) - 1 )
303
344
array( size( array, kind=int_size ) - 1 ) = y
304
- else if ( (v < u) .neqv. (v < w) ) then
345
+ else if ( (v ${signoppt}$ u) .neqv. (v ${signoppt}$ w) ) then
305
346
x = v
306
347
y = array(size( array, kind=int_size )/2-1)
307
348
array( size( array, kind=int_size )/2-1 ) = &
@@ -313,7 +354,7 @@ contains
313
354
! Partition the array.
314
355
i = -1_int_size
315
356
do j = 0_int_size, size(array, kind=int_size)-2
316
- if ( array(j) < = x ) then
357
+ if ( array(j) ${signoppt}$ = x ) then
317
358
i = i + 1
318
359
y = array(i)
319
360
array(i) = array(j)
@@ -338,7 +379,7 @@ contains
338
379
key = array(j)
339
380
i = j - 1
340
381
do while( i >= 0 )
341
- if ( array(i) < = key ) exit
382
+ if ( array(i) ${signoppt}$ = key ) exit
342
383
array(i+1) = array(i)
343
384
i = i - 1
344
385
end do
@@ -382,10 +423,10 @@ contains
382
423
l = 2_int_size * i + 1_int_size
383
424
r = l + 1_int_size
384
425
if ( l < heap_size ) then
385
- if ( array(l) > array(largest) ) largest = l
426
+ if ( array(l) ${signt}$ array(largest) ) largest = l
386
427
end if
387
428
if ( r < heap_size ) then
388
- if ( array(r) > array(largest) ) largest = r
429
+ if ( array(r) ${signt}$ array(largest) ) largest = r
389
430
end if
390
431
if ( largest /= i ) then
391
432
y = array(i)
@@ -396,6 +437,7 @@ contains
396
437
397
438
end subroutine max_heapify
398
439
399
- end subroutine char_sort
440
+ end subroutine char_${sname}$_sort
441
+ #:endfor
400
442
401
443
end submodule stdlib_sorting_sort
0 commit comments