Advertisement
mrlantan

Untitled

Oct 25th, 2020
2,431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.12 KB | None | 0 0
  1. void
  2. __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
  3. {
  4.     // _Compare is known to be a reference type
  5.     typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
  6.     typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
  7.     const difference_type __limit = is_trivially_copy_constructible<value_type>::value &&
  8.                                     is_trivially_copy_assignable<value_type>::value ? 30 : 6;
  9.     while (true)
  10.     {
  11.     __restart:
  12.         difference_type __len = __last - __first;
  13.         switch (__len)
  14.         {
  15.         case 0:
  16.         case 1:
  17.             return;
  18.         case 2:
  19.             if (__comp(*--__last, *__first))
  20.                 swap(*__first, *__last);
  21.             return;
  22.         case 3:
  23.             _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
  24.             return;
  25.         case 4:
  26.             _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
  27.             return;
  28.         case 5:
  29.             _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
  30.             return;
  31.         }
  32.         if (__len <= __limit)
  33.         {
  34.             _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp);
  35.             return;
  36.         }
  37.         // __len > 5
  38.         _RandomAccessIterator __m = __first;
  39.         _RandomAccessIterator __lm1 = __last;
  40.         --__lm1;
  41.         unsigned __n_swaps;
  42.         {
  43.         difference_type __delta;
  44.         if (__len >= 1000)
  45.         {
  46.             __delta = __len/2;
  47.             __m += __delta;
  48.             __delta /= 2;
  49.             __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp);
  50.         }
  51.         else
  52.         {
  53.             __delta = __len/2;
  54.             __m += __delta;
  55.             __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp);
  56.         }
  57.         }
  58.         // *__m is median
  59.         // partition [__first, __m) < *__m and *__m <= [__m, __last)
  60.         // (this inhibits tossing elements equivalent to __m around unnecessarily)
  61.         _RandomAccessIterator __i = __first;
  62.         _RandomAccessIterator __j = __lm1;
  63.         // j points beyond range to be tested, *__m is known to be <= *__lm1
  64.         // The search going up is known to be guarded but the search coming down isn't.
  65.         // Prime the downward search with a guard.
  66.         if (!__comp(*__i, *__m))  // if *__first == *__m
  67.         {
  68.             // *__first == *__m, *__first doesn't go in first part
  69.             // manually guard downward moving __j against __i
  70.             while (true)
  71.             {
  72.                 if (__i == --__j)
  73.                 {
  74.                     // *__first == *__m, *__m <= all other elements
  75.                     // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
  76.                     ++__i;  // __first + 1
  77.                     __j = __last;
  78.                     if (!__comp(*__first, *--__j))  // we need a guard if *__first == *(__last-1)
  79.                     {
  80.                         while (true)
  81.                         {
  82.                             if (__i == __j)
  83.                                 return;  // [__first, __last) all equivalent elements
  84.                             if (__comp(*__first, *__i))
  85.                             {
  86.                                 swap(*__i, *__j);
  87.                                 ++__n_swaps;
  88.                                 ++__i;
  89.                                 break;
  90.                             }
  91.                             ++__i;
  92.                         }
  93.                     }
  94.                     // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
  95.                     if (__i == __j)
  96.                         return;
  97.                     while (true)
  98.                     {
  99.                         while (!__comp(*__first, *__i))
  100.                             ++__i;
  101.                         while (__comp(*__first, *--__j))
  102.                             ;
  103.                         if (__i >= __j)
  104.                             break;
  105.                         swap(*__i, *__j);
  106.                         ++__n_swaps;
  107.                         ++__i;
  108.                     }
  109.                     // [__first, __i) == *__first and *__first < [__i, __last)
  110.                     // The first part is sorted, sort the secod part
  111.                     // _VSTD::__sort<_Compare>(__i, __last, __comp);
  112.                     __first = __i;
  113.                     goto __restart;
  114.                 }
  115.                 if (__comp(*__j, *__m))
  116.                 {
  117.                     swap(*__i, *__j);
  118.                     ++__n_swaps;
  119.                     break;  // found guard for downward moving __j, now use unguarded partition
  120.                 }
  121.             }
  122.         }
  123.         // It is known that *__i < *__m
  124.         ++__i;
  125.         // j points beyond range to be tested, *__m is known to be <= *__lm1
  126.         // if not yet partitioned...
  127.         if (__i < __j)
  128.         {
  129.             // known that *(__i - 1) < *__m
  130.             // known that __i <= __m
  131.             while (true)
  132.             {
  133.                 // __m still guards upward moving __i
  134.                 while (__comp(*__i, *__m))
  135.                     ++__i;
  136.                 // It is now known that a guard exists for downward moving __j
  137.                 while (!__comp(*--__j, *__m))
  138.                     ;
  139.                 if (__i > __j)
  140.                     break;
  141.                 swap(*__i, *__j);
  142.                 ++__n_swaps;
  143.                 // It is known that __m != __j
  144.                 // If __m just moved, follow it
  145.                 if (__m == __i)
  146.                     __m = __j;
  147.                 ++__i;
  148.             }
  149.         }
  150.         // [__first, __i) < *__m and *__m <= [__i, __last)
  151.         if (__i != __m && __comp(*__m, *__i))
  152.         {
  153.             swap(*__i, *__m);
  154.             ++__n_swaps;
  155.         }
  156.         // [__first, __i) < *__i and *__i <= [__i+1, __last)
  157.         // If we were given a perfect partition, see if insertion sort is quick...
  158.         if (__n_swaps == 0)
  159.         {
  160.             bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp);
  161.             if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp))
  162.             {
  163.                 if (__fs)
  164.                     return;
  165.                 __last = __i;
  166.                 continue;
  167.             }
  168.             else
  169.             {
  170.                 if (__fs)
  171.                 {
  172.                     __first = ++__i;
  173.                     continue;
  174.                 }
  175.             }
  176.         }
  177.         // sort smaller range with recursive call and larger with tail recursion elimination
  178.         if (__i - __first < __last - __i)
  179.         {
  180.             _VSTD::__sort<_Compare>(__first, __i, __comp);
  181.             // _VSTD::__sort<_Compare>(__i+1, __last, __comp);
  182.             __first = ++__i;
  183.         }
  184.         else
  185.         {
  186.             _VSTD::__sort<_Compare>(__i+1, __last, __comp);
  187.             // _VSTD::__sort<_Compare>(__first, __i, __comp);
  188.             __last = __i;
  189.         }
  190.     }
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement