comparison liboctave/oct-sort.cc @ 11586:12df7854fa7c

strip trailing whitespace from source files
author John W. Eaton <jwe@octave.org>
date Thu, 20 Jan 2011 17:24:59 -0500
parents fd0a3ac60b0e
children 01b7a60e2ff0
comparison
equal deleted inserted replaced
11585:1473d0cf86d2 11586:12df7854fa7c
25 code I ripped-off. 25 code I ripped-off.
26 26
27 As required in the Python license the short description of the changes 27 As required in the Python license the short description of the changes
28 made are 28 made are
29 29
30 * convert the sorting code in listobject.cc into a generic class, 30 * convert the sorting code in listobject.cc into a generic class,
31 replacing PyObject* with the type of the class T. 31 replacing PyObject* with the type of the class T.
32 32
33 * replaced usages of malloc, free, memcpy and memmove by standard C++ 33 * replaced usages of malloc, free, memcpy and memmove by standard C++
34 new [], delete [] and std::copy and std::copy_backward. Note that replacing 34 new [], delete [] and std::copy and std::copy_backward. Note that replacing
35 memmove by std::copy is possible if the destination starts before the source. 35 memmove by std::copy is possible if the destination starts before the source.
36 If not, std::copy_backward needs to be used. 36 If not, std::copy_backward needs to be used.
37 37
38 * templatize comparison operator in most methods, provide possible dispatch 38 * templatize comparison operator in most methods, provide possible dispatch
39 39
40 * duplicate methods to avoid by-the-way indexed sorting 40 * duplicate methods to avoid by-the-way indexed sorting
41 41
42 * add methods for verifying sortedness of array 42 * add methods for verifying sortedness of array
115 #include "quit.h" 115 #include "quit.h"
116 #include "oct-sort.h" 116 #include "oct-sort.h"
117 #include "oct-locbuf.h" 117 #include "oct-locbuf.h"
118 118
119 template <class T> 119 template <class T>
120 octave_sort<T>::octave_sort (void) : 120 octave_sort<T>::octave_sort (void) :
121 compare (ascending_compare), ms (0) 121 compare (ascending_compare), ms (0)
122 { 122 {
123 } 123 }
124 124
125 template <class T> 125 template <class T>
126 octave_sort<T>::octave_sort (compare_fcn_type comp) 126 octave_sort<T>::octave_sort (compare_fcn_type comp)
127 : compare (comp), ms (0) 127 : compare (comp), ms (0)
128 { 128 {
129 } 129 }
130 130
131 template <class T> 131 template <class T>
132 octave_sort<T>::~octave_sort () 132 octave_sort<T>::~octave_sort ()
133 { 133 {
134 delete ms; 134 delete ms;
135 } 135 }
136 136
137 template <class T> 137 template <class T>
138 void 138 void
147 } 147 }
148 148
149 template <class T> 149 template <class T>
150 template <class Comp> 150 template <class Comp>
151 void 151 void
152 octave_sort<T>::binarysort (T *data, octave_idx_type nel, 152 octave_sort<T>::binarysort (T *data, octave_idx_type nel,
153 octave_idx_type start, Comp comp) 153 octave_idx_type start, Comp comp)
154 { 154 {
155 if (start == 0) 155 if (start == 0)
156 ++start; 156 ++start;
157 157
158 for (; start < nel; ++start) 158 for (; start < nel; ++start)
159 { 159 {
160 /* set l to where *start belongs */ 160 /* set l to where *start belongs */
161 octave_idx_type l = 0, r = start; 161 octave_idx_type l = 0, r = start;
162 T pivot = data[start]; 162 T pivot = data[start];
163 /* Invariants: 163 /* Invariants:
164 * pivot >= all in [lo, l). 164 * pivot >= all in [lo, l).
165 * pivot < all in [r, start). 165 * pivot < all in [r, start).
166 * The second is vacuously true at the start. 166 * The second is vacuously true at the start.
167 */ 167 */
168 do 168 do
169 { 169 {
170 octave_idx_type p = l + ((r - l) >> 1); 170 octave_idx_type p = l + ((r - l) >> 1);
171 if (comp (pivot, data[p])) 171 if (comp (pivot, data[p]))
172 r = p; 172 r = p;
173 else 173 else
174 l = p+1; 174 l = p+1;
175 } 175 }
176 while (l < r); 176 while (l < r);
177 /* The invariants still hold, so pivot >= all in [lo, l) and 177 /* The invariants still hold, so pivot >= all in [lo, l) and
178 pivot < all in [l, start), so pivot belongs at l. Note 178 pivot < all in [l, start), so pivot belongs at l. Note
179 that if there are elements equal to pivot, l points to the 179 that if there are elements equal to pivot, l points to the
180 first slot after them -- that's why this sort is stable. 180 first slot after them -- that's why this sort is stable.
191 } 191 }
192 192
193 template <class T> 193 template <class T>
194 template <class Comp> 194 template <class Comp>
195 void 195 void
196 octave_sort<T>::binarysort (T *data, octave_idx_type *idx, octave_idx_type nel, 196 octave_sort<T>::binarysort (T *data, octave_idx_type *idx, octave_idx_type nel,
197 octave_idx_type start, Comp comp) 197 octave_idx_type start, Comp comp)
198 { 198 {
199 if (start == 0) 199 if (start == 0)
200 ++start; 200 ++start;
201 201
202 for (; start < nel; ++start) 202 for (; start < nel; ++start)
203 { 203 {
204 /* set l to where *start belongs */ 204 /* set l to where *start belongs */
205 octave_idx_type l = 0, r = start; 205 octave_idx_type l = 0, r = start;
206 T pivot = data[start]; 206 T pivot = data[start];
207 /* Invariants: 207 /* Invariants:
208 * pivot >= all in [lo, l). 208 * pivot >= all in [lo, l).
209 * pivot < all in [r, start). 209 * pivot < all in [r, start).
210 * The second is vacuously true at the start. 210 * The second is vacuously true at the start.
211 */ 211 */
212 do 212 do
213 { 213 {
214 octave_idx_type p = l + ((r - l) >> 1); 214 octave_idx_type p = l + ((r - l) >> 1);
215 if (comp (pivot, data[p])) 215 if (comp (pivot, data[p]))
216 r = p; 216 r = p;
217 else 217 else
218 l = p+1; 218 l = p+1;
219 } 219 }
220 while (l < r); 220 while (l < r);
221 /* The invariants still hold, so pivot >= all in [lo, l) and 221 /* The invariants still hold, so pivot >= all in [lo, l) and
222 pivot < all in [l, start), so pivot belongs at l. Note 222 pivot < all in [l, start), so pivot belongs at l. Note
223 that if there are elements equal to pivot, l points to the 223 that if there are elements equal to pivot, l points to the
224 first slot after them -- that's why this sort is stable. 224 first slot after them -- that's why this sort is stable.
272 n = 2; 272 n = 2;
273 273
274 if (comp (*lo, *(lo-1))) 274 if (comp (*lo, *(lo-1)))
275 { 275 {
276 descending = true; 276 descending = true;
277 for (lo = lo+1; lo < hi; ++lo, ++n) 277 for (lo = lo+1; lo < hi; ++lo, ++n)
278 { 278 {
279 if (comp (*lo, *(lo-1))) 279 if (comp (*lo, *(lo-1)))
280 ; 280 ;
281 else 281 else
282 break; 282 break;
283 } 283 }
284 } 284 }
285 else 285 else
286 { 286 {
287 for (lo = lo+1; lo < hi; ++lo, ++n) 287 for (lo = lo+1; lo < hi; ++lo, ++n)
288 { 288 {
289 if (comp (*lo, *(lo-1))) 289 if (comp (*lo, *(lo-1)))
290 break; 290 break;
291 } 291 }
292 } 292 }
332 { 332 {
333 /* a[hint] < key -- gallop right, until 333 /* a[hint] < key -- gallop right, until
334 * a[hint + lastofs] < key <= a[hint + ofs] 334 * a[hint + lastofs] < key <= a[hint + ofs]
335 */ 335 */
336 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */ 336 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */
337 while (ofs < maxofs) 337 while (ofs < maxofs)
338 { 338 {
339 if (comp (a[ofs], key)) 339 if (comp (a[ofs], key))
340 { 340 {
341 lastofs = ofs; 341 lastofs = ofs;
342 ofs = (ofs << 1) + 1; 342 ofs = (ofs << 1) + 1;
350 ofs = maxofs; 350 ofs = maxofs;
351 /* Translate back to offsets relative to &a[0]. */ 351 /* Translate back to offsets relative to &a[0]. */
352 lastofs += hint; 352 lastofs += hint;
353 ofs += hint; 353 ofs += hint;
354 } 354 }
355 else 355 else
356 { 356 {
357 /* key <= a[hint] -- gallop left, until 357 /* key <= a[hint] -- gallop left, until
358 * a[hint - ofs] < key <= a[hint - lastofs] 358 * a[hint - ofs] < key <= a[hint - lastofs]
359 */ 359 */
360 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */ 360 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */
361 while (ofs < maxofs) 361 while (ofs < maxofs)
362 { 362 {
363 if (comp (*(a-ofs), key)) 363 if (comp (*(a-ofs), key))
364 break; 364 break;
365 /* key <= a[hint - ofs] */ 365 /* key <= a[hint - ofs] */
366 lastofs = ofs; 366 lastofs = ofs;
380 /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the 380 /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the
381 * right of lastofs but no farther right than ofs. Do a binary 381 * right of lastofs but no farther right than ofs. Do a binary
382 * search, with invariant a[lastofs-1] < key <= a[ofs]. 382 * search, with invariant a[lastofs-1] < key <= a[ofs].
383 */ 383 */
384 ++lastofs; 384 ++lastofs;
385 while (lastofs < ofs) 385 while (lastofs < ofs)
386 { 386 {
387 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1); 387 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1);
388 388
389 if (comp (a[m], key)) 389 if (comp (a[m], key))
390 lastofs = m+1; /* a[m] < key */ 390 lastofs = m+1; /* a[m] < key */
426 { 426 {
427 /* key < a[hint] -- gallop left, until 427 /* key < a[hint] -- gallop left, until
428 * a[hint - ofs] <= key < a[hint - lastofs] 428 * a[hint - ofs] <= key < a[hint - lastofs]
429 */ 429 */
430 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */ 430 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */
431 while (ofs < maxofs) 431 while (ofs < maxofs)
432 { 432 {
433 if (comp (key, *(a-ofs))) 433 if (comp (key, *(a-ofs)))
434 { 434 {
435 lastofs = ofs; 435 lastofs = ofs;
436 ofs = (ofs << 1) + 1; 436 ofs = (ofs << 1) + 1;
445 /* Translate back to positive offsets relative to &a[0]. */ 445 /* Translate back to positive offsets relative to &a[0]. */
446 k = lastofs; 446 k = lastofs;
447 lastofs = hint - ofs; 447 lastofs = hint - ofs;
448 ofs = hint - k; 448 ofs = hint - k;
449 } 449 }
450 else 450 else
451 { 451 {
452 /* a[hint] <= key -- gallop right, until 452 /* a[hint] <= key -- gallop right, until
453 * a[hint + lastofs] <= key < a[hint + ofs] 453 * a[hint + lastofs] <= key < a[hint + ofs]
454 */ 454 */
455 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */ 455 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */
456 while (ofs < maxofs) 456 while (ofs < maxofs)
457 { 457 {
458 if (comp (key, a[ofs])) 458 if (comp (key, a[ofs]))
459 break; 459 break;
460 /* a[hint + ofs] <= key */ 460 /* a[hint + ofs] <= key */
461 lastofs = ofs; 461 lastofs = ofs;
474 /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the 474 /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the
475 * right of lastofs but no farther right than ofs. Do a binary 475 * right of lastofs but no farther right than ofs. Do a binary
476 * search, with invariant a[lastofs-1] <= key < a[ofs]. 476 * search, with invariant a[lastofs-1] <= key < a[ofs].
477 */ 477 */
478 ++lastofs; 478 ++lastofs;
479 while (lastofs < ofs) 479 while (lastofs < ofs)
480 { 480 {
481 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1); 481 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1);
482 482
483 if (comp (key, a[m])) 483 if (comp (key, a[m]))
484 ofs = m; /* key < a[m] */ 484 ofs = m; /* key < a[m] */
534 octave_sort<T>::MergeState::getmem (octave_idx_type need) 534 octave_sort<T>::MergeState::getmem (octave_idx_type need)
535 { 535 {
536 if (need <= alloced) 536 if (need <= alloced)
537 return; 537 return;
538 538
539 need = roundupsize (need); 539 need = roundupsize (need);
540 /* Don't realloc! That can cost cycles to copy the old data, but 540 /* Don't realloc! That can cost cycles to copy the old data, but
541 * we don't care what's in the block. 541 * we don't care what's in the block.
542 */ 542 */
543 delete [] a; 543 delete [] a;
544 delete [] ia; // Must do this or fool possible next getmemi. 544 delete [] ia; // Must do this or fool possible next getmemi.
552 octave_sort<T>::MergeState::getmemi (octave_idx_type need) 552 octave_sort<T>::MergeState::getmemi (octave_idx_type need)
553 { 553 {
554 if (ia && need <= alloced) 554 if (ia && need <= alloced)
555 return; 555 return;
556 556
557 need = roundupsize (need); 557 need = roundupsize (need);
558 /* Don't realloc! That can cost cycles to copy the old data, but 558 /* Don't realloc! That can cost cycles to copy the old data, but
559 * we don't care what's in the block. 559 * we don't care what's in the block.
560 */ 560 */
561 delete [] a; 561 delete [] a;
562 delete [] ia; 562 delete [] ia;
573 * Return 0 if successful, -1 if error. 573 * Return 0 if successful, -1 if error.
574 */ 574 */
575 template <class T> 575 template <class T>
576 template <class Comp> 576 template <class Comp>
577 int 577 int
578 octave_sort<T>::merge_lo (T *pa, octave_idx_type na, 578 octave_sort<T>::merge_lo (T *pa, octave_idx_type na,
579 T *pb, octave_idx_type nb, 579 T *pb, octave_idx_type nb,
580 Comp comp) 580 Comp comp)
581 { 581 {
582 octave_idx_type k; 582 octave_idx_type k;
583 T *dest; 583 T *dest;
608 for (;;) 608 for (;;)
609 { 609 {
610 610
611 // FIXME: these loops are candidates for further optimizations. 611 // FIXME: these loops are candidates for further optimizations.
612 // Rather than testing everything in each cycle, it may be more 612 // Rather than testing everything in each cycle, it may be more
613 // efficient to do it in hunks. 613 // efficient to do it in hunks.
614 if (comp (*pb, *pa)) 614 if (comp (*pb, *pa))
615 { 615 {
616 *dest++ = *pb++; 616 *dest++ = *pb++;
617 ++bcount; 617 ++bcount;
618 acount = 0; 618 acount = 0;
708 } 708 }
709 709
710 template <class T> 710 template <class T>
711 template <class Comp> 711 template <class Comp>
712 int 712 int
713 octave_sort<T>::merge_lo (T *pa, octave_idx_type *ipa, octave_idx_type na, 713 octave_sort<T>::merge_lo (T *pa, octave_idx_type *ipa, octave_idx_type na,
714 T *pb, octave_idx_type *ipb, octave_idx_type nb, 714 T *pb, octave_idx_type *ipb, octave_idx_type nb,
715 Comp comp) 715 Comp comp)
716 { 716 {
717 octave_idx_type k; 717 octave_idx_type k;
718 T *dest; 718 T *dest;
855 * Return 0 if successful, -1 if error. 855 * Return 0 if successful, -1 if error.
856 */ 856 */
857 template <class T> 857 template <class T>
858 template <class Comp> 858 template <class Comp>
859 int 859 int
860 octave_sort<T>::merge_hi (T *pa, octave_idx_type na, 860 octave_sort<T>::merge_hi (T *pa, octave_idx_type na,
861 T *pb, octave_idx_type nb, 861 T *pb, octave_idx_type nb,
862 Comp comp) 862 Comp comp)
863 { 863 {
864 octave_idx_type k; 864 octave_idx_type k;
865 T *dest; 865 T *dest;
881 if (na == 0) 881 if (na == 0)
882 goto Succeed; 882 goto Succeed;
883 if (nb == 1) 883 if (nb == 1)
884 goto CopyA; 884 goto CopyA;
885 885
886 for (;;) 886 for (;;)
887 { 887 {
888 octave_idx_type acount = 0; /* # of times A won in a row */ 888 octave_idx_type acount = 0; /* # of times A won in a row */
889 octave_idx_type bcount = 0; /* # of times B won in a row */ 889 octave_idx_type bcount = 0; /* # of times B won in a row */
890 890
891 /* Do the straightforward thing until (if ever) one run 891 /* Do the straightforward thing until (if ever) one run
892 * appears to win consistently. 892 * appears to win consistently.
893 */ 893 */
894 for (;;) 894 for (;;)
895 { 895 {
896 if (comp (*pb, *pa)) 896 if (comp (*pb, *pa))
897 { 897 {
898 *dest-- = *pa--; 898 *dest-- = *pa--;
899 ++acount; 899 ++acount;
902 if (na == 0) 902 if (na == 0)
903 goto Succeed; 903 goto Succeed;
904 if (acount >= min_gallop) 904 if (acount >= min_gallop)
905 break; 905 break;
906 } 906 }
907 else 907 else
908 { 908 {
909 *dest-- = *pb--; 909 *dest-- = *pb--;
910 ++bcount; 910 ++bcount;
911 acount = 0; 911 acount = 0;
912 --nb; 912 --nb;
921 * be a huge win. So try that, and continue galloping until 921 * be a huge win. So try that, and continue galloping until
922 * (if ever) neither run appears to be winning consistently 922 * (if ever) neither run appears to be winning consistently
923 * anymore. 923 * anymore.
924 */ 924 */
925 ++min_gallop; 925 ++min_gallop;
926 do 926 do
927 { 927 {
928 min_gallop -= min_gallop > 1; 928 min_gallop -= min_gallop > 1;
929 ms->min_gallop = min_gallop; 929 ms->min_gallop = min_gallop;
930 k = gallop_right (*pb, basea, na, na-1, comp); 930 k = gallop_right (*pb, basea, na, na-1, comp);
931 if (k < 0) 931 if (k < 0)
932 goto Fail; 932 goto Fail;
933 k = na - k; 933 k = na - k;
934 acount = k; 934 acount = k;
935 if (k) 935 if (k)
936 { 936 {
937 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1; 937 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1;
938 pa -= k; 938 pa -= k;
939 na -= k; 939 na -= k;
940 if (na == 0) 940 if (na == 0)
948 k = gallop_left (*pa, baseb, nb, nb-1, comp); 948 k = gallop_left (*pa, baseb, nb, nb-1, comp);
949 if (k < 0) 949 if (k < 0)
950 goto Fail; 950 goto Fail;
951 k = nb - k; 951 k = nb - k;
952 bcount = k; 952 bcount = k;
953 if (k) 953 if (k)
954 { 954 {
955 dest -= k; 955 dest -= k;
956 pb -= k; 956 pb -= k;
957 std::copy (pb+1, pb+1 + k, dest+1); 957 std::copy (pb+1, pb+1 + k, dest+1);
958 nb -= k; 958 nb -= k;
992 } 992 }
993 993
994 template <class T> 994 template <class T>
995 template <class Comp> 995 template <class Comp>
996 int 996 int
997 octave_sort<T>::merge_hi (T *pa, octave_idx_type *ipa, octave_idx_type na, 997 octave_sort<T>::merge_hi (T *pa, octave_idx_type *ipa, octave_idx_type na,
998 T *pb, octave_idx_type *ipb, octave_idx_type nb, 998 T *pb, octave_idx_type *ipb, octave_idx_type nb,
999 Comp comp) 999 Comp comp)
1000 { 1000 {
1001 octave_idx_type k; 1001 octave_idx_type k;
1002 T *dest; 1002 T *dest;
1022 if (na == 0) 1022 if (na == 0)
1023 goto Succeed; 1023 goto Succeed;
1024 if (nb == 1) 1024 if (nb == 1)
1025 goto CopyA; 1025 goto CopyA;
1026 1026
1027 for (;;) 1027 for (;;)
1028 { 1028 {
1029 octave_idx_type acount = 0; /* # of times A won in a row */ 1029 octave_idx_type acount = 0; /* # of times A won in a row */
1030 octave_idx_type bcount = 0; /* # of times B won in a row */ 1030 octave_idx_type bcount = 0; /* # of times B won in a row */
1031 1031
1032 /* Do the straightforward thing until (if ever) one run 1032 /* Do the straightforward thing until (if ever) one run
1033 * appears to win consistently. 1033 * appears to win consistently.
1034 */ 1034 */
1035 for (;;) 1035 for (;;)
1036 { 1036 {
1037 if (comp (*pb, *pa)) 1037 if (comp (*pb, *pa))
1038 { 1038 {
1039 *dest-- = *pa--; *idest-- = *ipa--; 1039 *dest-- = *pa--; *idest-- = *ipa--;
1040 ++acount; 1040 ++acount;
1043 if (na == 0) 1043 if (na == 0)
1044 goto Succeed; 1044 goto Succeed;
1045 if (acount >= min_gallop) 1045 if (acount >= min_gallop)
1046 break; 1046 break;
1047 } 1047 }
1048 else 1048 else
1049 { 1049 {
1050 *dest-- = *pb--; *idest-- = *ipb--; 1050 *dest-- = *pb--; *idest-- = *ipb--;
1051 ++bcount; 1051 ++bcount;
1052 acount = 0; 1052 acount = 0;
1053 --nb; 1053 --nb;
1062 * be a huge win. So try that, and continue galloping until 1062 * be a huge win. So try that, and continue galloping until
1063 * (if ever) neither run appears to be winning consistently 1063 * (if ever) neither run appears to be winning consistently
1064 * anymore. 1064 * anymore.
1065 */ 1065 */
1066 ++min_gallop; 1066 ++min_gallop;
1067 do 1067 do
1068 { 1068 {
1069 min_gallop -= min_gallop > 1; 1069 min_gallop -= min_gallop > 1;
1070 ms->min_gallop = min_gallop; 1070 ms->min_gallop = min_gallop;
1071 k = gallop_right (*pb, basea, na, na-1, comp); 1071 k = gallop_right (*pb, basea, na, na-1, comp);
1072 if (k < 0) 1072 if (k < 0)
1073 goto Fail; 1073 goto Fail;
1074 k = na - k; 1074 k = na - k;
1075 acount = k; 1075 acount = k;
1076 if (k) 1076 if (k)
1077 { 1077 {
1078 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1; 1078 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1;
1079 idest = std::copy_backward (ipa+1 - k, ipa+1, idest+1) - 1; 1079 idest = std::copy_backward (ipa+1 - k, ipa+1, idest+1) - 1;
1080 pa -= k; ipa -= k; 1080 pa -= k; ipa -= k;
1081 na -= k; 1081 na -= k;
1090 k = gallop_left (*pa, baseb, nb, nb-1, comp); 1090 k = gallop_left (*pa, baseb, nb, nb-1, comp);
1091 if (k < 0) 1091 if (k < 0)
1092 goto Fail; 1092 goto Fail;
1093 k = nb - k; 1093 k = nb - k;
1094 bcount = k; 1094 bcount = k;
1095 if (k) 1095 if (k)
1096 { 1096 {
1097 dest -= k; idest -= k; 1097 dest -= k; idest -= k;
1098 pb -= k; ipb -= k; 1098 pb -= k; ipb -= k;
1099 std::copy (pb+1, pb+1 + k, dest+1); 1099 std::copy (pb+1, pb+1 + k, dest+1);
1100 std::copy (ipb+1, ipb+1 + k, idest+1); 1100 std::copy (ipb+1, ipb+1 + k, idest+1);
1261 int 1261 int
1262 octave_sort<T>::merge_collapse (T *data, Comp comp) 1262 octave_sort<T>::merge_collapse (T *data, Comp comp)
1263 { 1263 {
1264 struct s_slice *p = ms->pending; 1264 struct s_slice *p = ms->pending;
1265 1265
1266 while (ms->n > 1) 1266 while (ms->n > 1)
1267 { 1267 {
1268 octave_idx_type n = ms->n - 2; 1268 octave_idx_type n = ms->n - 2;
1269 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) 1269 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len)
1270 { 1270 {
1271 if (p[n-1].len < p[n+1].len) 1271 if (p[n-1].len < p[n+1].len)
1272 --n; 1272 --n;
1273 if (merge_at (n, data, comp) < 0) 1273 if (merge_at (n, data, comp) < 0)
1274 return -1; 1274 return -1;
1275 } 1275 }
1276 else if (p[n].len <= p[n+1].len) 1276 else if (p[n].len <= p[n+1].len)
1277 { 1277 {
1278 if (merge_at (n, data, comp) < 0) 1278 if (merge_at (n, data, comp) < 0)
1279 return -1; 1279 return -1;
1280 } 1280 }
1281 else 1281 else
1290 int 1290 int
1291 octave_sort<T>::merge_collapse (T *data, octave_idx_type *idx, Comp comp) 1291 octave_sort<T>::merge_collapse (T *data, octave_idx_type *idx, Comp comp)
1292 { 1292 {
1293 struct s_slice *p = ms->pending; 1293 struct s_slice *p = ms->pending;
1294 1294
1295 while (ms->n > 1) 1295 while (ms->n > 1)
1296 { 1296 {
1297 octave_idx_type n = ms->n - 2; 1297 octave_idx_type n = ms->n - 2;
1298 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) 1298 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len)
1299 { 1299 {
1300 if (p[n-1].len < p[n+1].len) 1300 if (p[n-1].len < p[n+1].len)
1301 --n; 1301 --n;
1302 if (merge_at (n, data, idx, comp) < 0) 1302 if (merge_at (n, data, idx, comp) < 0)
1303 return -1; 1303 return -1;
1304 } 1304 }
1305 else if (p[n].len <= p[n+1].len) 1305 else if (p[n].len <= p[n+1].len)
1306 { 1306 {
1307 if (merge_at (n, data, idx, comp) < 0) 1307 if (merge_at (n, data, idx, comp) < 0)
1308 return -1; 1308 return -1;
1309 } 1309 }
1310 else 1310 else
1324 int 1324 int
1325 octave_sort<T>::merge_force_collapse (T *data, Comp comp) 1325 octave_sort<T>::merge_force_collapse (T *data, Comp comp)
1326 { 1326 {
1327 struct s_slice *p = ms->pending; 1327 struct s_slice *p = ms->pending;
1328 1328
1329 while (ms->n > 1) 1329 while (ms->n > 1)
1330 { 1330 {
1331 octave_idx_type n = ms->n - 2; 1331 octave_idx_type n = ms->n - 2;
1332 if (n > 0 && p[n-1].len < p[n+1].len) 1332 if (n > 0 && p[n-1].len < p[n+1].len)
1333 --n; 1333 --n;
1334 if (merge_at (n, data, comp) < 0) 1334 if (merge_at (n, data, comp) < 0)
1343 int 1343 int
1344 octave_sort<T>::merge_force_collapse (T *data, octave_idx_type *idx, Comp comp) 1344 octave_sort<T>::merge_force_collapse (T *data, octave_idx_type *idx, Comp comp)
1345 { 1345 {
1346 struct s_slice *p = ms->pending; 1346 struct s_slice *p = ms->pending;
1347 1347
1348 while (ms->n > 1) 1348 while (ms->n > 1)
1349 { 1349 {
1350 octave_idx_type n = ms->n - 2; 1350 octave_idx_type n = ms->n - 2;
1351 if (n > 0 && p[n-1].len < p[n+1].len) 1351 if (n > 0 && p[n-1].len < p[n+1].len)
1352 --n; 1352 --n;
1353 if (merge_at (n, data, idx, comp) < 0) 1353 if (merge_at (n, data, idx, comp) < 0)
1393 ms->reset (); 1393 ms->reset ();
1394 ms->getmem (1024); 1394 ms->getmem (1024);
1395 1395
1396 if (nel > 1) 1396 if (nel > 1)
1397 { 1397 {
1398 octave_idx_type nremaining = nel; 1398 octave_idx_type nremaining = nel;
1399 octave_idx_type lo = 0; 1399 octave_idx_type lo = 0;
1400 1400
1401 /* March over the array once, left to right, finding natural runs, 1401 /* March over the array once, left to right, finding natural runs,
1402 * and extending short natural runs to minrun elements. 1402 * and extending short natural runs to minrun elements.
1403 */ 1403 */
1404 octave_idx_type minrun = merge_compute_minrun (nremaining); 1404 octave_idx_type minrun = merge_compute_minrun (nremaining);
1405 do 1405 do
1406 { 1406 {
1407 bool descending; 1407 bool descending;
1408 octave_idx_type n; 1408 octave_idx_type n;
1409 1409
1410 /* Identify next run. */ 1410 /* Identify next run. */
1412 if (n < 0) 1412 if (n < 0)
1413 goto fail; 1413 goto fail;
1414 if (descending) 1414 if (descending)
1415 std::reverse (data + lo, data + lo + n); 1415 std::reverse (data + lo, data + lo + n);
1416 /* If short, extend to min(minrun, nremaining). */ 1416 /* If short, extend to min(minrun, nremaining). */
1417 if (n < minrun) 1417 if (n < minrun)
1418 { 1418 {
1419 const octave_idx_type force = nremaining <= minrun ? nremaining : minrun; 1419 const octave_idx_type force = nremaining <= minrun ? nremaining : minrun;
1420 binarysort (data + lo, force, n, comp); 1420 binarysort (data + lo, force, n, comp);
1421 n = force; 1421 n = force;
1422 } 1422 }
1441 } 1441 }
1442 1442
1443 template <class T> 1443 template <class T>
1444 template <class Comp> 1444 template <class Comp>
1445 void 1445 void
1446 octave_sort<T>::sort (T *data, octave_idx_type *idx, octave_idx_type nel, 1446 octave_sort<T>::sort (T *data, octave_idx_type *idx, octave_idx_type nel,
1447 Comp comp) 1447 Comp comp)
1448 { 1448 {
1449 /* Re-initialize the Mergestate as this might be the second time called */ 1449 /* Re-initialize the Mergestate as this might be the second time called */
1450 if (! ms) ms = new MergeState; 1450 if (! ms) ms = new MergeState;
1451 1451
1452 ms->reset (); 1452 ms->reset ();
1453 ms->getmemi (1024); 1453 ms->getmemi (1024);
1454 1454
1455 if (nel > 1) 1455 if (nel > 1)
1456 { 1456 {
1457 octave_idx_type nremaining = nel; 1457 octave_idx_type nremaining = nel;
1458 octave_idx_type lo = 0; 1458 octave_idx_type lo = 0;
1459 1459
1460 /* March over the array once, left to right, finding natural runs, 1460 /* March over the array once, left to right, finding natural runs,
1461 * and extending short natural runs to minrun elements. 1461 * and extending short natural runs to minrun elements.
1462 */ 1462 */
1463 octave_idx_type minrun = merge_compute_minrun (nremaining); 1463 octave_idx_type minrun = merge_compute_minrun (nremaining);
1464 do 1464 do
1465 { 1465 {
1466 bool descending; 1466 bool descending;
1467 octave_idx_type n; 1467 octave_idx_type n;
1468 1468
1469 /* Identify next run. */ 1469 /* Identify next run. */
1474 { 1474 {
1475 std::reverse (data + lo, data + lo + n); 1475 std::reverse (data + lo, data + lo + n);
1476 std::reverse (idx + lo, idx + lo + n); 1476 std::reverse (idx + lo, idx + lo + n);
1477 } 1477 }
1478 /* If short, extend to min(minrun, nremaining). */ 1478 /* If short, extend to min(minrun, nremaining). */
1479 if (n < minrun) 1479 if (n < minrun)
1480 { 1480 {
1481 const octave_idx_type force = nremaining <= minrun ? nremaining : minrun; 1481 const octave_idx_type force = nremaining <= minrun ? nremaining : minrun;
1482 binarysort (data + lo, idx + lo, force, n, comp); 1482 binarysort (data + lo, idx + lo, force, n, comp);
1483 n = force; 1483 n = force;
1484 } 1484 }
1509 #ifdef INLINE_ASCENDING_SORT 1509 #ifdef INLINE_ASCENDING_SORT
1510 if (compare == ascending_compare) 1510 if (compare == ascending_compare)
1511 sort (data, nel, std::less<T> ()); 1511 sort (data, nel, std::less<T> ());
1512 else 1512 else
1513 #endif 1513 #endif
1514 #ifdef INLINE_DESCENDING_SORT 1514 #ifdef INLINE_DESCENDING_SORT
1515 if (compare == descending_compare) 1515 if (compare == descending_compare)
1516 sort (data, nel, std::greater<T> ()); 1516 sort (data, nel, std::greater<T> ());
1517 else 1517 else
1518 #endif 1518 #endif
1519 if (compare) 1519 if (compare)
1527 #ifdef INLINE_ASCENDING_SORT 1527 #ifdef INLINE_ASCENDING_SORT
1528 if (compare == ascending_compare) 1528 if (compare == ascending_compare)
1529 sort (data, idx, nel, std::less<T> ()); 1529 sort (data, idx, nel, std::less<T> ());
1530 else 1530 else
1531 #endif 1531 #endif
1532 #ifdef INLINE_DESCENDING_SORT 1532 #ifdef INLINE_DESCENDING_SORT
1533 if (compare == descending_compare) 1533 if (compare == descending_compare)
1534 sort (data, idx, nel, std::greater<T> ()); 1534 sort (data, idx, nel, std::greater<T> ());
1535 else 1535 else
1536 #endif 1536 #endif
1537 if (compare) 1537 if (compare)
1538 sort (data, idx, nel, compare); 1538 sort (data, idx, nel, compare);
1539 } 1539 }
1540 1540
1541 template <class T> template <class Comp> 1541 template <class T> template <class Comp>
1542 bool 1542 bool
1543 octave_sort<T>::is_sorted (const T *data, octave_idx_type nel, Comp comp) 1543 octave_sort<T>::is_sorted (const T *data, octave_idx_type nel, Comp comp)
1544 { 1544 {
1545 const T *end = data + nel; 1545 const T *end = data + nel;
1546 if (data != end) 1546 if (data != end)
1547 { 1547 {
1556 } 1556 }
1557 1557
1558 return data == end; 1558 return data == end;
1559 } 1559 }
1560 1560
1561 template <class T> 1561 template <class T>
1562 bool 1562 bool
1563 octave_sort<T>::is_sorted (const T *data, octave_idx_type nel) 1563 octave_sort<T>::is_sorted (const T *data, octave_idx_type nel)
1564 { 1564 {
1565 bool retval = false; 1565 bool retval = false;
1566 #ifdef INLINE_ASCENDING_SORT 1566 #ifdef INLINE_ASCENDING_SORT
1567 if (compare == ascending_compare) 1567 if (compare == ascending_compare)
1568 retval = is_sorted (data, nel, std::less<T> ()); 1568 retval = is_sorted (data, nel, std::less<T> ());
1569 else 1569 else
1570 #endif 1570 #endif
1571 #ifdef INLINE_DESCENDING_SORT 1571 #ifdef INLINE_DESCENDING_SORT
1572 if (compare == descending_compare) 1572 if (compare == descending_compare)
1573 retval = is_sorted (data, nel, std::greater<T> ()); 1573 retval = is_sorted (data, nel, std::greater<T> ());
1574 else 1574 else
1575 #endif 1575 #endif
1576 if (compare) 1576 if (compare)
1587 octave_idx_type col, ofs, nel; 1587 octave_idx_type col, ofs, nel;
1588 }; 1588 };
1589 1589
1590 1590
1591 template <class T> template <class Comp> 1591 template <class T> template <class Comp>
1592 void 1592 void
1593 octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx, 1593 octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx,
1594 octave_idx_type rows, octave_idx_type cols, 1594 octave_idx_type rows, octave_idx_type cols,
1595 Comp comp) 1595 Comp comp)
1596 { 1596 {
1597 OCTAVE_LOCAL_BUFFER (T, buf, rows); 1597 OCTAVE_LOCAL_BUFFER (T, buf, rows);
1645 } 1645 }
1646 } 1646 }
1647 } 1647 }
1648 1648
1649 template <class T> 1649 template <class T>
1650 void 1650 void
1651 octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx, 1651 octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx,
1652 octave_idx_type rows, octave_idx_type cols) 1652 octave_idx_type rows, octave_idx_type cols)
1653 { 1653 {
1654 #ifdef INLINE_ASCENDING_SORT 1654 #ifdef INLINE_ASCENDING_SORT
1655 if (compare == ascending_compare) 1655 if (compare == ascending_compare)
1656 sort_rows (data, idx, rows, cols, std::less<T> ()); 1656 sort_rows (data, idx, rows, cols, std::less<T> ());
1657 else 1657 else
1658 #endif 1658 #endif
1659 #ifdef INLINE_DESCENDING_SORT 1659 #ifdef INLINE_DESCENDING_SORT
1660 if (compare == descending_compare) 1660 if (compare == descending_compare)
1661 sort_rows (data, idx, rows, cols, std::greater<T> ()); 1661 sort_rows (data, idx, rows, cols, std::greater<T> ());
1662 else 1662 else
1663 #endif 1663 #endif
1664 if (compare) 1664 if (compare)
1665 sort_rows (data, idx, rows, cols, compare); 1665 sort_rows (data, idx, rows, cols, compare);
1666 } 1666 }
1667 1667
1668 template <class T> template <class Comp> 1668 template <class T> template <class Comp>
1669 bool 1669 bool
1670 octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows, 1670 octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows,
1671 octave_idx_type cols, Comp comp) 1671 octave_idx_type cols, Comp comp)
1672 { 1672 {
1673 if (rows <= 1 || cols == 0) 1673 if (rows <= 1 || cols == 0)
1674 return true; 1674 return true;
1675 1675
1676 // This is a breadth-first traversal. 1676 // This is a breadth-first traversal.
1677 const T *lastrow = data + rows*(cols - 1); 1677 const T *lastrow = data + rows*(cols - 1);
1678 typedef std::pair<const T *, octave_idx_type> run_t; 1678 typedef std::pair<const T *, octave_idx_type> run_t;
1679 std::stack<run_t> runs; 1679 std::stack<run_t> runs;
1680 1680
1715 } 1715 }
1716 else 1716 else
1717 // The final column - use fast code. 1717 // The final column - use fast code.
1718 sorted = is_sorted (lo, n, comp); 1718 sorted = is_sorted (lo, n, comp);
1719 } 1719 }
1720 1720
1721 return sorted; 1721 return sorted;
1722 } 1722 }
1723 1723
1724 template <class T> 1724 template <class T>
1725 bool 1725 bool
1726 octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows, 1726 octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows,
1727 octave_idx_type cols) 1727 octave_idx_type cols)
1728 { 1728 {
1729 bool retval = false; 1729 bool retval = false;
1730 1730
1731 #ifdef INLINE_ASCENDING_SORT 1731 #ifdef INLINE_ASCENDING_SORT
1732 if (compare == ascending_compare) 1732 if (compare == ascending_compare)
1733 retval = is_sorted_rows (data, rows, cols, std::less<T> ()); 1733 retval = is_sorted_rows (data, rows, cols, std::less<T> ());
1734 else 1734 else
1735 #endif 1735 #endif
1736 #ifdef INLINE_DESCENDING_SORT 1736 #ifdef INLINE_DESCENDING_SORT
1737 if (compare == descending_compare) 1737 if (compare == descending_compare)
1738 retval = is_sorted_rows (data, rows, cols, std::greater<T> ()); 1738 retval = is_sorted_rows (data, rows, cols, std::greater<T> ());
1739 else 1739 else
1740 #endif 1740 #endif
1741 if (compare) 1741 if (compare)
1745 } 1745 }
1746 1746
1747 // The simple binary lookup. 1747 // The simple binary lookup.
1748 1748
1749 template <class T> template <class Comp> 1749 template <class T> template <class Comp>
1750 octave_idx_type 1750 octave_idx_type
1751 octave_sort<T>::lookup (const T *data, octave_idx_type nel, 1751 octave_sort<T>::lookup (const T *data, octave_idx_type nel,
1752 const T& value, Comp comp) 1752 const T& value, Comp comp)
1753 { 1753 {
1754 octave_idx_type lo = 0, hi = nel; 1754 octave_idx_type lo = 0, hi = nel;
1755 1755
1764 1764
1765 return lo; 1765 return lo;
1766 } 1766 }
1767 1767
1768 template <class T> 1768 template <class T>
1769 octave_idx_type 1769 octave_idx_type
1770 octave_sort<T>::lookup (const T *data, octave_idx_type nel, 1770 octave_sort<T>::lookup (const T *data, octave_idx_type nel,
1771 const T& value) 1771 const T& value)
1772 { 1772 {
1773 octave_idx_type retval = 0; 1773 octave_idx_type retval = 0;
1774 1774
1775 #ifdef INLINE_ASCENDING_SORT 1775 #ifdef INLINE_ASCENDING_SORT
1776 if (compare == ascending_compare) 1776 if (compare == ascending_compare)
1777 retval = lookup (data, nel, value, std::less<T> ()); 1777 retval = lookup (data, nel, value, std::less<T> ());
1778 else 1778 else
1779 #endif 1779 #endif
1780 #ifdef INLINE_DESCENDING_SORT 1780 #ifdef INLINE_DESCENDING_SORT
1781 if (compare == descending_compare) 1781 if (compare == descending_compare)
1782 retval = lookup (data, nel, value, std::greater<T> ()); 1782 retval = lookup (data, nel, value, std::greater<T> ());
1783 else 1783 else
1784 #endif 1784 #endif
1785 if (compare) 1785 if (compare)
1787 1787
1788 return retval; 1788 return retval;
1789 } 1789 }
1790 1790
1791 template <class T> template <class Comp> 1791 template <class T> template <class Comp>
1792 void 1792 void
1793 octave_sort<T>::lookup (const T *data, octave_idx_type nel, 1793 octave_sort<T>::lookup (const T *data, octave_idx_type nel,
1794 const T *values, octave_idx_type nvalues, 1794 const T *values, octave_idx_type nvalues,
1795 octave_idx_type *idx, Comp comp) 1795 octave_idx_type *idx, Comp comp)
1796 { 1796 {
1797 // Use a sequence of binary lookups. 1797 // Use a sequence of binary lookups.
1800 for (octave_idx_type j = 0; j < nvalues; j++) 1800 for (octave_idx_type j = 0; j < nvalues; j++)
1801 idx[j] = lookup (data, nel, values[j], comp); 1801 idx[j] = lookup (data, nel, values[j], comp);
1802 } 1802 }
1803 1803
1804 template <class T> 1804 template <class T>
1805 void 1805 void
1806 octave_sort<T>::lookup (const T *data, octave_idx_type nel, 1806 octave_sort<T>::lookup (const T *data, octave_idx_type nel,
1807 const T* values, octave_idx_type nvalues, 1807 const T* values, octave_idx_type nvalues,
1808 octave_idx_type *idx) 1808 octave_idx_type *idx)
1809 { 1809 {
1810 #ifdef INLINE_ASCENDING_SORT 1810 #ifdef INLINE_ASCENDING_SORT
1811 if (compare == ascending_compare) 1811 if (compare == ascending_compare)
1812 lookup (data, nel, values, nvalues, idx, std::less<T> ()); 1812 lookup (data, nel, values, nvalues, idx, std::less<T> ());
1813 else 1813 else
1814 #endif 1814 #endif
1815 #ifdef INLINE_DESCENDING_SORT 1815 #ifdef INLINE_DESCENDING_SORT
1816 if (compare == descending_compare) 1816 if (compare == descending_compare)
1817 lookup (data, nel, values, nvalues, idx, std::greater<T> ()); 1817 lookup (data, nel, values, nvalues, idx, std::greater<T> ());
1818 else 1818 else
1819 #endif 1819 #endif
1820 if (compare) 1820 if (compare)
1821 lookup (data, nel, values, nvalues, idx, std::ptr_fun (compare)); 1821 lookup (data, nel, values, nvalues, idx, std::ptr_fun (compare));
1822 } 1822 }
1823 1823
1824 template <class T> template <class Comp> 1824 template <class T> template <class Comp>
1825 void 1825 void
1826 octave_sort<T>::lookup_sorted (const T *data, octave_idx_type nel, 1826 octave_sort<T>::lookup_sorted (const T *data, octave_idx_type nel,
1827 const T *values, octave_idx_type nvalues, 1827 const T *values, octave_idx_type nvalues,
1828 octave_idx_type *idx, bool rev, Comp comp) 1828 octave_idx_type *idx, bool rev, Comp comp)
1829 { 1829 {
1830 if (rev) 1830 if (rev)
1872 idx[j] = i; 1872 idx[j] = i;
1873 } 1873 }
1874 } 1874 }
1875 1875
1876 template <class T> 1876 template <class T>
1877 void 1877 void
1878 octave_sort<T>::lookup_sorted (const T *data, octave_idx_type nel, 1878 octave_sort<T>::lookup_sorted (const T *data, octave_idx_type nel,
1879 const T* values, octave_idx_type nvalues, 1879 const T* values, octave_idx_type nvalues,
1880 octave_idx_type *idx, bool rev) 1880 octave_idx_type *idx, bool rev)
1881 { 1881 {
1882 #ifdef INLINE_ASCENDING_SORT 1882 #ifdef INLINE_ASCENDING_SORT
1883 if (compare == ascending_compare) 1883 if (compare == ascending_compare)
1884 lookup_sorted (data, nel, values, nvalues, idx, rev, std::less<T> ()); 1884 lookup_sorted (data, nel, values, nvalues, idx, rev, std::less<T> ());
1885 else 1885 else
1886 #endif 1886 #endif
1887 #ifdef INLINE_DESCENDING_SORT 1887 #ifdef INLINE_DESCENDING_SORT
1888 if (compare == descending_compare) 1888 if (compare == descending_compare)
1889 lookup_sorted (data, nel, values, nvalues, idx, rev, std::greater<T> ()); 1889 lookup_sorted (data, nel, values, nvalues, idx, rev, std::greater<T> ());
1890 else 1890 else
1891 #endif 1891 #endif
1892 if (compare) 1892 if (compare)
1893 lookup_sorted (data, nel, values, nvalues, idx, rev, std::ptr_fun (compare)); 1893 lookup_sorted (data, nel, values, nvalues, idx, rev, std::ptr_fun (compare));
1894 } 1894 }
1895 1895
1896 template <class T> template <class Comp> 1896 template <class T> template <class Comp>
1897 void 1897 void
1898 octave_sort<T>::nth_element (T *data, octave_idx_type nel, 1898 octave_sort<T>::nth_element (T *data, octave_idx_type nel,
1899 octave_idx_type lo, octave_idx_type up, 1899 octave_idx_type lo, octave_idx_type up,
1900 Comp comp) 1900 Comp comp)
1901 { 1901 {
1902 // Simply wrap the STL algorithms. 1902 // Simply wrap the STL algorithms.
1909 { 1909 {
1910 std::nth_element (data, data + lo, data + nel, comp); 1910 std::nth_element (data, data + lo, data + nel, comp);
1911 if (up == lo + 2) 1911 if (up == lo + 2)
1912 { 1912 {
1913 // Finding two subsequent elements. 1913 // Finding two subsequent elements.
1914 std::swap (data[lo+1], 1914 std::swap (data[lo+1],
1915 *std::min_element (data + lo + 1, data + nel, comp)); 1915 *std::min_element (data + lo + 1, data + nel, comp));
1916 } 1916 }
1917 else 1917 else
1918 std::partial_sort (data + lo + 1, data + up, data + nel, comp); 1918 std::partial_sort (data + lo + 1, data + up, data + nel, comp);
1919 } 1919 }
1920 } 1920 }
1921 1921
1922 template <class T> 1922 template <class T>
1923 void 1923 void
1924 octave_sort<T>::nth_element (T *data, octave_idx_type nel, 1924 octave_sort<T>::nth_element (T *data, octave_idx_type nel,
1925 octave_idx_type lo, octave_idx_type up) 1925 octave_idx_type lo, octave_idx_type up)
1926 { 1926 {
1927 if (up < 0) 1927 if (up < 0)
1928 up = lo + 1; 1928 up = lo + 1;
1929 #ifdef INLINE_ASCENDING_SORT 1929 #ifdef INLINE_ASCENDING_SORT
1930 if (compare == ascending_compare) 1930 if (compare == ascending_compare)
1931 nth_element (data, nel, lo, up, std::less<T> ()); 1931 nth_element (data, nel, lo, up, std::less<T> ());
1932 else 1932 else
1933 #endif 1933 #endif
1934 #ifdef INLINE_DESCENDING_SORT 1934 #ifdef INLINE_DESCENDING_SORT
1935 if (compare == descending_compare) 1935 if (compare == descending_compare)
1936 nth_element (data, nel, lo, up, std::greater<T> ()); 1936 nth_element (data, nel, lo, up, std::greater<T> ());
1937 else 1937 else
1938 #endif 1938 #endif
1939 if (compare) 1939 if (compare)
1940 nth_element (data, nel, lo, up, std::ptr_fun (compare)); 1940 nth_element (data, nel, lo, up, std::ptr_fun (compare));
1941 } 1941 }
1942 1942
1943 template <class T> 1943 template <class T>
1944 bool 1944 bool
1945 octave_sort<T>::ascending_compare (typename ref_param<T>::type x, 1945 octave_sort<T>::ascending_compare (typename ref_param<T>::type x,
1946 typename ref_param<T>::type y) 1946 typename ref_param<T>::type y)
1947 { 1947 {
1948 return x < y; 1948 return x < y;
1949 } 1949 }
1950 1950
1951 template <class T> 1951 template <class T>
1952 bool 1952 bool
1953 octave_sort<T>::descending_compare (typename ref_param<T>::type x, 1953 octave_sort<T>::descending_compare (typename ref_param<T>::type x,
1954 typename ref_param<T>::type y) 1954 typename ref_param<T>::type y)
1955 { 1955 {
1956 return x > y; 1956 return x > y;
1957 } 1957 }