55namespace std {
66
77template <typename T> inline const T& max(const T& a, const T& b) {
8- return a < b ? b : a;
8+ return ( a < b) ? b : a;
99}
1010
1111template <typename T> inline const T& min(const T& a, const T& b) {
12- return b < a ? b : a;
12+ return ( b < a) ? b : a;
1313}
1414
1515template <typename TPtr, typename T>
@@ -22,32 +22,196 @@ inline TPtr find(TPtr first, TPtr last, const T& value) {
2222}
2323
2424template <typename TPtr> inline long distance(TPtr first, TPtr last) {
25- random_access_iterator_tag tag;
26- return __distance(first, last, tag);
25+ return __distance(first, last, random_access_iterator_tag());
2726}
2827
2928template <typename TPtr>
30- inline long __distance(TPtr first, TPtr last, random_access_iterator_tag tag) {
31- long dist = reinterpret_cast<long>(last) - reinterpret_cast<long>(first);
32- return dist / static_cast<long>(sizeof(TPtr));
29+ inline long __distance(TPtr first, TPtr last, random_access_iterator_tag) {
30+ return static_cast<long>(last - first);
3331}
3432
35- #if __option(rvalue_refs)
36- template <typename T> inline T&& move(T&& x) {
37- return static_cast<T&&>(x);
38- }
39- #else
4033template <typename T> inline T& move(T& x) {
4134 return x;
4235}
43- #endif
4436
4537template <typename T> inline void swap(T& a, T& b) {
4638 T tmp = move(a);
4739 a = move(b);
4840 b = move(tmp);
4941}
5042
43+ template <typename TIt, typename TCompare>
44+ inline TIt min_element(TIt first, TIt last, TCompare compare) {
45+ TIt it = first;
46+
47+ if (first != last) {
48+ for (++first; first != last; ++first) {
49+ if (compare(*first, *it)) {
50+ it = first;
51+ }
52+ }
53+ }
54+
55+ return it;
56+ }
57+
58+ template <typename TCompare, typename TIt>
59+ inline void __selection_sort(TIt first, TIt last, TCompare compare) {
60+ if (first == last) {
61+ return;
62+ }
63+
64+ TIt j = last;
65+ for (--j; first != j; ++first) {
66+ TIt i = min_element<TIt, TCompare&>(first, last, compare);
67+
68+ if (i != first) {
69+ swap(*i, *first);
70+ }
71+ }
72+ }
73+
74+ template <typename TCompare, typename TIt>
75+ void __sort132(TIt a1, TIt a2, TIt a3, TCompare compare) DECOMP_DONT_INLINE {
76+ bool b1 = !compare(*a3, *a1);
77+ bool b2 = !compare(*a2, *a3);
78+
79+ if (!b1 || !b2) {
80+ if (!b1 && !b2) {
81+ swap(*a1, *a2);
82+ return;
83+ }
84+
85+ if (compare(*a2, *a1)) {
86+ swap(*a1, *a2);
87+ }
88+
89+ if (b1) {
90+ swap(*a2, *a3);
91+ return;
92+ }
93+
94+ swap(*a1, *a3);
95+ }
96+ }
97+
98+ template <typename TIt, typename TCompare>
99+ void sort(TIt first, TIt last, TCompare compare) {
100+ static const int SHUFFLE_MIN = -4;
101+ static const int SHUFFLE_MAX = 5;
102+ static const int SELECTION_SORT_MIN = 20;
103+
104+ while (true) {
105+ long len = static_cast<long>(last - first);
106+ if (len <= 1) {
107+ return;
108+ }
109+
110+ if (len <= SELECTION_SORT_MIN) {
111+ __selection_sort<TCompare&, TIt>(first, last, compare);
112+ return;
113+ }
114+
115+ static int shuffle = -4;
116+ TIt m = first +
117+ (len / static_cast<long>(sizeof(TIt)) + shuffle % SHUFFLE_MAX);
118+
119+ if (++shuffle >= SHUFFLE_MAX) {
120+ shuffle = SHUFFLE_MIN;
121+ }
122+
123+ TIt i1 = first + (len * static_cast<long>(sizeof(TIt) - 1) /
124+ static_cast<long>(sizeof(TIt)) +
125+ shuffle % SHUFFLE_MAX);
126+
127+ if (++shuffle >= SHUFFLE_MAX) {
128+ shuffle = SHUFFLE_MIN;
129+ }
130+
131+ TIt j = last - 1;
132+ __sort132<TCompare&, TIt>(m, i1, j, compare);
133+
134+ m = first;
135+ i1 = j;
136+ while (compare(*m, *j)) {
137+ m++;
138+ }
139+
140+ do {
141+ i1--;
142+
143+ if (m == i1) {
144+ break;
145+ }
146+ } while (!compare(*i1, *j));
147+
148+ if (m < i1) {
149+ swap(*m, *i1);
150+ m++;
151+
152+ while (true) {
153+ while (compare(*m, *j)) {
154+ m++;
155+ }
156+
157+ while (!compare(*--i1, *j)) {
158+ ;
159+ }
160+
161+ if (m < i1) {
162+ swap(*m, *i1);
163+ m++;
164+ } else {
165+ break;
166+ }
167+ }
168+ }
169+
170+ if (m == first) {
171+ swap(*m, *j);
172+ m++;
173+
174+ i1 = last;
175+ if (!compare(*first, *--i1)) {
176+ while (m != last && !compare(*first, *m)) {
177+ m++;
178+ }
179+
180+ if (m < i1) {
181+ swap(*m, *i1);
182+ }
183+ }
184+
185+ if (m < i1) {
186+ while (true) {
187+ while (!compare(*first, *m)) {
188+ m++;
189+ }
190+
191+ while (compare(*first, *--i1)) {
192+ ;
193+ }
194+
195+ if (m < i1) {
196+ swap(*m, *i1);
197+ m++;
198+ } else {
199+ break;
200+ }
201+ }
202+ }
203+
204+ first = m;
205+ } else if (m - first < last - m) {
206+ sort<TIt, TCompare&>(first, m, compare);
207+ first = m;
208+ } else {
209+ sort<TIt, TCompare&>(m, last, compare);
210+ last = m;
211+ }
212+ }
213+ }
214+
51215} // namespace std
52216
53217#endif
0 commit comments