@@ -80,31 +80,32 @@ contains
80
80
! a non-increasing sort. The logic of the determination of indexing largely
81
81
! follows the `"Rust" sort` found in `slice.rs`:
82
82
! https://github.com/rust-lang/rust/blob/90eb44a5897c39e3dff9c7e48e3973671dcd9496/src/liballoc/slice.rs#L2159
83
- ! The Rust version is a simplification of the Timsort algorithm described
84
- ! in https://svn.python.org/projects/python/trunk/Objects/listsort.txt, as
83
+ ! The Rust version in turn is a simplification of the Timsort algorithm
84
+ ! described in
85
+ ! https://svn.python.org/projects/python/trunk/Objects/listsort.txt, as
85
86
! it drops both the use of 'galloping' to identify bounds of regions to be
86
87
! sorted and the estimation of the optimal `run size`. However it remains
87
88
! a hybrid sorting algorithm combining an iterative Merge sort controlled
88
89
! by a stack of `RUNS` identified by regions of uniformly decreasing or
89
- ! non-decreasing sequences that may be expanded to a minimum run size, with
90
- ! an insertion sort.
90
+ ! non-decreasing sequences that may be expanded to a minimum run size and
91
+ ! initially processed by an insertion sort.
91
92
!
92
93
! Note the Fortran implementation simplifies the logic as it only has to
93
94
! deal with Fortran arrays of intrinsic types and not the full generality
94
95
! of Rust's arrays and lists for arbitrary types. It also adds the
95
96
! estimation of the optimal `run size` as suggested in Tim Peters'
96
- ! original listsort.txt, and the optional `work` and `iwork` arrays to be
97
+ ! original ` listsort.txt` , and the optional `work` and `iwork` arrays to be
97
98
! used as scratch memory.
98
99
99
- ${t1}$, intent(inout) :: array(0:)
100
+ ${t1}$, intent(inout) :: array(0:)
100
101
${ti}$, intent(out) :: index(0:)
101
- ${t3}$, intent(out), optional :: work(0:)
102
+ ${t3}$, intent(out), optional :: work(0:)
102
103
${ti}$, intent(out), optional :: iwork(0:)
103
- logical, intent(in), optional :: reverse
104
+ logical, intent(in), optional :: reverse
104
105
105
- integer(int_index) :: array_size, i, stat
106
106
${t2}$, allocatable :: buf(:)
107
107
${ti}$, allocatable :: ibuf(:)
108
+ integer(int_index) :: array_size, i, stat
108
109
109
110
array_size = size(array, kind=int_index)
110
111
@@ -189,7 +190,7 @@ contains
189
190
pure subroutine insertion_sort( array, index )
190
191
! Sorts `ARRAY` using an insertion sort, while maintaining consistency in
191
192
! location of the indices in `INDEX` to the elements of `ARRAY`.
192
- ${t1}$, intent(inout) :: array(0:)
193
+ ${t1}$, intent(inout) :: array(0:)
193
194
${ti}$, intent(inout) :: index(0:)
194
195
195
196
integer(int_index) :: i, j
@@ -219,7 +220,6 @@ contains
219
220
!
220
221
! 1. len(-3) > len(-2) + len(-1)
221
222
! 2. len(-2) > len(-1)
222
-
223
223
integer(int_index) :: r
224
224
type(run_type), intent(in), target :: runs(0:)
225
225
@@ -274,7 +274,7 @@ contains
274
274
! Consistency of the indices in `index` with the elements of `array`
275
275
! are maintained.
276
276
277
- ${t1}$, intent(inout) :: array(0:)
277
+ ${t1}$, intent(inout) :: array(0:)
278
278
${ti}$, intent(inout) :: index(0:)
279
279
280
280
${t3}$ :: tmp
@@ -315,9 +315,9 @@ contains
315
315
! worst-case. Consistency of the indices in `index` with the elements of
316
316
! `array` are maintained.
317
317
318
- ${t1}$, intent(inout) :: array(0:)
318
+ ${t1}$, intent(inout) :: array(0:)
319
319
${ti}$, intent(inout) :: index(0:)
320
- ${t3}$, intent(inout) :: buf(0:)
320
+ ${t3}$, intent(inout) :: buf(0:)
321
321
${ti}$, intent(inout) :: ibuf(0:)
322
322
323
323
integer(int_index) :: array_size, finish, min_run, r, r_count, &
@@ -335,7 +335,6 @@ contains
335
335
return
336
336
end if
337
337
338
-
339
338
! Following Rust sort, natural runs in `array` are identified by traversing
340
339
! it backwards. By traversing it backward, merges more often go in the
341
340
! opposite direction (forwards). According to developers of Rust sort,
@@ -385,7 +384,7 @@ contains
385
384
left = runs( r + 1 )
386
385
right = runs( r )
387
386
call merge( array( left % base: &
388
- right % base + right % len - 1 ), &
387
+ right % base + right % len - 1 ), &
389
388
left % len, buf, &
390
389
index( left % base: &
391
390
right % base + right % len - 1 ), ibuf )
@@ -408,9 +407,9 @@ contains
408
407
! using `BUF` as temporary storage, and stores the merged runs into
409
408
! `ARRAY(0:)`. `MID` must be > 0, and < `SIZE(ARRAY)-1`. Buffer `BUF`
410
409
! must be long enough to hold the shorter of the two runs.
411
- ${t1}$, intent(inout) :: array(0:)
412
- integer(int_index), intent(in) :: mid
413
- ${t3}$, intent(inout) :: buf(0:)
410
+ ${t1}$, intent(inout) :: array(0:)
411
+ integer(int_index), intent(in) :: mid
412
+ ${t3}$, intent(inout) :: buf(0:)
414
413
${ti}$, intent(inout) :: index(0:)
415
414
${ti}$, intent(inout) :: ibuf(0:)
416
415
0 commit comments