VirtualBox

Changeset 96361 in vbox


Ignore:
Timestamp:
Aug 19, 2022 8:55:32 PM (2 years ago)
Author:
vboxsync
Message:

iprt/nocrt/algorithm: Just use shell sort for the std::sort implementation for now. bugref:10261

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/nocrt/algorithm

    r95993 r96361  
    3737namespace std
    3838{
     39    /**
     40     * Swap the values pointed to by the two references.
     41     */
     42    template<typename a_Type>
     43    void swap(a_Type &a_rObj1, a_Type &a_rObj2)
     44    {
     45        a_Type Tmp(a_rObj1);
     46        a_rObj1 = a_rObj2;
     47        a_rObj2 = Tmp;
     48    }
     49
     50    /**
     51     * Swap the values pointed to by two forward iterators.
     52     */
     53    template<typename a_ForwardIt1, typename a_ForwardIt2>
     54    void iter_swap(a_ForwardIt1 a_It1, a_ForwardIt2 a_It2)
     55    {
     56        swap(*a_It1, *a_It2);
     57    }
     58
    3959    template<typename a_RandomIt>
    40     void sort(a_RandomIt a_ItBegin, a_RandomIt a_ItEnd);
     60    void sort(a_RandomIt a_ItBegin, a_RandomIt a_ItEnd)
     61    {
     62        /* Note! Using shell sort here because it's tiny and we've got code for it. */
     63        /** @todo replace with faster code.   */
    4164
    42     template<typename a_RandomIt, typename a_Compare>
    43     void sort(a_RandomIt a_ItBegin, a_RandomIt a_ItEnd, a_Compare);
     65        /* Anything worth sorting? */
     66        std::size_t const cElements = a_ItEnd - a_ItBegin;
     67        if (cElements >= 1)
     68        {
     69            /* Loop on decreasing gap, ending with 1: */
     70            std::size_t cGap = (cElements + 1) / 2;
     71            while (cGap > 0)
     72            {
     73                /* Iterate from cGap till the end: */
     74                for (std::size_t i = cGap; i < cElements; i++)
     75                {
     76                    /* Find the best suitable location for the item at 'i' comparing
     77                       backwards in steps of 'cGap', swapping the item at 'i' with the
     78                       one at '-cGap*j' if it's smaller, stopping if it's larger.
     79
     80                       Note! Original algorithm would make a copy of the item, this version
     81                             avoids extra copies of sorted items at the cost of extra copies
     82                             when dealing with unsorted ones a small cGaps values. */
     83                    a_RandomIt ItCur = a_ItBegin + i;
     84                    size_t     j     = i;
     85                    do
     86                    {
     87                        j -= cGap;
     88                        a_RandomIt ItAtGap = a_ItBegin + j;
     89                        if (*ItAtGap < *ItCur)
     90                            break;
     91                        std::iter_swap(ItAtGap, ItCur);
     92                        ItCur = ItAtGap;
     93                    } while (j >= cGap);
     94                }
     95
     96                /* This does not generate the most optimal gap sequence, but it has the
     97                   advantage of being simple and avoid floating point. */
     98                cGap /= 2;
     99            }
     100        }
     101    }
     102
     103    template<typename a_RandomIt, typename a_FnCompareType>
     104    void sort(a_RandomIt a_ItBegin, a_RandomIt a_ItEnd, a_FnCompareType a_fnComp)
     105    {
     106        /* Note! Using shell sort here because it's tiny and we've got code for it. */
     107        /** @todo replace with faster code.   */
     108
     109        /* Anything worth sorting? */
     110        std::size_t const cElements = a_ItEnd - a_ItBegin;
     111        if (cElements >= 1)
     112        {
     113            /* Loop on decreasing gap, ending with 1: */
     114            std::size_t cGap = (cElements + 1) / 2;
     115            while (cGap > 0)
     116            {
     117                /* Iterate from cGap till the end: */
     118                for (std::size_t i = cGap; i < cElements; i++)
     119                {
     120                    /* Find the best suitable location for the item at 'i' comparing
     121                       backwards in steps of 'cGap', swapping the item at 'i' with the
     122                       one at '-cGap*j' if it's smaller, stopping if it's larger.
     123
     124                       Note! Original algorithm would make a copy of the item, this version
     125                             avoids extra copies of sorted items at the cost of extra copies
     126                             when dealing with unsorted ones a small cGaps values. */
     127                    a_RandomIt ItCur = a_ItBegin + i;
     128                    size_t     j     = i;
     129                    do
     130                    {
     131                        j -= cGap;
     132                        a_RandomIt ItAtGap = a_ItBegin + j;
     133                        if (a_fnComp(*ItAtGap, *ItCur))
     134                            break;
     135                        std::iter_swap(ItAtGap, ItCur);
     136                        ItCur = ItAtGap;
     137                    } while (j >= cGap);
     138                }
     139
     140                /* This does not generate the most optimal gap sequence, but it has the
     141                   advantage of being simple and avoid floating point. */
     142                cGap /= 2;
     143            }
     144        }
     145    }
    44146
    45147}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette