blob: 9144a58c0251471e21a04d4ee30d276a79d82841 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:251/*
mflodman@webrtc.orgc80d9d92012-02-06 10:11:252 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:253 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// When the platform supports STL, the functions are implemented using a
12// templated spreadsort algorithm (http://sourceforge.net/projects/spreadsort/),
13// part of the Boost C++ library collection. Otherwise, the C standard library's
14// qsort() will be used.
15
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2416#include "webrtc/system_wrappers/interface/sort.h"
niklase@google.com470e71d2011-07-07 08:21:2517
pbos@webrtc.org12dc1a32013-08-05 16:22:5318#include <assert.h>
19#include <string.h> // memcpy
20
niklase@google.com470e71d2011-07-07 08:21:2521#include <new> // nothrow new
22
23#ifdef NO_STL
pbos@webrtc.org12dc1a32013-08-05 16:22:5324#include <stdlib.h> // qsort
niklase@google.com470e71d2011-07-07 08:21:2525#else
26#include <algorithm> // std::sort
27#include <vector>
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2428
pbos@webrtc.orgacaf3a12013-05-27 15:07:4529// TODO(ajm) upgrade to spreadsort v2.
30#include "webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp"
niklase@google.com470e71d2011-07-07 08:21:2531#endif
32
33#ifdef NO_STL
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2434#define COMPARE_DEREFERENCED(XT, YT) \
35 do { \
36 if ((XT) > (YT)) { \
37 return 1; \
38 } \
39 else if ((XT) < (YT)) { \
40 return -1; \
41 } \
42 return 0; \
43 } while(0)
niklase@google.com470e71d2011-07-07 08:21:2544
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2445#define COMPARE_FOR_QSORT(X, Y, TYPE) \
46 do { \
47 TYPE xT = static_cast<TYPE>(*static_cast<const TYPE*>(X)); \
48 TYPE yT = static_cast<TYPE>(*static_cast<const TYPE*>(Y)); \
49 COMPARE_DEREFERENCED(xT, yT); \
50 } while(0)
niklase@google.com470e71d2011-07-07 08:21:2551
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2452#define COMPARE_KEY_FOR_QSORT(SORT_KEY_X, SORT_KEY_Y, TYPE) \
53 do { \
54 TYPE xT = static_cast<TYPE>( \
55 *static_cast<TYPE*>(static_cast<const SortKey*>(SORT_KEY_X)->key_)); \
56 TYPE yT = static_cast<TYPE>( \
57 *static_cast<TYPE*>(static_cast<const SortKey*>(SORT_KEY_Y)->key_)); \
58 COMPARE_DEREFERENCED(xT, yT); \
59 } while(0)
niklase@google.com470e71d2011-07-07 08:21:2560
61#define KEY_QSORT(SORT_KEY, KEY, NUM_OF_ELEMENTS, KEY_TYPE, COMPARE_FUNC) \
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2462 do { \
63 KEY_TYPE* key_type = (KEY_TYPE*)(key); \
pbos@webrtc.org046deb92013-04-09 09:06:1164 for (uint32_t i = 0; i < (NUM_OF_ELEMENTS); ++i) { \
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2465 ptr_sort_key[i].key_ = &key_type[i]; \
66 ptr_sort_key[i].index_ = i; \
niklase@google.com470e71d2011-07-07 08:21:2567 } \
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2468 qsort((SORT_KEY), (NUM_OF_ELEMENTS), sizeof(SortKey), (COMPARE_FUNC)); \
69 } while(0)
niklase@google.com470e71d2011-07-07 08:21:2570#endif
71
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2472namespace webrtc {
73
niklase@google.com470e71d2011-07-07 08:21:2574#ifdef NO_STL
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2475struct SortKey {
76 void* key_;
pbos@webrtc.org046deb92013-04-09 09:06:1177 uint32_t index_;
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2478};
niklase@google.com470e71d2011-07-07 08:21:2579#else
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2480template<typename KeyType>
81struct SortKey {
82 KeyType key_;
pbos@webrtc.org046deb92013-04-09 09:06:1183 uint32_t index_;
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2484};
niklase@google.com470e71d2011-07-07 08:21:2585#endif
86
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2487namespace { // Unnamed namespace provides internal linkage.
88
niklase@google.com470e71d2011-07-07 08:21:2589#ifdef NO_STL
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2490int CompareWord8(const void* x, const void* y) {
pbos@webrtc.org046deb92013-04-09 09:06:1191 COMPARE_FOR_QSORT(x, y, int8_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2492}
niklase@google.com470e71d2011-07-07 08:21:2593
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2494int CompareUWord8(const void* x, const void* y) {
pbos@webrtc.org046deb92013-04-09 09:06:1195 COMPARE_FOR_QSORT(x, y, uint8_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2496}
niklase@google.com470e71d2011-07-07 08:21:2597
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:2498int CompareWord16(const void* x, const void* y) {
pbos@webrtc.org046deb92013-04-09 09:06:1199 COMPARE_FOR_QSORT(x, y, int16_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24100}
niklase@google.com470e71d2011-07-07 08:21:25101
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24102int CompareUWord16(const void* x, const void* y) {
pbos@webrtc.org046deb92013-04-09 09:06:11103 COMPARE_FOR_QSORT(x, y, uint16_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24104}
niklase@google.com470e71d2011-07-07 08:21:25105
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24106int CompareWord32(const void* x, const void* y) {
pbos@webrtc.org046deb92013-04-09 09:06:11107 COMPARE_FOR_QSORT(x, y, int32_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24108}
niklase@google.com470e71d2011-07-07 08:21:25109
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24110int CompareUWord32(const void* x, const void* y) {
pbos@webrtc.org046deb92013-04-09 09:06:11111 COMPARE_FOR_QSORT(x, y, uint32_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24112}
niklase@google.com470e71d2011-07-07 08:21:25113
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24114int CompareWord64(const void* x, const void* y) {
pbos@webrtc.org046deb92013-04-09 09:06:11115 COMPARE_FOR_QSORT(x, y, int64_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24116}
niklase@google.com470e71d2011-07-07 08:21:25117
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24118int CompareUWord64(const void* x, const void* y) {
pbos@webrtc.org046deb92013-04-09 09:06:11119 COMPARE_FOR_QSORT(x, y, uint64_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24120}
niklase@google.com470e71d2011-07-07 08:21:25121
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24122int CompareFloat32(const void* x, const void* y) {
123 COMPARE_FOR_QSORT(x, y, float);
124}
niklase@google.com470e71d2011-07-07 08:21:25125
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24126int CompareFloat64(const void* x, const void* y) {
127 COMPARE_FOR_QSORT(x, y, double);
128}
niklase@google.com470e71d2011-07-07 08:21:25129
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24130int CompareKeyWord8(const void* sort_key_x, const void* sort_key_y) {
pbos@webrtc.org046deb92013-04-09 09:06:11131 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, int8_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24132}
niklase@google.com470e71d2011-07-07 08:21:25133
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24134int CompareKeyUWord8(const void* sort_key_x, const void* sort_key_y) {
pbos@webrtc.org046deb92013-04-09 09:06:11135 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, uint8_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24136}
niklase@google.com470e71d2011-07-07 08:21:25137
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24138int CompareKeyWord16(const void* sort_key_x, const void* sort_key_y) {
pbos@webrtc.org046deb92013-04-09 09:06:11139 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, int16_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24140}
niklase@google.com470e71d2011-07-07 08:21:25141
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24142int CompareKeyUWord16(const void* sort_key_x, const void* sort_key_y) {
pbos@webrtc.org046deb92013-04-09 09:06:11143 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, uint16_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24144}
niklase@google.com470e71d2011-07-07 08:21:25145
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24146int CompareKeyWord32(const void* sort_key_x, const void* sort_key_y) {
pbos@webrtc.org046deb92013-04-09 09:06:11147 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, int32_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24148}
niklase@google.com470e71d2011-07-07 08:21:25149
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24150int CompareKeyUWord32(const void* sort_key_x, const void* sort_key_y) {
pbos@webrtc.org046deb92013-04-09 09:06:11151 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, uint32_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24152}
niklase@google.com470e71d2011-07-07 08:21:25153
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24154int CompareKeyWord64(const void* sort_key_x, const void* sort_key_y) {
pbos@webrtc.org046deb92013-04-09 09:06:11155 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, int64_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24156}
niklase@google.com470e71d2011-07-07 08:21:25157
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24158int CompareKeyUWord64(const void* sort_key_x, const void* sort_key_y) {
pbos@webrtc.org046deb92013-04-09 09:06:11159 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, uint64_t);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24160}
niklase@google.com470e71d2011-07-07 08:21:25161
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24162int CompareKeyFloat32(const void* sort_key_x, const void* sort_key_y) {
163 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, float);
164}
niklase@google.com470e71d2011-07-07 08:21:25165
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24166int CompareKeyFloat64(const void* sort_key_x, const void* sort_key_y) {
167 COMPARE_KEY_FOR_QSORT(sort_key_x, sort_key_y, double);
168}
niklase@google.com470e71d2011-07-07 08:21:25169#else
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24170template <typename KeyType>
171struct KeyLessThan {
172 bool operator()(const SortKey<KeyType>& sort_key_x,
173 const SortKey<KeyType>& sort_key_y) const {
174 return sort_key_x.key_ < sort_key_y.key_;
175 }
176};
niklase@google.com470e71d2011-07-07 08:21:25177
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24178template <typename KeyType>
179struct KeyRightShift {
180 KeyType operator()(const SortKey<KeyType>& sort_key,
181 const unsigned offset) const {
182 return sort_key.key_ >> offset;
183 }
184};
niklase@google.com470e71d2011-07-07 08:21:25185
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24186template <typename DataType>
pbos@webrtc.org046deb92013-04-09 09:06:11187inline void IntegerSort(void* data, uint32_t num_of_elements) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24188 DataType* data_type = static_cast<DataType*>(data);
189 boost::integer_sort(data_type, data_type + num_of_elements);
190}
niklase@google.com470e71d2011-07-07 08:21:25191
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24192template <typename DataType, typename IntegerType>
pbos@webrtc.org046deb92013-04-09 09:06:11193inline void FloatSort(void* data, uint32_t num_of_elements) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24194 DataType* data_type = static_cast<DataType*>(data);
195 IntegerType c_val = 0;
196 boost::float_sort_cast(data_type, data_type + num_of_elements, c_val);
197}
niklase@google.com470e71d2011-07-07 08:21:25198
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24199template <typename DataType>
pbos@webrtc.org046deb92013-04-09 09:06:11200inline void StdSort(void* data, uint32_t num_of_elements) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24201 DataType* data_type = static_cast<DataType*>(data);
202 std::sort(data_type, data_type + num_of_elements);
203}
niklase@google.com470e71d2011-07-07 08:21:25204
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24205template<typename KeyType>
pbos@webrtc.org046deb92013-04-09 09:06:11206inline int32_t SetupKeySort(void* key,
207 SortKey<KeyType>*& ptr_sort_key,
208 uint32_t num_of_elements) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24209 ptr_sort_key = new(std::nothrow) SortKey<KeyType>[num_of_elements];
210 if (ptr_sort_key == NULL) {
211 return -1;
212 }
niklase@google.com470e71d2011-07-07 08:21:25213
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24214 KeyType* key_type = static_cast<KeyType*>(key);
pbos@webrtc.org046deb92013-04-09 09:06:11215 for (uint32_t i = 0; i < num_of_elements; i++) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24216 ptr_sort_key[i].key_ = key_type[i];
217 ptr_sort_key[i].index_ = i;
218 }
niklase@google.com470e71d2011-07-07 08:21:25219
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24220 return 0;
221}
niklase@google.com470e71d2011-07-07 08:21:25222
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24223template<typename KeyType>
pbos@webrtc.org046deb92013-04-09 09:06:11224inline int32_t TeardownKeySort(void* data,
225 SortKey<KeyType>* ptr_sort_key,
226 uint32_t num_of_elements,
227 uint32_t size_of_element) {
228 uint8_t* ptr_data = static_cast<uint8_t*>(data);
229 uint8_t* ptr_data_sorted =
230 new(std::nothrow) uint8_t[num_of_elements * size_of_element];
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24231 if (ptr_data_sorted == NULL) {
232 return -1;
233 }
niklase@google.com470e71d2011-07-07 08:21:25234
pbos@webrtc.org046deb92013-04-09 09:06:11235 for (uint32_t i = 0; i < num_of_elements; i++) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24236 memcpy(ptr_data_sorted + i * size_of_element, ptr_data +
237 ptr_sort_key[i].index_ * size_of_element, size_of_element);
238 }
239 memcpy(ptr_data, ptr_data_sorted, num_of_elements * size_of_element);
240 delete[] ptr_sort_key;
241 delete[] ptr_data_sorted;
242 return 0;
243}
niklase@google.com470e71d2011-07-07 08:21:25244
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24245template<typename KeyType>
pbos@webrtc.org046deb92013-04-09 09:06:11246inline int32_t IntegerKeySort(void* data, void* key,
247 uint32_t num_of_elements,
248 uint32_t size_of_element) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24249 SortKey<KeyType>* ptr_sort_key;
250 if (SetupKeySort<KeyType>(key, ptr_sort_key, num_of_elements) != 0) {
251 return -1;
252 }
niklase@google.com470e71d2011-07-07 08:21:25253
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24254 boost::integer_sort(ptr_sort_key, ptr_sort_key + num_of_elements,
255 KeyRightShift<KeyType>(), KeyLessThan<KeyType>());
niklase@google.com470e71d2011-07-07 08:21:25256
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24257 if (TeardownKeySort<KeyType>(data, ptr_sort_key, num_of_elements,
258 size_of_element) != 0) {
259 return -1;
260 }
niklase@google.com470e71d2011-07-07 08:21:25261
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24262 return 0;
263}
niklase@google.com470e71d2011-07-07 08:21:25264
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24265template<typename KeyType>
pbos@webrtc.org046deb92013-04-09 09:06:11266inline int32_t StdKeySort(void* data, void* key,
267 uint32_t num_of_elements,
268 uint32_t size_of_element) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24269 SortKey<KeyType>* ptr_sort_key;
270 if (SetupKeySort<KeyType>(key, ptr_sort_key, num_of_elements) != 0) {
271 return -1;
272 }
niklase@google.com470e71d2011-07-07 08:21:25273
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24274 std::sort(ptr_sort_key, ptr_sort_key + num_of_elements,
275 KeyLessThan<KeyType>());
niklase@google.com470e71d2011-07-07 08:21:25276
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24277 if (TeardownKeySort<KeyType>(data, ptr_sort_key, num_of_elements,
278 size_of_element) != 0) {
279 return -1;
280 }
niklase@google.com470e71d2011-07-07 08:21:25281
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24282 return 0;
283}
niklase@google.com470e71d2011-07-07 08:21:25284#endif
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24285}
niklase@google.com470e71d2011-07-07 08:21:25286
pbos@webrtc.org046deb92013-04-09 09:06:11287int32_t Sort(void* data, uint32_t num_of_elements, Type type) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24288 if (data == NULL) {
289 return -1;
290 }
niklase@google.com470e71d2011-07-07 08:21:25291
292#ifdef NO_STL
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24293 switch (type) {
294 case TYPE_Word8:
pbos@webrtc.org046deb92013-04-09 09:06:11295 qsort(data, num_of_elements, sizeof(int8_t), CompareWord8);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24296 break;
297 case TYPE_UWord8:
pbos@webrtc.org046deb92013-04-09 09:06:11298 qsort(data, num_of_elements, sizeof(uint8_t), CompareUWord8);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24299 break;
300 case TYPE_Word16:
pbos@webrtc.org046deb92013-04-09 09:06:11301 qsort(data, num_of_elements, sizeof(int16_t), CompareWord16);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24302 break;
303 case TYPE_UWord16:
pbos@webrtc.org046deb92013-04-09 09:06:11304 qsort(data, num_of_elements, sizeof(uint16_t), CompareUWord16);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24305 break;
306 case TYPE_Word32:
pbos@webrtc.org046deb92013-04-09 09:06:11307 qsort(data, num_of_elements, sizeof(int32_t), CompareWord32);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24308 break;
309 case TYPE_UWord32:
pbos@webrtc.org046deb92013-04-09 09:06:11310 qsort(data, num_of_elements, sizeof(uint32_t), CompareUWord32);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24311 break;
312 case TYPE_Word64:
pbos@webrtc.org046deb92013-04-09 09:06:11313 qsort(data, num_of_elements, sizeof(int64_t), CompareWord64);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24314 break;
315 case TYPE_UWord64:
pbos@webrtc.org046deb92013-04-09 09:06:11316 qsort(data, num_of_elements, sizeof(uint64_t), CompareUWord64);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24317 break;
318 case TYPE_Float32:
319 qsort(data, num_of_elements, sizeof(float), CompareFloat32);
320 break;
321 case TYPE_Float64:
322 qsort(data, num_of_elements, sizeof(double), CompareFloat64);
323 break;
324 default:
325 return -1;
326 }
niklase@google.com470e71d2011-07-07 08:21:25327#else
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24328 // Fall back to std::sort for 64-bit types and floats due to compiler
329 // warnings and VS 2003 build crashes respectively with spreadsort.
330 switch (type) {
331 case TYPE_Word8:
pbos@webrtc.org046deb92013-04-09 09:06:11332 IntegerSort<int8_t>(data, num_of_elements);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24333 break;
334 case TYPE_UWord8:
pbos@webrtc.org046deb92013-04-09 09:06:11335 IntegerSort<uint8_t>(data, num_of_elements);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24336 break;
337 case TYPE_Word16:
pbos@webrtc.org046deb92013-04-09 09:06:11338 IntegerSort<int16_t>(data, num_of_elements);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24339 break;
340 case TYPE_UWord16:
pbos@webrtc.org046deb92013-04-09 09:06:11341 IntegerSort<uint16_t>(data, num_of_elements);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24342 break;
343 case TYPE_Word32:
pbos@webrtc.org046deb92013-04-09 09:06:11344 IntegerSort<int32_t>(data, num_of_elements);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24345 break;
346 case TYPE_UWord32:
pbos@webrtc.org046deb92013-04-09 09:06:11347 IntegerSort<uint32_t>(data, num_of_elements);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24348 break;
349 case TYPE_Word64:
pbos@webrtc.org046deb92013-04-09 09:06:11350 StdSort<int64_t>(data, num_of_elements);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24351 break;
352 case TYPE_UWord64:
pbos@webrtc.org046deb92013-04-09 09:06:11353 StdSort<uint64_t>(data, num_of_elements);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24354 break;
355 case TYPE_Float32:
356 StdSort<float>(data, num_of_elements);
357 break;
358 case TYPE_Float64:
359 StdSort<double>(data, num_of_elements);
360 break;
361 }
niklase@google.com470e71d2011-07-07 08:21:25362#endif
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24363 return 0;
364}
niklase@google.com470e71d2011-07-07 08:21:25365
pbos@webrtc.org046deb92013-04-09 09:06:11366int32_t KeySort(void* data, void* key, uint32_t num_of_elements,
367 uint32_t size_of_element, Type key_type) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24368 if (data == NULL) {
369 return -1;
370 }
niklase@google.com470e71d2011-07-07 08:21:25371
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24372 if (key == NULL) {
373 return -1;
374 }
niklase@google.com470e71d2011-07-07 08:21:25375
pbos@webrtc.org046deb92013-04-09 09:06:11376 if ((uint64_t)num_of_elements * size_of_element > 0xffffffff) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24377 return -1;
378 }
niklase@google.com470e71d2011-07-07 08:21:25379
380#ifdef NO_STL
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24381 SortKey* ptr_sort_key = new(std::nothrow) SortKey[num_of_elements];
382 if (ptr_sort_key == NULL) {
383 return -1;
384 }
niklase@google.com470e71d2011-07-07 08:21:25385
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24386 switch (key_type) {
387 case TYPE_Word8:
pbos@webrtc.org046deb92013-04-09 09:06:11388 KEY_QSORT(ptr_sort_key, key, num_of_elements, int8_t,
niklase@google.com470e71d2011-07-07 08:21:25389 CompareKeyWord8);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24390 break;
391 case TYPE_UWord8:
pbos@webrtc.org046deb92013-04-09 09:06:11392 KEY_QSORT(ptr_sort_key, key, num_of_elements, uint8_t,
niklase@google.com470e71d2011-07-07 08:21:25393 CompareKeyUWord8);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24394 break;
395 case TYPE_Word16:
pbos@webrtc.org046deb92013-04-09 09:06:11396 KEY_QSORT(ptr_sort_key, key, num_of_elements, int16_t,
niklase@google.com470e71d2011-07-07 08:21:25397 CompareKeyWord16);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24398 break;
399 case TYPE_UWord16:
pbos@webrtc.org046deb92013-04-09 09:06:11400 KEY_QSORT(ptr_sort_key, key, num_of_elements, uint16_t,
niklase@google.com470e71d2011-07-07 08:21:25401 CompareKeyUWord16);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24402 break;
403 case TYPE_Word32:
pbos@webrtc.org046deb92013-04-09 09:06:11404 KEY_QSORT(ptr_sort_key, key, num_of_elements, int32_t,
niklase@google.com470e71d2011-07-07 08:21:25405 CompareKeyWord32);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24406 break;
407 case TYPE_UWord32:
pbos@webrtc.org046deb92013-04-09 09:06:11408 KEY_QSORT(ptr_sort_key, key, num_of_elements, uint32_t,
niklase@google.com470e71d2011-07-07 08:21:25409 CompareKeyUWord32);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24410 break;
411 case TYPE_Word64:
pbos@webrtc.org046deb92013-04-09 09:06:11412 KEY_QSORT(ptr_sort_key, key, num_of_elements, int64_t,
niklase@google.com470e71d2011-07-07 08:21:25413 CompareKeyWord64);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24414 break;
415 case TYPE_UWord64:
pbos@webrtc.org046deb92013-04-09 09:06:11416 KEY_QSORT(ptr_sort_key, key, num_of_elements, uint64_t,
niklase@google.com470e71d2011-07-07 08:21:25417 CompareKeyUWord64);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24418 break;
419 case TYPE_Float32:
420 KEY_QSORT(ptr_sort_key, key, num_of_elements, float,
niklase@google.com470e71d2011-07-07 08:21:25421 CompareKeyFloat32);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24422 break;
423 case TYPE_Float64:
424 KEY_QSORT(ptr_sort_key, key, num_of_elements, double,
niklase@google.com470e71d2011-07-07 08:21:25425 CompareKeyFloat64);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24426 break;
427 default:
428 return -1;
429 }
niklase@google.com470e71d2011-07-07 08:21:25430
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24431 // Shuffle into sorted position based on index map.
pbos@webrtc.org046deb92013-04-09 09:06:11432 uint8_t* ptr_data = static_cast<uint8_t*>(data);
433 uint8_t* ptr_data_sorted =
434 new(std::nothrow) uint8_t[num_of_elements * size_of_element];
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24435 if (ptr_data_sorted == NULL) {
436 return -1;
437 }
niklase@google.com470e71d2011-07-07 08:21:25438
pbos@webrtc.org046deb92013-04-09 09:06:11439 for (uint32_t i = 0; i < num_of_elements; i++) {
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24440 memcpy(ptr_data_sorted + i * size_of_element, ptr_data +
441 ptr_sort_key[i].index_ * size_of_element, size_of_element);
442 }
443 memcpy(ptr_data, ptr_data_sorted, num_of_elements * size_of_element);
niklase@google.com470e71d2011-07-07 08:21:25444
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24445 delete[] ptr_sort_key;
446 delete[] ptr_data_sorted;
niklase@google.com470e71d2011-07-07 08:21:25447
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24448 return 0;
niklase@google.com470e71d2011-07-07 08:21:25449#else
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24450 // Fall back to std::sort for 64-bit types and floats due to compiler
451 // warnings and errors respectively with spreadsort.
452 switch (key_type) {
453 case TYPE_Word8:
pbos@webrtc.org046deb92013-04-09 09:06:11454 return IntegerKeySort<int8_t>(data, key, num_of_elements,
455 size_of_element);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24456 case TYPE_UWord8:
pbos@webrtc.org046deb92013-04-09 09:06:11457 return IntegerKeySort<uint8_t>(data, key, num_of_elements,
458 size_of_element);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24459 case TYPE_Word16:
pbos@webrtc.org046deb92013-04-09 09:06:11460 return IntegerKeySort<int16_t>(data, key, num_of_elements,
461 size_of_element);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24462 case TYPE_UWord16:
pbos@webrtc.org046deb92013-04-09 09:06:11463 return IntegerKeySort<uint16_t>(data, key, num_of_elements,
464 size_of_element);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24465 case TYPE_Word32:
pbos@webrtc.org046deb92013-04-09 09:06:11466 return IntegerKeySort<int32_t>(data, key, num_of_elements,
467 size_of_element);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24468 case TYPE_UWord32:
pbos@webrtc.org046deb92013-04-09 09:06:11469 return IntegerKeySort<uint32_t>(data, key, num_of_elements,
470 size_of_element);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24471 case TYPE_Word64:
pbos@webrtc.org046deb92013-04-09 09:06:11472 return StdKeySort<int64_t>(data, key, num_of_elements,
473 size_of_element);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24474 case TYPE_UWord64:
pbos@webrtc.org046deb92013-04-09 09:06:11475 return StdKeySort<uint64_t>(data, key, num_of_elements,
476 size_of_element);
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24477 case TYPE_Float32:
478 return StdKeySort<float>(data, key, num_of_elements, size_of_element);
479 case TYPE_Float64:
480 return StdKeySort<double>(data, key, num_of_elements, size_of_element);
481 }
482 assert(false);
483 return -1;
niklase@google.com470e71d2011-07-07 08:21:25484#endif
phoglund@webrtc.org6bc5d4d2012-12-19 14:55:24485}
486
pbos@webrtc.orgd900e8b2013-07-03 15:12:26487} // namespace webrtc