@@ -103,6 +103,52 @@ namespace gfx {
103
103
104
104
namespace detail {
105
105
106
+ // Equivalent to C++20 std::identity
107
+ struct identity {
108
+ #if GFX_TIMSORT_USE_STD_MOVE
109
+ template <typename T>
110
+ T&& operator ()(T&& value) const
111
+ {
112
+ return std::forward<T>(value);
113
+ }
114
+ #else
115
+ template <typename T>
116
+ T& operator ()(T& value) const {
117
+ return value;
118
+ }
119
+
120
+ template <typename T>
121
+ T const & operator ()(T const & value) const {
122
+ return value;
123
+ }
124
+ #endif
125
+ };
126
+
127
+ // Merge a predicate and a projection function
128
+ template <typename Compare, typename Projection>
129
+ struct projection_compare {
130
+ projection_compare (Compare comp, Projection proj) : compare(comp), projection(proj) {
131
+ }
132
+
133
+ #if GFX_TIMSORT_USE_STD_MOVE
134
+ template <typename T, typename U>
135
+ bool operator ()(T &&lhs, U &&rhs) {
136
+ return static_cast <bool >(compare (
137
+ projection (std::forward<T>(lhs)),
138
+ projection (std::forward<U>(rhs))
139
+ ));
140
+ }
141
+ #else
142
+ template <typename T, typename U>
143
+ bool operator ()(T &lhs, U &rhs) {
144
+ return static_cast <bool >(compare (projection (lhs), projection (rhs)));
145
+ }
146
+ #endif
147
+
148
+ Compare compare;
149
+ Projection projection;
150
+ };
151
+
106
152
template <typename Iterator> struct run {
107
153
typedef typename std::iterator_traits<Iterator>::difference_type diff_t ;
108
154
@@ -669,12 +715,23 @@ template <typename RandomAccessIterator, typename Compare> class TimSort {
669
715
// Public interface implementation
670
716
// ---------------------------------------
671
717
718
+ /* *
719
+ * Stably sorts a range with a comparison function and a projection function.
720
+ */
721
+ template <typename RandomAccessIterator, typename Compare, typename Projection>
722
+ void timsort (RandomAccessIterator const first, RandomAccessIterator const last,
723
+ Compare compare, Projection projection) {
724
+ typedef detail::projection_compare<Compare, Projection> compare_t ;
725
+ compare_t comp (compare, projection);
726
+ detail::TimSort<RandomAccessIterator, compare_t >::sort (first, last, comp);
727
+ }
728
+
672
729
/* *
673
730
* Same as std::stable_sort(first, last, compare).
674
731
*/
675
732
template <typename RandomAccessIterator, typename Compare>
676
733
void timsort (RandomAccessIterator const first, RandomAccessIterator const last, Compare compare) {
677
- detail::TimSort<RandomAccessIterator, Compare>:: sort (first, last, compare);
734
+ gfx::timsort (first, last, compare, detail::identity () );
678
735
}
679
736
680
737
/* *
@@ -683,7 +740,7 @@ void timsort(RandomAccessIterator const first, RandomAccessIterator const last,
683
740
template <typename RandomAccessIterator>
684
741
void timsort (RandomAccessIterator const first, RandomAccessIterator const last) {
685
742
typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
686
- gfx::timsort (first, last, std::less<value_type>());
743
+ gfx::timsort (first, last, std::less<value_type>(), detail::identity () );
687
744
}
688
745
689
746
} // namespace gfx
0 commit comments