4#include "numeric_array.h"
5#include "acme/prototype/comparison/less.h"
12 template<
typename A,
typename B>
13 constexpr bool sort(A & a, B & b)
30 static iptr NumericCompare(
const TYPE * pointA,
const TYPE * pointB);
46 static iptr CompareTkPosition(
const A a1,
const A a2);
49 iptr NumericCompare(
const TYPE * p1,
const TYPE * p2)
61 static iptr CompareTkPosition(
const A a1,
const A a2)
63 if (a1.m_tkPosition > a2.m_tkPosition)
65 else if (a1.m_tkPosition > a2.m_tkPosition)
102 iptr CompareAscending(
109 template<
class TYPE,
class ARG_TYPE,
class FIRST>
110 void quick_sort(array<TYPE, ARG_TYPE> & a)
113 index_array stackLowerBound;
114 index_array stackUpperBound;
117 iptr iLPos, iUPos, iMPos;
120 if (a.get_size() >= 2)
122 stackLowerBound.push(0);
123 stackUpperBound.push(a.get_size() - 1);
126 iLowerBound = stackLowerBound.pop();
127 iUpperBound = stackUpperBound.pop();
137 if (FIRST::Compare(&a.element_at(iMPos), &a.element_at(iUPos)) <= 0)
141 t = a.element_at(iMPos);
142 a.element_at(iMPos) = a.element_at(iUPos);
143 a.element_at(iUPos) = t;
154 if (FIRST::Compare(&a.element_at(iLPos), &a.element_at(iMPos)) <= 0)
158 t = a.element_at(iMPos);
159 a.element_at(iMPos) = a.element_at(iLPos);
160 a.element_at(iLPos) = t;
168 if (iLowerBound < iMPos - 1)
170 stackLowerBound.push(iLowerBound);
171 stackUpperBound.push(iMPos - 1);
173 if (iMPos + 1 < iUpperBound)
175 stackLowerBound.push(iMPos + 1);
176 stackUpperBound.push(iUpperBound);
178 if (stackLowerBound.get_size() == 0)
186 template<
class TYPE,
class ARG_TYPE,
typename SWAP>
188 array<TYPE, ARG_TYPE> & a,
191 index_array stackLowerBound;
192 index_array stackUpperBound;
195 iptr iLPos, iUPos, iMPos;
197 if (a.get_size() >= 2)
199 stackLowerBound.push(0);
200 stackUpperBound.push(a.get_size() - 1);
203 iLowerBound = stackLowerBound.pop();
204 iUpperBound = stackUpperBound.pop();
214 if (a.get_at(iMPos) <= a.get_at(iUPos))
218 a.__swap(iMPos, iUPos);
219 __swap(iUPos, iMPos);
230 if (a.get_at(iLPos) <= a.get_at(iMPos))
234 a.__swap(iMPos, iLPos);
235 __swap(iLPos, iMPos);
243 if (iLowerBound < iMPos - 1)
245 stackLowerBound.push(iLowerBound);
246 stackUpperBound.push(iMPos - 1);
248 if (iMPos + 1 < iUpperBound)
250 stackLowerBound.push(iMPos + 1);
251 stackUpperBound.push(iUpperBound);
253 if (stackLowerBound.get_size() == 0)
261 template<
class TYPE,
class ARG_TYPE>
263 array<TYPE, ARG_TYPE> & a,
264 ::std::strong_ordering fCompare(
const ARG_TYPE,
const ARG_TYPE),
265 void __swap(
void * pVoidSwapArg, iptr iA, iptr iB),
269 index_array stackLowerBound;
270 index_array stackUpperBound;
273 iptr iLPos, iUPos, iMPos;
275 if (a.get_size() >= 2)
277 stackLowerBound.push(0);
278 stackUpperBound.push(a.get_size() - 1);
281 iLowerBound = stackLowerBound.pop();
282 iUpperBound = stackUpperBound.pop();
292 if (fCompare(a.get_at(iMPos), a.get_at(iUPos)) <= 0)
296 a.__swap(iMPos, iUPos);
297 __swap(pVoidSwapArg, iUPos, iMPos);
309 if (fCompare(a.get_at(iLPos), a.get_at(iMPos)) <= 0)
313 a.__swap(iMPos, iLPos);
314 __swap(pVoidSwapArg, iLPos, iMPos);
323 if (iLowerBound < iMPos - 1)
325 stackLowerBound.push(iLowerBound);
326 stackUpperBound.push(iMPos - 1);
328 if (iMPos + 1 < iUpperBound)
330 stackLowerBound.push(iMPos + 1);
331 stackUpperBound.push(iUpperBound);
333 if (stackLowerBound.get_size() == 0)
341 template<
class iterator,
class COMPARE = ::comparison::less<
typename iterator::BASE_TYPE,
typename iterator::BASE_ARG_TYPE> >
342 void quick_sort(
const iterator & a,
const iterator & b);
426 template<
typename PRED_LE,
typename ARRAY>
427 void predicate_array_quick_sort(ARRAY & a, PRED_LE predicate_le)
429 index_array stackLowerBound;
430 index_array stackUpperBound;
433 iptr iLPos, iUPos, iMPos;
435 if (a.get_size() >= 2)
437 stackLowerBound.push(0);
438 stackUpperBound.push(a.get_size() - 1);
441 iLowerBound = stackLowerBound.pop();
442 iUpperBound = stackUpperBound.pop();
452 if (predicate_le(a.element_at(iMPos), a.element_at(iUPos)))
459 a.__swap(iMPos, iUPos);
470 if (predicate_le(a.element_at(iLPos), a.element_at(iMPos)))
477 a.__swap(iLPos, iMPos);
485 if (iLowerBound < iMPos - 1)
487 stackLowerBound.push(iLowerBound);
488 stackUpperBound.push(iMPos - 1);
490 if (iMPos + 1 < iUpperBound)
492 stackLowerBound.push(iMPos + 1);
493 stackUpperBound.push(iUpperBound);
496 if (stackLowerBound.get_size() == 0)
506 template<
class TYPE,
class ARG_TYPE,
class ARRAY_TYPE>
507 void QuickSortAsc(comparable_array<TYPE, ARG_TYPE, ARRAY_TYPE> & a)
509 index_array stackLowerBound;
510 index_array stackUpperBound;
513 iptr iLPos, iUPos, iMPos;
515 if (a.get_size() >= 2)
517 stackLowerBound.push(0);
518 stackUpperBound.push(a.get_upper_bound());
521 iLowerBound = stackLowerBound.pop();
522 iUpperBound = stackUpperBound.pop();
532 if (a.element_at(iMPos) <= a.element_at(iUPos))
536 a.__swap(iMPos, iUPos);
547 if (a.element_at(iLPos) <= a.element_at(iMPos))
551 a.__swap(iLPos, iMPos);
559 if (iLowerBound < iMPos - 1)
561 stackLowerBound.push(iLowerBound);
562 stackUpperBound.push(iMPos - 1);
564 if (iMPos + 1 < iUpperBound)
566 stackLowerBound.push(iMPos + 1);
567 stackUpperBound.push(iUpperBound);
569 if (stackLowerBound.get_size() == 0)
575 template<
class TYPE,
class ARG_TYPE,
class ARRAY_TYPE>
576 void QuickSortDesc(comparable_array<TYPE, ARG_TYPE, ARRAY_TYPE> & a)
578 index_array stackLowerBound;
579 index_array stackUpperBound;
582 iptr iLPos, iUPos, iMPos;
584 if (a.get_size() >= 2)
586 stackLowerBound.push(0);
587 stackUpperBound.push(a.get_upper_bound());
590 iLowerBound = stackLowerBound.pop();
591 iUpperBound = stackUpperBound.pop();
601 if (a.element_at(iUPos) <= a.element_at(iMPos))
605 a.__swap(iMPos, iUPos);
616 if (a.element_at(iMPos) <= a.element_at(iLPos))
620 a.__swap(iLPos, iMPos);
628 if (iLowerBound < iMPos - 1)
630 stackLowerBound.push(iLowerBound);
631 stackUpperBound.push(iMPos - 1);
633 if (iMPos + 1 < iUpperBound)
635 stackLowerBound.push(iMPos + 1);
636 stackUpperBound.push(iUpperBound);
638 if (stackLowerBound.get_size() == 0)
645 template<prototype_range RANGE>
646 void QuickSortAsc(RANGE & range)
649 if (range.size() < 2)
656 ::array < typename RANGE::iterator > stackLowerBound;
657 ::array < typename RANGE::iterator > stackUpperBound;
658 typename RANGE::iterator iLowerBound;
659 typename RANGE::iterator iUpperBound;
660 typename RANGE::iterator iLPos, iUPos, iMPos;
662 stackLowerBound.push(range.begin());
663 stackUpperBound.push(range.back());
666 iLowerBound = stackLowerBound.pop();
667 iUpperBound = stackUpperBound.pop();
677 if (*iMPos <= *iUPos)
681 ::swap(*iMPos, *iUPos);
692 if (*iLPos <= *iMPos)
696 ::swap(*iLPos, *iMPos);
704 if (iLowerBound < iMPos - 1)
706 stackLowerBound.push(iLowerBound);
707 stackUpperBound.push(iMPos - 1);
709 if (iMPos + 1 < iUpperBound)
711 stackLowerBound.push(iMPos + 1);
712 stackUpperBound.push(iUpperBound);
714 if (stackLowerBound.get_size() == 0)
721 template<prototype_range RANGE>
722 void QuickSortDesc(RANGE & range)
725 if (range.size() < 2)
732 ::array < typename RANGE::iterator > stackLowerBound;
733 ::array < typename RANGE::iterator > stackUpperBound;
734 typename RANGE::iterator iLowerBound;
735 typename RANGE::iterator iUpperBound;
736 typename RANGE::iterator iLPos, iUPos, iMPos;
738 stackLowerBound.push(range.begin());
739 stackUpperBound.push(range.end());
742 iLowerBound = stackLowerBound.pop();
743 iUpperBound = stackUpperBound.pop();
753 if (*iUPos <= *iMPos)
757 ::swap(*iMPos, *iUPos);
768 if (*iMPos <= *iLPos)
772 ::swap(*iLPos, *iMPos);
780 if (iLowerBound < iMPos - 1)
782 stackLowerBound.push(iLowerBound);
783 stackUpperBound.push(iMPos - 1);
785 if (iMPos + 1 < iUpperBound)
787 stackLowerBound.push(iMPos + 1);
788 stackUpperBound.push(iUpperBound);
790 if (stackLowerBound.get_size() == 0)
797 template<
class KEY,
class TYPE,
class ARG_TYPE>
799 array<TYPE, ARG_TYPE> & a,
800 KEY(TYPE:: * fKey)())
802 index_array stackLowerBound;
803 index_array stackUpperBound;
806 iptr iLPos, iUPos, iMPos;
809 if (a.get_size() >= 2)
811 stackLowerBound.push(0);
812 stackUpperBound.push(a.get_size() - 1);
815 iLowerBound = stackLowerBound.pop();
816 iUpperBound = stackUpperBound.pop();
826 if ((a.element_at(iMPos).*fKey)() < (a.element_at(iUPos).*fKey)())
833 a.__swap(iMPos, iUPos);
844 if ((a.element_at(iLPos).*fKey)() < (a.element_at(iMPos).*fKey)())
851 a.__swap(iLPos, iMPos);
859 if (iLowerBound < iMPos - 1)
861 stackLowerBound.push(iLowerBound);
862 stackUpperBound.push(iMPos - 1);
864 if (iMPos + 1 < iUpperBound)
866 stackLowerBound.push(iMPos + 1);
867 stackUpperBound.push(iUpperBound);
869 if (stackLowerBound.get_size() == 0)
875 template<
class ARG_TYPE>
876 inline iptr SortCompare(ARG_TYPE t1, ARG_TYPE t2)
882 template<
class TYPE,
class ARG_TYPE>
883 bool SortFind(array<TYPE, ARG_TYPE> & a, ARG_TYPE t, iptr & iIndex, iptr iStart, iptr iEnd)
885 if (a.get_size() == 0)
889 iptr iLowerBound = iStart;
890 iptr iMaxBound = iEnd;
891 iptr iUpperBound = iMaxBound;
896 iIndex = (iUpperBound + iLowerBound) / 2;
897 iCompare = SortCompare((ARG_TYPE)a.element_at(iIndex), (ARG_TYPE)t);
902 else if (iCompare > 0)
904 iUpperBound = iIndex - 1;
910 iLowerBound = iIndex + 1;
911 if (iLowerBound > iMaxBound)
913 iIndex = iLowerBound;
917 if (iUpperBound < iLowerBound)
925 template<
class TYPE,
class ARG_TYPE>
926 bool SortFind(array<TYPE, ARG_TYPE> & a, ARG_TYPE t, iptr & iIndex)
928 return SortFind(a, t, iIndex, 0, a.get_size() - 1);
931 template<
class TYPE,
class ARG_TYPE>
932 void BubbleSortByLPGetSize(array<TYPE, ARG_TYPE> & a,
bool bAsc =
true);
937 template<
typename TYPE>
938 void BubbleSortByPtrAtGetSize(
939 pointer_array<TYPE> & a,
942 template<
class TYPE,
class ARG_TYPE = const TYPE &,
class DEFCONSTRUCTOR>
944 array<TYPE, ARG_TYPE, DEFCONSTRUCTOR> & a,
945 ::std::strong_ordering(*pfnCompare)(ARG_TYPE, ARG_TYPE));
948 template<
class TYPE,
class ARG_TYPE>
949 void BubbleSortByLPGetSize(
950 array<TYPE, ARG_TYPE> & a,
956 for (iptr i = 0; i < a.get_size(); i++)
957 for (iptr j = i + 1; j < a.get_size(); j++)
959 if (a.element_at(i)->get_size() > a.element_at(j)->get_size())
962 set_at(i, a.element_at(j));
970 for (iptr i = 0; i < a.get_size(); i++)
971 for (iptr j = i + 1; j < a.get_size(); j++)
973 if (a.element_at(i)->get_size() < a.element_at(j)->get_size())
976 set_at(i, a.element_at(j));
987 template<prototype_array ARRAY>
988 void BubbleSortByGetSize(ARRAY & a,
bool bAsc)
994 for (iptr i = 0; i < a.get_size(); i++)
997 for (iptr j = i + 1; j < a.get_size(); j++)
1000 if (a[i].get_size() > a[j].get_size())
1015 for (iptr i = 0; i < a.get_size(); i++)
1018 for (iptr j = i + 1; j < a.get_size(); j++)
1021 if (a[i].get_size() < a[j].get_size())
1070 template<
typename TYPE>
1071 void BubbleSortByPtrAtGetSize(
1072 pointer_array<TYPE> & a,
1078 for (iptr i = 0; i < a.get_size(); i++)
1079 for (iptr j = i + 1; j < a.get_size(); j++)
1081 if (a.element_at(i)->get_size() > a.element_at(j)->get_size())
1089 for (iptr i = 0; i < a.get_size(); i++)
1090 for (iptr j = i + 1; j < a.get_size(); j++)
1092 if (a.element_at(i)->get_size() < a.element_at(j)->get_size())
1108 template <
typename ARRAY_TYPE >
1111 ::std::strong_ordering(*pfnCompare)(
typename ARRAY_TYPE::BASE_ARG_TYPE,
typename ARRAY_TYPE::BASE_ARG_TYPE))
1114 index_array stackLowerBound;
1116 index_array stackUpperBound;
1122 iptr iLPos, iUPos, iMPos;
1124 if (a.get_size() >= 2)
1127 stackLowerBound.push(0);
1129 stackUpperBound.push(a.get_upper_bound());
1134 iLowerBound = stackLowerBound.pop();
1136 iUpperBound = stackUpperBound.pop();
1138 iLPos = iLowerBound;
1140 iMPos = iLowerBound;
1142 iUPos = iUpperBound;
1157 if (pfnCompare((
typename ARRAY_TYPE::BASE_ARG_TYPE)a.element_at(iMPos), (
typename ARRAY_TYPE::BASE_ARG_TYPE)a.element_at(iUPos)) <= 0)
1166 a.__swap(iMPos, iUPos);
1193 if (pfnCompare((
typename ARRAY_TYPE::BASE_ARG_TYPE)a.element_at(iLPos), (
typename ARRAY_TYPE::BASE_ARG_TYPE)a.element_at(iMPos)) <= 0)
1202 a.__swap(iLPos, iMPos);
1221 if (iLowerBound < iMPos - 1)
1224 stackLowerBound.push(iLowerBound);
1226 stackUpperBound.push(iMPos - 1);
1230 if (iMPos + 1 < iUpperBound)
1233 stackLowerBound.push(iMPos + 1);
1235 stackUpperBound.push(iUpperBound);
1239 if (stackLowerBound.get_size() == 0)
1253 template <
typename ARRAY_TYPE >
1254 void quick_sort(ARRAY_TYPE & a, less_predicate_base < typename ARRAY_TYPE::BASE_ARG_TYPE > * pless, index_array & ia)
1257 if (ia.get_size() != a.get_size())
1260 throw_exception(error_bad_argument);
1264 index_array stackLowerBound;
1266 index_array stackUpperBound;
1272 iptr iLPos, iUPos, iMPos;
1274 if (a.get_size() >= 2)
1277 stackLowerBound.push(0);
1279 stackUpperBound.push(a.get_upper_bound());
1284 iLowerBound = stackLowerBound.pop();
1286 iUpperBound = stackUpperBound.pop();
1288 iLPos = iLowerBound;
1290 iMPos = iLowerBound;
1292 iUPos = iUpperBound;
1307 if (pless->less(a.element_at(ia[iMPos]), a.element_at(ia[iUPos])) <= 0)
1316 ia.__swap(iMPos, iUPos);
1343 if (pless->less(a.element_at(ia[iLPos]), a.element_at(ia[iMPos])) <= 0)
1352 ia.__swap(iLPos, iMPos);
1371 if (iLowerBound < iMPos - 1)
1374 stackLowerBound.push(iLowerBound);
1376 stackUpperBound.push(iMPos - 1);
1380 if (iMPos + 1 < iUpperBound)
1383 stackLowerBound.push(iMPos + 1);
1385 stackUpperBound.push(iUpperBound);
1389 if (stackLowerBound.is_empty())
1414 template <
typename LIST,
typename PRED>
1415 void predicate_quick_sort_list(LIST & list_base, PRED pred)
1418 if (list_base.get_size() < 2)
1425 typedef typename LIST::node node;
1427 ::raw_array_base < node * > stackLowerBound;
1429 ::raw_array_base < node * > stackUpperBound;
1434 node * iLPos, * iUPos, * iMPos;
1436 stackLowerBound.push(list_base.m_phead);
1437 stackUpperBound.push(list_base.m_ptail);
1440 iLowerBound = stackLowerBound.pop();
1441 iUpperBound = stackUpperBound.pop();
1442 iLPos = iLowerBound;
1443 iMPos = iLowerBound;
1444 iUPos = iUpperBound;
1450 goto break_mid_loop;
1451 if (pred(iUPos->m_value, iMPos->m_value))
1453 list_base.__swap(iMPos, iUPos);
1456 iUPos = iUPos->m_pprevious;
1462 goto break_mid_loop;
1463 if (pred(iMPos->m_value, iLPos->m_value))
1465 list_base.__swap(iLPos, iMPos);
1468 iLPos = iLPos->m_pnext;
1473 if (iLowerBound != iMPos->m_pprevious)
1475 stackLowerBound.push(iLowerBound);
1476 stackUpperBound.push(iMPos->m_pprevious);
1478 if (iMPos->m_pnext != iUpperBound)
1480 stackLowerBound.push(iMPos->m_pnext);
1481 stackUpperBound.push(iUpperBound);
1483 if (stackLowerBound.get_size() == 0)
1490 template <
typename LIST,
typename PRED >
1491 void predicate_quick_sort_list_descending(LIST & list_base, PRED pred)
1494 predicate_quick_sort_list(list_base, [&](
auto & a,
auto & b) {
return pred(b, a); });
1499 template <
typename LIST >
1500 void quick_sort_list(LIST & list_base,
bool bAscendent =
true)
1506 predicate_quick_sort_list(list_base, [](
auto & a,
auto & b) {
return a < b; });
1512 predicate_quick_sort_list(list_base, [](
auto & a,
auto & b) {
return b < a; });
1519 template <
class ARRAY >
1520 inline bool sort_find(ARRAY & a,
typename ARRAY::BASE_ARG_TYPE arg, iptr & iIndex, iptr iStart, iptr iEnd)
1522 if (a.get_size() == 0)
1526 iptr iLowerBound = iStart;
1527 iptr iMaxBound = iEnd;
1528 iptr iUpperBound = iMaxBound;
1531 iIndex = (iUpperBound + iLowerBound) / 2;
1532 while (iUpperBound - iLowerBound >= 8)
1534 iCompare = CompareElements(a.element_at(iIndex), arg);
1539 else if (iCompare > 0)
1541 iUpperBound = iIndex - 1;
1542 if (iUpperBound < 0)
1550 iLowerBound = iIndex + 1;
1551 if (iLowerBound > iMaxBound)
1553 iIndex = iMaxBound + 1;
1557 iIndex = (iUpperBound + iLowerBound) / 2;
1560 while (iIndex < a.get_count())
1562 iCompare = CompareElements(a.element_at(iIndex), arg);
1565 else if (iCompare < 0)
1570 if (iIndex >= a.get_count())
1574 iCompare = CompareElements(a.element_at(iIndex), arg);
1577 else if (iCompare > 0)
1587 template <
class ARRAY >
1588 void quick_sort(ARRAY & a,
bool bAsc)
1592 sort::QuickSortAsc(a);
1596 sort::QuickSortDesc(a);
1601 template <
typename ITERATOR>
1602 void quick_sort_iter(ITERATOR first, ITERATOR last)
1616 if (last - first < 2)
1623 ::array < ITERATOR > stackLowerBound;
1624 ::array < ITERATOR > stackUpperBound;
1625 ITERATOR iLowerBound;
1626 ITERATOR iUpperBound;
1627 ITERATOR iLPos, iUPos, iMPos;
1629 stackLowerBound.push(first);
1630 stackUpperBound.push(last);
1635 iLowerBound = stackLowerBound.pop();
1636 iUpperBound = stackUpperBound.pop();
1638 iLPos = iLowerBound;
1639 iMPos = iLowerBound;
1640 iUPos = iUpperBound;
1647 goto break_mid_loop;
1648 __sort(*iMPos, *iUPos);
1658 goto break_mid_loop;
1659 __sort(*iLPos, *iMPos);
1667 if (iLowerBound < iMPos - 1)
1669 stackLowerBound.push(iLowerBound);
1670 stackUpperBound.push(iMPos - 1);
1672 if (iMPos + 1 < iUpperBound)
1674 stackLowerBound.push(iMPos + 1);
1675 stackUpperBound.push(iUpperBound);
1677 if (stackLowerBound.get_size() == 0)
1686 template <
typename ARRAY,
typename PRED >
1687 void predicate_index_merge(ARRAY & a, PRED leq, index_array & temp, index_array & perm, ::i32 lo, ::i32 mid, ::i32 hi)
1690 ::i32 i = lo, j = mid + 1;
1692 for (::i32 k = lo; k <= hi; k++)
1699 for (::i32 k = lo; k <= hi; k++)
1705 perm[k] = temp[j++];
1711 perm[k] = temp[i++];
1714 else if (leq(a[temp[i]], a[temp[j]]))
1717 perm[k] = temp[i++];
1723 perm[k] = temp[j++];
1731 template <
typename ARRAY,
typename PRED >
1732 void predicate_index_merge_sort(ARRAY & a, PRED leq, index_array & temp, index_array & perm, ::i32 lo, ::i32 hi)
1738 ::i32 mid = (hi + lo) / 2;
1740 predicate_merge_sort(a, leq, temp, perm, lo, mid);
1742 predicate_merge_sort(a, leq, temp, perm, mid + 1, hi);
1744 predicate_merge(a, leq, temp, perm, lo, mid, hi);
1748 template <
typename ARRAY,
typename PRED >
1749 void predicate_stable_index_sort(ARRAY & a, index_array & perm, PRED leq)
1754 temp.set_size(a.get_size());
1756 predicate_index_merge_sort(a, leq, temp, perm, 0, a.get_upper_bound());
1765 template <
typename ARRAY,
typename PRED >
1766 void predicate_merge(ARRAY & a, PRED leq, ::i32 l, ::i32 m, ::i32 r)
1770 ::i32 n1 = m - l + 1;
1780 for (i = 0; i < n1; i++)
1782 for (j = 0; j < n2; j++)
1783 R[j] = a[m + 1 + j];
1789 while (i < n1 && j < n2)
1791 if (leq(L[i], R[j]))
1825 template <
typename ARRAY,
typename PRED >
1826 void predicate_merge_sort(ARRAY & a, PRED leq, ::i32 l, ::i32 r)
1834 ::i32 m = l + (r - l) / 2;
1838 predicate_merge_sort(a, leq, l, m);
1840 predicate_merge_sort(a, leq, m + 1, r);
1842 predicate_merge(a, leq, l, m, r);
1848 template <
typename ARRAY,
typename PRED >
1849 void predicate_stable_sort(ARRAY & a, PRED leq)
1852 predicate_merge_sort(a, leq, 0, a.get_upper_bound());