2#ifndef __ASE_SORTNET_HH__
3#define __ASE_SORTNET_HH__
10namespace SortingNetworks {
12template<
class RandomIt,
class Compare>
inline __attribute__ ((always_inline))
void
13srt (RandomIt &v1, RandomIt &v2, Compare lesser)
16 if (__builtin_expect (lesser (v2, v1), 0))
20template<
class RandomIt,
class Compare>
void
21sort_3 (RandomIt v, Compare c)
23 srt (v[0], v[1], c); srt (v[0], v[2], c); srt (v[1], v[2], c);
26template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
27sort_4 (RandomIt v, Compare c)
30 srt (v[0], v[1], c); srt (v[2], v[3], c); srt (v[0], v[2], c);
31 srt (v[1], v[3], c); srt (v[1], v[2], c);
34template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
35sort_5 (RandomIt v, Compare c)
38 srt (v[0], v[1], c); srt (v[3], v[4], c); srt (v[2], v[4], c); srt (v[2], v[3], c); srt (v[1], v[4], c);
39 srt (v[1], v[2], c); srt (v[0], v[3], c); srt (v[0], v[1], c); srt (v[2], v[3], c);
42template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
43sort_6 (RandomIt v, Compare c)
46 srt (v[0], v[1], c); srt (v[2], v[3], c); srt (v[4], v[5], c); srt (v[0], v[2], c);
47 srt (v[1], v[3], c); srt (v[1], v[2], c); srt (v[0], v[4], c); srt (v[2], v[4], c);
48 srt (v[1], v[5], c); srt (v[3], v[5], c); srt (v[1], v[2], c); srt (v[3], v[4], c);
51template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
52sort_7 (RandomIt v, Compare c)
55 srt (v[0], v[1], c); srt (v[2], v[3], c); srt (v[4], v[5], c); srt (v[0], v[2], c);
56 srt (v[1], v[3], c); srt (v[4], v[6], c); srt (v[1], v[2], c); srt (v[5], v[6], c);
57 srt (v[0], v[4], c); srt (v[2], v[6], c); srt (v[1], v[5], c); srt (v[2], v[4], c);
58 srt (v[3], v[5], c); srt (v[1], v[2], c); srt (v[3], v[4], c); srt (v[5], v[6], c);
61template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
62sort_8 (RandomIt v, Compare c)
65 srt (v[0], v[1], c); srt (v[2], v[3], c); srt (v[4], v[5], c); srt (v[6], v[7], c); srt (v[0], v[2], c);
66 srt (v[1], v[3], c); srt (v[4], v[6], c); srt (v[5], v[7], c); srt (v[1], v[2], c); srt (v[5], v[6], c);
67 srt (v[0], v[4], c); srt (v[3], v[7], c); srt (v[2], v[6], c); srt (v[1], v[5], c); srt (v[2], v[4], c);
68 srt (v[3], v[5], c); srt (v[1], v[2], c); srt (v[3], v[4], c); srt (v[5], v[6], c);
71template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
72sort_9 (RandomIt v, Compare c)
75 srt (v[0], v[1], c); srt (v[2], v[3], c); srt (v[4], v[5], c); srt (v[6], v[7], c); srt (v[1], v[3], c);
76 srt (v[5], v[7], c); srt (v[0], v[2], c); srt (v[4], v[6], c); srt (v[1], v[5], c); srt (v[3], v[7], c);
77 srt (v[0], v[4], c); srt (v[2], v[6], c); srt (v[1], v[8], c); srt (v[2], v[4], c); srt (v[3], v[5], c);
78 srt (v[1], v[2], c); srt (v[4], v[8], c); srt (v[2], v[4], c); srt (v[6], v[8], c); srt (v[0], v[1], c);
79 srt (v[5], v[8], c); srt (v[3], v[6], c); srt (v[3], v[4], c); srt (v[5], v[6], c); srt (v[7], v[8], c);
82template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
83sort_10 (RandomIt v, Compare c)
86 srt (v[0], v[8], c); srt (v[1], v[9], c); srt (v[2], v[7], c); srt (v[3], v[5], c); srt (v[4], v[6], c);
87 srt (v[0], v[2], c); srt (v[1], v[4], c); srt (v[5], v[8], c); srt (v[7], v[9], c); srt (v[0], v[3], c);
88 srt (v[2], v[4], c); srt (v[5], v[7], c); srt (v[6], v[9], c); srt (v[0], v[1], c); srt (v[3], v[6], c);
89 srt (v[8], v[9], c); srt (v[1], v[5], c); srt (v[2], v[3], c); srt (v[4], v[8], c); srt (v[6], v[7], c);
90 srt (v[1], v[2], c); srt (v[3], v[5], c); srt (v[4], v[6], c); srt (v[7], v[8], c); srt (v[2], v[3], c);
91 srt (v[4], v[5], c); srt (v[6], v[7], c); srt (v[3], v[4], c); srt (v[5], v[6], c);
94template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
95sort_11 (RandomIt v, Compare c)
98 srt (v[0], v[9], c); srt (v[1], v[6], c); srt (v[2], v[4], c); srt (v[3], v[7], c); srt (v[5], v[8], c);
99 srt (v[0], v[1], c); srt (v[3], v[5], c); srt (v[4], v[10], c); srt (v[6], v[9], c); srt (v[7], v[8], c);
100 srt (v[1], v[3], c); srt (v[2], v[5], c); srt (v[4], v[7], c); srt (v[8], v[10], c); srt (v[0], v[4], c);
101 srt (v[1], v[2], c); srt (v[3], v[7], c); srt (v[5], v[9], c); srt (v[6], v[8], c); srt (v[0], v[1], c);
102 srt (v[2], v[6], c); srt (v[4], v[5], c); srt (v[7], v[8], c); srt (v[9], v[10], c); srt (v[2], v[4], c);
103 srt (v[3], v[6], c); srt (v[5], v[7], c); srt (v[8], v[9], c); srt (v[1], v[2], c); srt (v[3], v[4], c);
104 srt (v[5], v[6], c); srt (v[7], v[8], c); srt (v[2], v[3], c); srt (v[4], v[5], c); srt (v[6], v[7], c);
107template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
108sort_12 (RandomIt v, Compare c)
111 srt (v[0], v[8], c); srt (v[1], v[7], c); srt (v[2], v[6], c); srt (v[3], v[11], c); srt (v[4], v[10], c);
112 srt (v[5], v[9], c); srt (v[0], v[1], c); srt (v[2], v[5], c); srt (v[3], v[4], c); srt (v[6], v[9], c);
113 srt (v[7], v[8], c); srt (v[10], v[11], c); srt (v[0], v[2], c); srt (v[1], v[6], c); srt (v[5], v[10], c);
114 srt (v[9], v[11], c); srt (v[0], v[3], c); srt (v[1], v[2], c); srt (v[4], v[6], c); srt (v[5], v[7], c);
115 srt (v[8], v[11], c); srt (v[9], v[10], c); srt (v[1], v[4], c); srt (v[3], v[5], c); srt (v[6], v[8], c);
116 srt (v[7], v[10], c); srt (v[1], v[3], c); srt (v[2], v[5], c); srt (v[6], v[9], c); srt (v[8], v[10], c);
117 srt (v[2], v[3], c); srt (v[4], v[5], c); srt (v[6], v[7], c); srt (v[8], v[9], c); srt (v[4], v[6], c);
118 srt (v[5], v[7], c); srt (v[3], v[4], c); srt (v[5], v[6], c); srt (v[7], v[8], c);
121template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
122sort_13 (RandomIt v, Compare c)
125 srt (v[0], v[12], c); srt (v[1], v[10], c); srt (v[2], v[9], c); srt (v[3], v[7], c); srt (v[5], v[11], c);
126 srt (v[6], v[8], c); srt (v[1], v[6], c); srt (v[2], v[3], c); srt (v[4], v[11], c); srt (v[7], v[9], c);
127 srt (v[8], v[10], c); srt (v[0], v[4], c); srt (v[1], v[2], c); srt (v[3], v[6], c); srt (v[7], v[8], c);
128 srt (v[9], v[10], c); srt (v[11], v[12], c); srt (v[4], v[6], c); srt (v[5], v[9], c); srt (v[8], v[11], c);
129 srt (v[10], v[12], c); srt (v[0], v[5], c); srt (v[3], v[8], c); srt (v[4], v[7], c); srt (v[6], v[11], c);
130 srt (v[9], v[10], c); srt (v[0], v[1], c); srt (v[2], v[5], c); srt (v[6], v[9], c); srt (v[7], v[8], c);
131 srt (v[10], v[11], c); srt (v[1], v[3], c); srt (v[2], v[4], c); srt (v[5], v[6], c); srt (v[9], v[10], c);
132 srt (v[1], v[2], c); srt (v[3], v[4], c); srt (v[5], v[7], c); srt (v[6], v[8], c); srt (v[2], v[3], c);
133 srt (v[4], v[5], c); srt (v[6], v[7], c); srt (v[8], v[9], c); srt (v[3], v[4], c); srt (v[5], v[6], c);
136template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
137sort_14 (RandomIt v, Compare c)
140 srt (v[0], v[6], c); srt (v[1], v[11], c); srt (v[2], v[12], c); srt (v[3], v[10], c); srt (v[4], v[5], c);
141 srt (v[7], v[13], c); srt (v[8], v[9], c); srt (v[1], v[2], c); srt (v[3], v[7], c); srt (v[4], v[8], c);
142 srt (v[5], v[9], c); srt (v[6], v[10], c); srt (v[11], v[12], c); srt (v[0], v[4], c); srt (v[1], v[3], c);
143 srt (v[5], v[6], c); srt (v[7], v[8], c); srt (v[9], v[13], c); srt (v[10], v[12], c); srt (v[0], v[1], c);
144 srt (v[2], v[9], c); srt (v[3], v[7], c); srt (v[4], v[11], c); srt (v[6], v[10], c); srt (v[12], v[13], c);
145 srt (v[2], v[5], c); srt (v[4], v[7], c); srt (v[6], v[9], c); srt (v[8], v[11], c); srt (v[1], v[2], c);
146 srt (v[3], v[4], c); srt (v[6], v[7], c); srt (v[9], v[10], c); srt (v[11], v[12], c); srt (v[1], v[3], c);
147 srt (v[2], v[4], c); srt (v[5], v[6], c); srt (v[7], v[8], c); srt (v[9], v[11], c); srt (v[10], v[12], c);
148 srt (v[2], v[3], c); srt (v[4], v[7], c); srt (v[6], v[9], c); srt (v[10], v[11], c); srt (v[4], v[5], c);
149 srt (v[6], v[7], c); srt (v[8], v[9], c); srt (v[3], v[4], c); srt (v[5], v[6], c); srt (v[7], v[8], c);
150 srt (v[9], v[10], c);
153template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
154sort_15 (RandomIt v, Compare c)
157 srt (v[1], v[2], c); srt (v[3], v[10], c); srt (v[4], v[14], c); srt (v[5], v[8], c); srt (v[6], v[13], c);
158 srt (v[7], v[12], c); srt (v[9], v[11], c); srt (v[0], v[14], c); srt (v[1], v[5], c); srt (v[2], v[8], c);
159 srt (v[3], v[7], c); srt (v[6], v[9], c); srt (v[10], v[12], c); srt (v[11], v[13], c); srt (v[0], v[7], c);
160 srt (v[1], v[6], c); srt (v[2], v[9], c); srt (v[4], v[10], c); srt (v[5], v[11], c); srt (v[8], v[13], c);
161 srt (v[12], v[14], c); srt (v[0], v[6], c); srt (v[2], v[4], c); srt (v[3], v[5], c); srt (v[7], v[11], c);
162 srt (v[8], v[10], c); srt (v[9], v[12], c); srt (v[13], v[14], c); srt (v[0], v[3], c); srt (v[1], v[2], c);
163 srt (v[4], v[7], c); srt (v[5], v[9], c); srt (v[6], v[8], c); srt (v[10], v[11], c); srt (v[12], v[13], c);
164 srt (v[0], v[1], c); srt (v[2], v[3], c); srt (v[4], v[6], c); srt (v[7], v[9], c); srt (v[10], v[12], c);
165 srt (v[11], v[13], c); srt (v[1], v[2], c); srt (v[3], v[5], c); srt (v[8], v[10], c); srt (v[11], v[12], c);
166 srt (v[3], v[4], c); srt (v[5], v[6], c); srt (v[7], v[8], c); srt (v[9], v[10], c); srt (v[2], v[3], c);
167 srt (v[4], v[5], c); srt (v[6], v[7], c); srt (v[8], v[9], c); srt (v[10], v[11], c); srt (v[5], v[6], c);
171template<
class RandomIt,
class Compare>
void __attribute__ ((noinline))
172sort_16 (RandomIt v, Compare c)
175 srt (v[0], v[13], c); srt (v[1], v[12], c); srt (v[2], v[15], c); srt (v[3], v[14], c); srt (v[4], v[8], c);
176 srt (v[5], v[6], c); srt (v[7], v[11], c); srt (v[9], v[10], c); srt (v[0], v[5], c); srt (v[1], v[7], c);
177 srt (v[2], v[9], c); srt (v[3], v[4], c); srt (v[6], v[13], c); srt (v[8], v[14], c); srt (v[10], v[15], c);
178 srt (v[11], v[12], c); srt (v[0], v[1], c); srt (v[2], v[3], c); srt (v[4], v[5], c); srt (v[6], v[8], c);
179 srt (v[7], v[9], c); srt (v[10], v[11], c); srt (v[12], v[13], c); srt (v[14], v[15], c); srt (v[0], v[2], c);
180 srt (v[1], v[3], c); srt (v[4], v[10], c); srt (v[5], v[11], c); srt (v[6], v[7], c); srt (v[8], v[9], c);
181 srt (v[12], v[14], c); srt (v[13], v[15], c); srt (v[1], v[2], c); srt (v[3], v[12], c); srt (v[4], v[6], c);
182 srt (v[5], v[7], c); srt (v[8], v[10], c); srt (v[9], v[11], c); srt (v[13], v[14], c); srt (v[1], v[4], c);
183 srt (v[2], v[6], c); srt (v[5], v[8], c); srt (v[7], v[10], c); srt (v[9], v[13], c); srt (v[11], v[14], c);
184 srt (v[2], v[4], c); srt (v[3], v[6], c); srt (v[9], v[12], c); srt (v[11], v[13], c); srt (v[3], v[5], c);
185 srt (v[6], v[8], c); srt (v[7], v[9], c); srt (v[10], v[12], c); srt (v[3], v[4], c); srt (v[5], v[6], c);
186 srt (v[7], v[8], c); srt (v[9], v[10], c); srt (v[11], v[12], c); srt (v[6], v[7], c); srt (v[8], v[9], c);
192template<
class RandomIt,
class Compare>
inline void
196 using namespace SortingNetworks;
197 const size_t n = last - first;
202 case 2:
return srt (first[0], first[1], comp);
203 case 3:
return sort_3 (first, comp);
204 case 4:
return sort_4 (first, comp);
205 case 5:
return sort_5 (first, comp);
206 case 6:
return sort_6 (first, comp);
207 case 7:
return sort_7 (first, comp);
208 case 8:
return sort_8 (first, comp);
209 case 9:
return sort_9 (first, comp);
210 case 10:
return sort_10 (first, comp);
211 case 11:
return sort_11 (first, comp);
212 case 12:
return sort_12 (first, comp);
213 case 13:
return sort_13 (first, comp);
214 case 14:
return sort_14 (first, comp);
215 case 15:
return sort_15 (first, comp);
216 case 16:
return sort_16 (first, comp);
217 default:
return std::sort (first, last, comp);
222template<
class T,
class Less = std::less<T>>
233 constexpr void reserve (size_type n) { v_.reserve (n); }
234 constexpr size_type capacity ()
const noexcept {
return v_.capacity(); }
235 constexpr const_iterator begin ()
const noexcept {
return v_.begin(); }
236 constexpr const_iterator end ()
const noexcept {
return v_.end(); }
237 constexpr const_reverse_iterator crbegin ()
const noexcept {
return v_.crbegin(); }
238 constexpr const_reverse_iterator crend ()
const noexcept {
return v_.crend(); }
239 constexpr const_reverse_iterator rbegin ()
const noexcept {
return v_.rbegin(); }
240 constexpr const_reverse_iterator rend ()
const noexcept {
return v_.rend(); }
241 constexpr void clear ()
noexcept { v_.clear(); }
242 constexpr bool empty ()
const noexcept {
return v_.empty(); }
243 constexpr iterator erase (const_iterator first, const_iterator last) {
return v_.erase (first, last); }
244 constexpr iterator erase (const_iterator position) {
return v_.erase (position); }
245 constexpr iterator replace (
const value_type &val) {
return insert (val,
true); }
246 constexpr size_type size ()
const noexcept {
return v_.size(); }
247 constexpr void shrink_to_fit () { v_.shrink_to_fit(); }
248 constexpr bool sorted (
const bool allow_multiple =
false)
const {
return sorted (*
this, allow_multiple); }
249 constexpr bool contains (
const value_type &val)
const {
return end() != find (val); }
250 constexpr const_iterator find (
const value_type &val)
const {
return const_cast<SortedVector&
> (*this).find (val); }
251 constexpr const_reference front ()
const noexcept {
return v_.front(); }
252 constexpr const_reference back ()
const noexcept {
return v_.back(); }
253 constexpr const T* data ()
const noexcept {
return v_.data(); }
254 constexpr T* data ()
noexcept {
return v_.data(); }
255 constexpr void swap (
std::vector<T> &other)
noexcept { v_.swap (other); sort(); }
256 constexpr void swap (
SortedVector &other)
noexcept { v_.swap (other); }
257 constexpr const_reference at (size_type n)
const {
return v_.at (n); }
258 constexpr const_reference operator[] (size_type n)
const noexcept {
return v_[n]; }
290 resize (size_type n,
const value_type &el)
292 const size_type o = v_.size();
306 const Less &lesser = *
this;
310 find (
const value_type &val)
312 const Less &lesser = *
this;
314 if (it == v_.end() || lesser (val, *it))
319 insert (
const value_type &val,
bool replace =
false)
321 const Less &lesser = *
this;
323 if (it != end() && !lesser (val, *it))
330 return v_.insert (it, val);
333 sorted (
const Less &lesser,
const bool allow_multiple =
false)
const
335 const size_type l = size();
336 for (size_type i = 1; i < l; i++)
337 if (lesser (v_[i-1], v_[i]) ==
false)
339 if (allow_multiple && lesser (v_[i], v_[i-1]) ==
false)
346 collapse (
bool delete_first =
true)
348 const Less &lesser = *
this;
349 const size_type l = size();
350 for (size_type i = 1; i < size(); i++)
351 if (lesser (v_[i-1], v_[i]) ==
false)
353 erase (begin() + i - delete_first);
358 template<
class Pred>
constexpr size_type
361 const size_type l = size();
362 for (iterator it = v_.begin(); it != v_.end(); )
369 template<
class InputIterator>
constexpr
370 SortedVector (InputIterator first, InputIterator last) :
381 template<
class Pred>
friend constexpr size_type erase_if (
SortedVector &self, Pred pred) {
return self.erase_if (pred); }
Vector that keeps its elements sorted.
The Anklang C++ API namespace.
void fixed_sort(RandomIt first, RandomIt last, Compare comp=std::less< typename std::iterator_traits< RandomIt >::value_type >())
Use sorting networks to sort containers <= 16 elements without allocations.