9090namespace gfx {
9191
9292// ---------------------------------------
93- // Declaration
93+ // Implementation details
9494// ---------------------------------------
9595
96- /* *
97- * Same as std::stable_sort(first, last).
98- */
99- template <typename RandomAccessIterator>
100- void timsort (RandomAccessIterator const first, RandomAccessIterator const last);
96+ namespace detail {
10197
102- /* *
103- * Same as std::stable_sort(first, last, compare).
104- */
105- template <typename RandomAccessIterator, typename Compare>
106- void timsort (RandomAccessIterator const first, RandomAccessIterator const last, Compare compare);
98+ template <typename Iterator> struct run {
99+ typedef typename std::iterator_traits<Iterator>::difference_type diff_t ;
107100
108- // ---------------------------------------
109- // Implementation
110- // ---------------------------------------
101+ Iterator base;
102+ diff_t len;
103+
104+ run (Iterator b, diff_t l) : base(b), len(l) {
105+ }
106+ };
111107
112108template <typename RandomAccessIterator, typename Compare> class TimSort {
113109 typedef RandomAccessIterator iter_t ;
@@ -123,56 +119,7 @@ template <typename RandomAccessIterator, typename Compare> class TimSort {
123119 std::vector<value_t > tmp_; // temp storage for merges
124120 typedef typename std::vector<value_t >::iterator tmp_iter_t ;
125121
126- struct run {
127- iter_t base;
128- diff_t len;
129-
130- run (iter_t const b, diff_t const l) : base(b), len(l) {
131- }
132- };
133- std::vector<run> pending_;
134-
135- static void sort (iter_t const lo, iter_t const hi, Compare compare) {
136- GFX_TIMSORT_ASSERT (lo <= hi);
137-
138- diff_t nRemaining = (hi - lo);
139- if (nRemaining < 2 ) {
140- return ; // nothing to do
141- }
142-
143- if (nRemaining < MIN_MERGE) {
144- diff_t const initRunLen = countRunAndMakeAscending (lo, hi, compare);
145- GFX_TIMSORT_LOG (" initRunLen: " << initRunLen);
146- binarySort (lo, hi, lo + initRunLen, compare);
147- return ;
148- }
149-
150- TimSort ts;
151- diff_t const minRun = minRunLength (nRemaining);
152- iter_t cur = lo;
153- do {
154- diff_t runLen = countRunAndMakeAscending (cur, hi, compare);
155-
156- if (runLen < minRun) {
157- diff_t const force = std::min (nRemaining, minRun);
158- binarySort (cur, cur + force, cur + runLen, compare);
159- runLen = force;
160- }
161-
162- ts.pushRun (cur, runLen);
163- ts.mergeCollapse (compare);
164-
165- cur += runLen;
166- nRemaining -= runLen;
167- } while (nRemaining != 0 );
168-
169- GFX_TIMSORT_ASSERT (cur == hi);
170- ts.mergeForceCollapse (compare);
171- GFX_TIMSORT_ASSERT (ts.pending_ .size () == 1 );
172-
173- GFX_TIMSORT_LOG (" size: " << (hi - lo) << " tmp_.size(): " << ts.tmp_ .size ()
174- << " pending_.size(): " << ts.pending_ .size ());
175- }
122+ std::vector<run<RandomAccessIterator> > pending_;
176123
177124 static void binarySort (iter_t const lo, iter_t const hi, iter_t start, Compare compare) {
178125 GFX_TIMSORT_ASSERT (lo <= start && start <= hi);
@@ -231,7 +178,7 @@ template <typename RandomAccessIterator, typename Compare> class TimSort {
231178 ~TimSort () {}
232179
233180 void pushRun (iter_t const runBase, diff_t const runLen) {
234- pending_.push_back (run (runBase, runLen));
181+ pending_.push_back (run< iter_t > (runBase, runLen));
235182 }
236183
237184 void mergeCollapse (Compare compare) {
@@ -645,19 +592,72 @@ template <typename RandomAccessIterator, typename Compare> class TimSort {
645592#endif
646593 }
647594
648- template <typename IterT, typename LessT>
649- friend void timsort (IterT first, IterT last, LessT c);
595+ public:
596+
597+ static void sort (iter_t const lo, iter_t const hi, Compare compare) {
598+ GFX_TIMSORT_ASSERT (lo <= hi);
599+
600+ diff_t nRemaining = (hi - lo);
601+ if (nRemaining < 2 ) {
602+ return ; // nothing to do
603+ }
604+
605+ if (nRemaining < MIN_MERGE) {
606+ diff_t const initRunLen = countRunAndMakeAscending (lo, hi, compare);
607+ GFX_TIMSORT_LOG (" initRunLen: " << initRunLen);
608+ binarySort (lo, hi, lo + initRunLen, compare);
609+ return ;
610+ }
611+
612+ TimSort ts;
613+ diff_t const minRun = minRunLength (nRemaining);
614+ iter_t cur = lo;
615+ do {
616+ diff_t runLen = countRunAndMakeAscending (cur, hi, compare);
617+
618+ if (runLen < minRun) {
619+ diff_t const force = std::min (nRemaining, minRun);
620+ binarySort (cur, cur + force, cur + runLen, compare);
621+ runLen = force;
622+ }
623+
624+ ts.pushRun (cur, runLen);
625+ ts.mergeCollapse (compare);
626+
627+ cur += runLen;
628+ nRemaining -= runLen;
629+ } while (nRemaining != 0 );
630+
631+ GFX_TIMSORT_ASSERT (cur == hi);
632+ ts.mergeForceCollapse (compare);
633+ GFX_TIMSORT_ASSERT (ts.pending_ .size () == 1 );
634+
635+ GFX_TIMSORT_LOG (" size: " << (hi - lo) << " tmp_.size(): " << ts.tmp_ .size ()
636+ << " pending_.size(): " << ts.pending_ .size ());
637+ }
650638};
651639
652- template <typename RandomAccessIterator>
653- void timsort (RandomAccessIterator const first, RandomAccessIterator const last) {
654- typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
655- timsort (first, last, std::less<value_type>());
656- }
640+ } // namespace detail
657641
642+ // ---------------------------------------
643+ // Public interface implementation
644+ // ---------------------------------------
645+
646+ /* *
647+ * Same as std::stable_sort(first, last, compare).
648+ */
658649template <typename RandomAccessIterator, typename Compare>
659650void timsort (RandomAccessIterator const first, RandomAccessIterator const last, Compare compare) {
660- TimSort<RandomAccessIterator, Compare>::sort (first, last, compare);
651+ detail::TimSort<RandomAccessIterator, Compare>::sort (first, last, compare);
652+ }
653+
654+ /* *
655+ * Same as std::stable_sort(first, last).
656+ */
657+ template <typename RandomAccessIterator>
658+ void timsort (RandomAccessIterator const first, RandomAccessIterator const last) {
659+ typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
660+ gfx::timsort (first, last, std::less<value_type>());
661661}
662662
663663} // namespace gfx
0 commit comments