110 #include <functional>
121 compare (ascending_compare), ms (0)
127 : compare (comp), ms (0)
142 compare = ascending_compare;
144 compare = descending_compare;
150 template <
class Comp>
158 for (; start < nel; ++start)
163 T pivot = data[start];
172 if (comp (pivot, data[p]))
187 std::swap (pivot, data[p]);
195 template <
class Comp>
203 for (; start < nel; ++start)
208 T pivot = data[start];
217 if (comp (pivot, data[p]))
232 std::swap (pivot, data[p]);
236 std::swap (ipivot, idx[p]);
262 template <
class Comp>
277 if (comp (*lo, *(lo-1)))
280 for (lo = lo+1; lo < hi; ++lo, ++n)
282 if (comp (*lo, *(lo-1)))
290 for (lo = lo+1; lo < hi; ++lo, ++n)
292 if (comp (*lo, *(lo-1)))
322 template <
class Comp>
343 if (comp (a[ofs], key))
346 ofs = (ofs << 1) + 1;
367 if (comp (*(a-ofs), key))
371 ofs = (ofs << 1) + 1;
379 lastofs = hint - ofs;
389 while (lastofs < ofs)
393 if (comp (a[m], key))
417 template <
class Comp>
438 if (comp (key, *(a-ofs)))
441 ofs = (ofs << 1) + 1;
452 lastofs = hint - ofs;
463 if (comp (key, a[ofs]))
467 ofs = (ofs << 1) + 1;
484 while (lastofs < ofs)
488 if (comp (key, a[m]))
500 unsigned int nbits = 3;
531 return ((n >> nbits) + 1) << nbits;
559 if (ia && need <= alloced)
581 template <
class Comp>
594 std::copy (pa, pa + na,
ms->
a);
627 if (bcount >= min_gallop)
638 if (acount >= min_gallop)
651 min_gallop -= min_gallop > 1;
659 dest = std::copy (pa, pa + k, dest);
682 dest = std::copy (pb, pb + k, dest);
704 std::copy (pa, pa + na, dest);
709 std::copy (pb, pb + nb, dest);
716 template <
class Comp>
730 std::copy (pa, pa + na,
ms->
a);
731 std::copy (ipa, ipa + na,
ms->
ia);
732 dest = pa; idest = ipa;
735 *dest++ = *pb++; *idest++ = *ipb++;
755 *dest++ = *pb++; *idest++ = *ipb++;
761 if (bcount >= min_gallop)
766 *dest++ = *pa++; *idest++ = *ipa++;
772 if (acount >= min_gallop)
785 min_gallop -= min_gallop > 1;
793 dest = std::copy (pa, pa + k, dest);
794 idest = std::copy (ipa, ipa + k, idest);
806 *dest++ = *pb++; *idest++ = *ipb++;
817 dest = std::copy (pb, pb + k, dest);
818 idest = std::copy (ipb, ipb + k, idest);
824 *dest++ = *pa++; *idest++ = *ipa++;
841 std::copy (pa, pa + na, dest);
842 std::copy (ipa, ipa + na, idest);
848 std::copy (pb, pb + nb, dest);
849 std::copy (ipb, ipb + nb, idest);
863 template <
class Comp>
878 std::copy (pb, pb + nb,
ms->
a);
909 if (acount >= min_gallop)
920 if (bcount >= min_gallop)
933 min_gallop -= min_gallop > 1;
942 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1;
962 std::copy (pb+1, pb+1 + k, dest+1);
987 std::copy (baseb, baseb + nb, dest-(nb-1));
992 dest = std::copy_backward (pa+1 - na, pa+1, dest+1) - 1;
1000 template <
class Comp>
1017 idest = ipb + nb - 1;
1018 std::copy (pb, pb + nb,
ms->
a);
1019 std::copy (ipb, ipb + nb,
ms->
ia);
1021 baseb =
ms->
a; ibaseb =
ms->
ia;
1022 pb =
ms->
a + nb - 1; ipb =
ms->
ia + nb - 1;
1023 pa += na - 1; ipa += na - 1;
1025 *dest-- = *pa--; *idest-- = *ipa--;
1042 if (comp (*pb, *pa))
1044 *dest-- = *pa--; *idest-- = *ipa--;
1050 if (acount >= min_gallop)
1055 *dest-- = *pb--; *idest-- = *ipb--;
1061 if (bcount >= min_gallop)
1074 min_gallop -= min_gallop > 1;
1083 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1;
1084 idest = std::copy_backward (ipa+1 - k, ipa+1, idest+1) - 1;
1090 *dest-- = *pb--; *idest-- = *ipb--;
1102 dest -= k; idest -= k;
1104 std::copy (pb+1, pb+1 + k, dest+1);
1105 std::copy (ipb+1, ipb+1 + k, idest+1);
1116 *dest-- = *pa--; *idest-- = *ipa--;
1131 std::copy (baseb, baseb + nb, dest-(nb-1));
1132 std::copy (ibaseb, ibaseb + nb, idest-(nb-1));
1138 dest = std::copy_backward (pa+1 - na, pa+1, dest+1) - 1;
1139 idest = std::copy_backward (ipa+1 - na, ipa+1, idest+1) - 1;
1140 pa -= na; ipa -= na;
1141 *dest = *pb; *idest = *ipb;
1150 template <
class Comp>
1195 return merge_lo (pa, na, pb, nb, comp);
1197 return merge_hi (pa, na, pb, nb, comp);
1201 template <
class Comp>
1249 return merge_lo (pa, ipa, na, pb, ipb, nb, comp);
1251 return merge_hi (pa, ipa, na, pb, ipb, nb, comp);
1265 template <
class Comp>
1274 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len)
1276 if (p[n-1].len < p[n+1].len)
1281 else if (p[n].len <= p[n+1].len)
1294 template <
class Comp>
1303 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len)
1305 if (p[n-1].len < p[n+1].len)
1307 if (
merge_at (n, data, idx, comp) < 0)
1310 else if (p[n].len <= p[n+1].len)
1312 if (
merge_at (n, data, idx, comp) < 0)
1328 template <
class Comp>
1337 if (n > 0 && p[n-1].len < p[n+1].len)
1347 template <
class Comp>
1356 if (n > 0 && p[n-1].len < p[n+1].len)
1358 if (
merge_at (n, data, idx, comp) < 0)
1391 template <
class Comp>
1416 n =
count_run (data + lo, nremaining, descending, comp);
1420 std::reverse (data + lo, data + lo + n);
1450 template <
class Comp>
1476 n =
count_run (data + lo, nremaining, descending, comp);
1481 std::reverse (data + lo, data + lo + n);
1482 std::reverse (idx + lo, idx + lo + n);
1489 binarysort (data + lo, idx + lo, force, n, comp);
1516 #ifdef INLINE_ASCENDING_SORT
1518 sort (data, nel, std::less<T> ());
1521 #ifdef INLINE_DESCENDING_SORT
1523 sort (data, nel, std::greater<T> ());
1534 #ifdef INLINE_ASCENDING_SORT
1536 sort (data, idx, nel, std::less<T> ());
1539 #ifdef INLINE_DESCENDING_SORT
1541 sort (data, idx, nel, std::greater<T> ());
1548 template <
class T>
template <
class Comp>
1552 const T *end = data + nel;
1555 const T *
next = data;
1556 while (++next != end)
1558 if (comp (*next, *data))
1572 bool retval =
false;
1573 #ifdef INLINE_ASCENDING_SORT
1575 retval =
is_sorted (data, nel, std::less<T> ());
1578 #ifdef INLINE_DESCENDING_SORT
1580 retval =
is_sorted (data, nel, std::greater<T> ());
1593 : col (c), ofs (o), nel (n) { }
1598 template <
class T>
template <
class Comp>
1608 if (cols == 0 || rows <= 1)
1614 std::stack<run_t> runs;
1616 runs.push (run_t (0, 0, rows));
1618 while (! runs.empty ())
1626 T *lbuf = buf + ofs;
1627 const T *ldata = data + rows*col;
1632 lbuf[i] = ldata[lidx[i]];
1635 sort (lbuf, lidx, nel, comp);
1643 if (comp (lbuf[lst], lbuf[i]))
1646 runs.push (run_t (col+1, ofs + lst, i - lst));
1651 runs.push (run_t (col+1, ofs + lst, nel - lst));
1661 #ifdef INLINE_ASCENDING_SORT
1663 sort_rows (data, idx, rows, cols, std::less<T> ());
1666 #ifdef INLINE_DESCENDING_SORT
1668 sort_rows (data, idx, rows, cols, std::greater<T> ());
1675 template <
class T>
template <
class Comp>
1680 if (rows <= 1 || cols == 0)
1684 const T *lastrow = data + rows*(cols - 1);
1685 typedef std::pair<const T *, octave_idx_type> run_t;
1686 std::stack<run_t> runs;
1689 runs.push (run_t (data, rows));
1690 while (sorted && ! runs.empty ())
1692 const T *lo = runs.top ().first;
1699 const T *hi = lo + n;
1701 for (lo++; lo < hi; lo++)
1703 if (comp (*lst, *lo))
1706 runs.push (run_t (lst + rows, lo - lst));
1709 else if (comp (*lo, *lst))
1716 runs.push (run_t (lst + rows, lo - lst));
1737 bool retval =
false;
1739 #ifdef INLINE_ASCENDING_SORT
1744 #ifdef INLINE_DESCENDING_SORT
1757 template <
class T>
template <
class Comp>
1760 const T& value, Comp comp)
1768 if (comp (value, data[mid]))
1784 #ifdef INLINE_ASCENDING_SORT
1786 retval =
lookup (data, nel, value, std::less<T> ());
1789 #ifdef INLINE_DESCENDING_SORT
1791 retval =
lookup (data, nel, value, std::greater<T> ());
1800 template <
class T>
template <
class Comp>
1810 idx[j] =
lookup (data, nel, values[j], comp);
1819 #ifdef INLINE_ASCENDING_SORT
1821 lookup (data, nel, values, nvalues, idx, std::less<T> ());
1824 #ifdef INLINE_DESCENDING_SORT
1826 lookup (data, nel, values, nvalues, idx, std::greater<T> ());
1830 lookup (data, nel, values, nvalues, idx, std::ptr_fun (
compare));
1833 template <
class T>
template <
class Comp>
1844 if (nvalues > 0 && nel > 0)
1848 if (comp (values[j], data[i]))
1854 else if (++i == nel)
1867 if (nvalues > 0 && nel > 0)
1871 if (comp (values[j], data[i]))
1877 else if (++i == nel)
1882 for (; j != nvalues; j++)
1893 #ifdef INLINE_ASCENDING_SORT
1895 lookup_sorted (data, nel, values, nvalues, idx, rev, std::less<T> ());
1898 #ifdef INLINE_DESCENDING_SORT
1900 lookup_sorted (data, nel, values, nvalues, idx, rev, std::greater<T> ());
1908 template <
class T>
template <
class Comp>
1917 std::nth_element (data, data + lo, data + nel, comp);
1919 std::partial_sort (data, data + up, data + nel, comp);
1922 std::nth_element (data, data + lo, data + nel, comp);
1926 std::swap (data[lo+1],
1927 *std::min_element (data + lo + 1, data + nel, comp));
1930 std::partial_sort (data + lo + 1, data + up, data + nel, comp);
1941 #ifdef INLINE_ASCENDING_SORT
1946 #ifdef INLINE_DESCENDING_SORT
1948 nth_element (data, nel, lo, up, std::greater<T> ());
int merge_at(octave_idx_type i, T *data, Comp comp)
void sort_rows(const T *data, octave_idx_type *idx, octave_idx_type rows, octave_idx_type cols)
octave_idx_type lookup(const T *data, octave_idx_type nel, const T &value)
octave_idx_type gallop_left(T key, T *a, octave_idx_type n, octave_idx_type hint, Comp comp)
void set_compare(compare_fcn_type comp)
sortrows_run_t(octave_idx_type c, octave_idx_type o, octave_idx_type n)
void binarysort(T *data, octave_idx_type nel, octave_idx_type start, Comp comp)
octave_idx_type count_run(T *lo, octave_idx_type n, bool &descending, Comp comp)
int merge_hi(T *pa, octave_idx_type na, T *pb, octave_idx_type nb, Comp comp)
void getmemi(octave_idx_type need)
static octave_idx_type roundupsize(octave_idx_type n)
static bool descending_compare(typename ref_param< T >::type, typename ref_param< T >::type)
#define MAX_MERGE_PENDING
bool is_sorted_rows(const T *data, octave_idx_type rows, octave_idx_type cols)
bool is_sorted(const T *data, octave_idx_type nel)
if_then_else< is_class_type< T >::no, T, T const & >::result type
octave_idx_type gallop_right(T key, T *a, octave_idx_type n, octave_idx_type hint, Comp comp)
void sort(T *data, octave_idx_type nel)
int merge_force_collapse(T *data, Comp comp)
void lookup_sorted(const T *data, octave_idx_type nel, const T *values, octave_idx_type nvalues, octave_idx_type *idx, bool rev=false)
void getmem(octave_idx_type need)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
struct s_slice pending[85]
void nth_element(T *data, octave_idx_type nel, octave_idx_type lo, octave_idx_type up=-1)
int merge_collapse(T *data, Comp comp)
octave_idx_type merge_compute_minrun(octave_idx_type n)
octave_idx_type min_gallop
F77_RET_T const double * x
static bool ascending_compare(typename ref_param< T >::type, typename ref_param< T >::type)
int merge_lo(T *pa, octave_idx_type na, T *pb, octave_idx_type nb, Comp comp)