1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "mozilla/Assertions.h"
8 #include "mozilla/EndianUtils.h"
9
10 #include <stddef.h>
11
12 using mozilla::BigEndian;
13 using mozilla::LittleEndian;
14 using mozilla::NativeEndian;
15
16 template<typename T>
17 void
TestSingleSwap(T aValue,T aSwappedValue)18 TestSingleSwap(T aValue, T aSwappedValue)
19 {
20 #if MOZ_LITTLE_ENDIAN
21 MOZ_RELEASE_ASSERT(NativeEndian::swapToBigEndian(aValue) == aSwappedValue);
22 MOZ_RELEASE_ASSERT(NativeEndian::swapFromBigEndian(aValue) == aSwappedValue);
23 MOZ_RELEASE_ASSERT(NativeEndian::swapToNetworkOrder(aValue) == aSwappedValue);
24 MOZ_RELEASE_ASSERT(NativeEndian::swapFromNetworkOrder(aValue) ==
25 aSwappedValue);
26 #else
27 MOZ_RELEASE_ASSERT(NativeEndian::swapToLittleEndian(aValue) == aSwappedValue);
28 MOZ_RELEASE_ASSERT(NativeEndian::swapFromLittleEndian(aValue) ==
29 aSwappedValue);
30 #endif
31 }
32
33 template<typename T>
34 void
TestSingleNoSwap(T aValue,T aUnswappedValue)35 TestSingleNoSwap(T aValue, T aUnswappedValue)
36 {
37 #if MOZ_LITTLE_ENDIAN
38 MOZ_RELEASE_ASSERT(NativeEndian::swapToLittleEndian(aValue) ==
39 aUnswappedValue);
40 MOZ_RELEASE_ASSERT(NativeEndian::swapFromLittleEndian(aValue) ==
41 aUnswappedValue);
42 #else
43 MOZ_RELEASE_ASSERT(NativeEndian::swapToBigEndian(aValue) == aUnswappedValue);
44 MOZ_RELEASE_ASSERT(NativeEndian::swapFromBigEndian(aValue) == aUnswappedValue);
45 MOZ_RELEASE_ASSERT(NativeEndian::swapToNetworkOrder(aValue) ==
46 aUnswappedValue);
47 MOZ_RELEASE_ASSERT(NativeEndian::swapFromNetworkOrder(aValue) ==
48 aUnswappedValue);
49 #endif
50 }
51
52 // EndianUtils.h functions are declared as protected in a base class and
53 // then re-exported as public in public derived classes. The
54 // standardese around explicit instantiation of templates is not clear
55 // in such cases. Provide these wrappers to make things more explicit.
56 // For your own enlightenment, you may wish to peruse:
57 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56152 and subsequently
58 // http://j.mp/XosS6S .
59 #define WRAP_COPYTO(NAME) \
60 template<typename T> \
61 void \
62 NAME(void* aDst, const T* aSrc, size_t aCount) \
63 { \
64 NativeEndian::NAME<T>(aDst, aSrc, aCount); \
65 }
66
67 WRAP_COPYTO(copyAndSwapToLittleEndian)
68 WRAP_COPYTO(copyAndSwapToBigEndian)
69 WRAP_COPYTO(copyAndSwapToNetworkOrder)
70
71 #define WRAP_COPYFROM(NAME) \
72 template<typename T> \
73 void \
74 NAME(T* aDst, const void* aSrc, size_t aCount) \
75 { \
76 NativeEndian::NAME<T>(aDst, aSrc, aCount); \
77 }
78
79 WRAP_COPYFROM(copyAndSwapFromLittleEndian)
80 WRAP_COPYFROM(copyAndSwapFromBigEndian)
81 WRAP_COPYFROM(copyAndSwapFromNetworkOrder)
82
83 #define WRAP_IN_PLACE(NAME) \
84 template<typename T> \
85 void \
86 NAME(T* aP, size_t aCount) \
87 { \
88 NativeEndian::NAME<T>(aP, aCount); \
89 }
90 WRAP_IN_PLACE(swapToLittleEndianInPlace)
91 WRAP_IN_PLACE(swapFromLittleEndianInPlace)
92 WRAP_IN_PLACE(swapToBigEndianInPlace)
93 WRAP_IN_PLACE(swapFromBigEndianInPlace)
94 WRAP_IN_PLACE(swapToNetworkOrderInPlace)
95 WRAP_IN_PLACE(swapFromNetworkOrderInPlace)
96
97 enum SwapExpectation
98 {
99 Swap,
100 NoSwap
101 };
102
103 template<typename T, size_t Count>
104 void
TestBulkSwapToSub(enum SwapExpectation aExpectSwap,const T (& aValues)[Count],void (* aSwapperFunc)(void *,const T *,size_t),T (* aReaderFunc)(const void *))105 TestBulkSwapToSub(enum SwapExpectation aExpectSwap,
106 const T (&aValues)[Count],
107 void (*aSwapperFunc)(void*, const T*, size_t),
108 T (*aReaderFunc)(const void*))
109 {
110 const size_t arraySize = 2 * Count;
111 const size_t bufferSize = arraySize * sizeof(T);
112 static uint8_t buffer[bufferSize];
113 const uint8_t fillValue = 0xa5;
114 static uint8_t checkBuffer[bufferSize];
115
116 MOZ_RELEASE_ASSERT(bufferSize > 2 * sizeof(T));
117
118 memset(checkBuffer, fillValue, bufferSize);
119
120 for (size_t startPosition = 0; startPosition < sizeof(T); ++startPosition) {
121 for (size_t nValues = 0; nValues < Count; ++nValues) {
122 memset(buffer, fillValue, bufferSize);
123 aSwapperFunc(buffer + startPosition, aValues, nValues);
124
125 MOZ_RELEASE_ASSERT(memcmp(buffer, checkBuffer, startPosition) == 0);
126 size_t valuesEndPosition = startPosition + sizeof(T) * nValues;
127 MOZ_RELEASE_ASSERT(memcmp(buffer + valuesEndPosition,
128 checkBuffer + valuesEndPosition,
129 bufferSize - valuesEndPosition) == 0);
130 if (aExpectSwap == NoSwap) {
131 MOZ_RELEASE_ASSERT(memcmp(buffer + startPosition, aValues,
132 nValues * sizeof(T)) == 0);
133 }
134 for (size_t i = 0; i < nValues; ++i) {
135 MOZ_RELEASE_ASSERT(
136 aReaderFunc(buffer + startPosition + sizeof(T) * i) == aValues[i]);
137 }
138 }
139 }
140 }
141
142 template<typename T, size_t Count>
143 void
TestBulkSwapFromSub(enum SwapExpectation aExpectSwap,const T (& aValues)[Count],void (* aSwapperFunc)(T *,const void *,size_t),T (* aReaderFunc)(const void *))144 TestBulkSwapFromSub(enum SwapExpectation aExpectSwap,
145 const T (&aValues)[Count],
146 void (*aSwapperFunc)(T*, const void*, size_t),
147 T (*aReaderFunc)(const void*))
148 {
149 const size_t arraySize = 2 * Count;
150 const size_t bufferSize = arraySize * sizeof(T);
151 static T buffer[arraySize];
152 const uint8_t fillValue = 0xa5;
153 static T checkBuffer[arraySize];
154
155 memset(checkBuffer, fillValue, bufferSize);
156
157 for (size_t startPosition = 0; startPosition < Count; ++startPosition) {
158 for (size_t nValues = 0; nValues < (Count - startPosition); ++nValues) {
159 memset(buffer, fillValue, bufferSize);
160 aSwapperFunc(buffer + startPosition, aValues, nValues);
161
162 MOZ_RELEASE_ASSERT(
163 memcmp(buffer, checkBuffer, startPosition * sizeof(T)) == 0);
164 size_t valuesEndPosition = startPosition + nValues;
165 MOZ_RELEASE_ASSERT(memcmp(buffer + valuesEndPosition,
166 checkBuffer + valuesEndPosition,
167 (arraySize - valuesEndPosition) * sizeof(T)) == 0);
168 if (aExpectSwap == NoSwap) {
169 MOZ_RELEASE_ASSERT(memcmp(buffer + startPosition, aValues,
170 nValues * sizeof(T)) == 0);
171 }
172 for (size_t i = 0; i < nValues; ++i) {
173 MOZ_RELEASE_ASSERT(aReaderFunc(buffer + startPosition + i) == aValues[i]);
174 }
175 }
176 }
177 }
178
179
180 template<typename T, size_t Count>
181 void
TestBulkInPlaceSub(enum SwapExpectation aExpectSwap,const T (& aValues)[Count],void (* aSwapperFunc)(T *,size_t),T (* aReaderFunc)(const void *))182 TestBulkInPlaceSub(enum SwapExpectation aExpectSwap,
183 const T (&aValues)[Count],
184 void (*aSwapperFunc)(T*, size_t),
185 T (*aReaderFunc)(const void*))
186 {
187 const size_t bufferCount = 4 * Count;
188 const size_t bufferSize = bufferCount * sizeof(T);
189 static T buffer[bufferCount];
190 const T fillValue = 0xa5;
191 static T checkBuffer[bufferCount];
192
193 MOZ_RELEASE_ASSERT(bufferSize > 2 * sizeof(T));
194
195 memset(checkBuffer, fillValue, bufferSize);
196
197 for (size_t startPosition = 0; startPosition < Count; ++startPosition) {
198 for (size_t nValues = 0; nValues < Count; ++nValues) {
199 memset(buffer, fillValue, bufferSize);
200 memcpy(buffer + startPosition, aValues, nValues * sizeof(T));
201 aSwapperFunc(buffer + startPosition, nValues);
202
203 MOZ_RELEASE_ASSERT(
204 memcmp(buffer, checkBuffer, startPosition * sizeof(T)) == 0);
205 size_t valuesEndPosition = startPosition + nValues;
206 MOZ_RELEASE_ASSERT(memcmp(buffer + valuesEndPosition,
207 checkBuffer + valuesEndPosition,
208 bufferSize - valuesEndPosition * sizeof(T)) == 0);
209 if (aExpectSwap == NoSwap) {
210 MOZ_RELEASE_ASSERT(memcmp(buffer + startPosition, aValues,
211 nValues * sizeof(T)) == 0);
212 }
213 for (size_t i = 0; i < nValues; ++i) {
214 MOZ_RELEASE_ASSERT(aReaderFunc(buffer + startPosition + i) == aValues[i]);
215 }
216 }
217 }
218 }
219
220 template<typename T>
221 struct Reader
222 {
223 };
224
225 #define SPECIALIZE_READER(TYPE, READ_FUNC) \
226 template<> \
227 struct Reader<TYPE> \
228 { \
229 static TYPE readLE(const void* aP) { return LittleEndian::READ_FUNC(aP); }\
230 static TYPE readBE(const void* aP) { return BigEndian::READ_FUNC(aP); } \
231 };
232
SPECIALIZE_READER(uint16_t,readUint16)233 SPECIALIZE_READER(uint16_t, readUint16)
234 SPECIALIZE_READER(uint32_t, readUint32)
235 SPECIALIZE_READER(uint64_t, readUint64)
236 SPECIALIZE_READER(int16_t, readInt16)
237 SPECIALIZE_READER(int32_t, readInt32)
238 SPECIALIZE_READER(int64_t, readInt64)
239
240 template<typename T, size_t Count>
241 void
242 TestBulkSwap(const T (&aBytes)[Count])
243 {
244 #if MOZ_LITTLE_ENDIAN
245 TestBulkSwapToSub(Swap, aBytes, copyAndSwapToBigEndian<T>,
246 Reader<T>::readBE);
247 TestBulkSwapFromSub(Swap, aBytes, copyAndSwapFromBigEndian<T>,
248 Reader<T>::readBE);
249 TestBulkSwapToSub(Swap, aBytes, copyAndSwapToNetworkOrder<T>,
250 Reader<T>::readBE);
251 TestBulkSwapFromSub(Swap, aBytes, copyAndSwapFromNetworkOrder<T>,
252 Reader<T>::readBE);
253 #else
254 TestBulkSwapToSub(Swap, aBytes, copyAndSwapToLittleEndian<T>,
255 Reader<T>::readLE);
256 TestBulkSwapFromSub(Swap, aBytes, copyAndSwapFromLittleEndian<T>,
257 Reader<T>::readLE);
258 #endif
259 }
260
261 template<typename T, size_t Count>
262 void
TestBulkNoSwap(const T (& aBytes)[Count])263 TestBulkNoSwap(const T (&aBytes)[Count])
264 {
265 #if MOZ_LITTLE_ENDIAN
266 TestBulkSwapToSub(NoSwap, aBytes, copyAndSwapToLittleEndian<T>,
267 Reader<T>::readLE);
268 TestBulkSwapFromSub(NoSwap, aBytes, copyAndSwapFromLittleEndian<T>,
269 Reader<T>::readLE);
270 #else
271 TestBulkSwapToSub(NoSwap, aBytes, copyAndSwapToBigEndian<T>,
272 Reader<T>::readBE);
273 TestBulkSwapFromSub(NoSwap, aBytes, copyAndSwapFromBigEndian<T>,
274 Reader<T>::readBE);
275 TestBulkSwapToSub(NoSwap, aBytes, copyAndSwapToNetworkOrder<T>,
276 Reader<T>::readBE);
277 TestBulkSwapFromSub(NoSwap, aBytes, copyAndSwapFromNetworkOrder<T>,
278 Reader<T>::readBE);
279 #endif
280 }
281
282 template<typename T, size_t Count>
283 void
TestBulkInPlaceSwap(const T (& aBytes)[Count])284 TestBulkInPlaceSwap(const T (&aBytes)[Count])
285 {
286 #if MOZ_LITTLE_ENDIAN
287 TestBulkInPlaceSub(Swap, aBytes, swapToBigEndianInPlace<T>,
288 Reader<T>::readBE);
289 TestBulkInPlaceSub(Swap, aBytes, swapFromBigEndianInPlace<T>,
290 Reader<T>::readBE);
291 TestBulkInPlaceSub(Swap, aBytes, swapToNetworkOrderInPlace<T>,
292 Reader<T>::readBE);
293 TestBulkInPlaceSub(Swap, aBytes, swapFromNetworkOrderInPlace<T>,
294 Reader<T>::readBE);
295 #else
296 TestBulkInPlaceSub(Swap, aBytes, swapToLittleEndianInPlace<T>,
297 Reader<T>::readLE);
298 TestBulkInPlaceSub(Swap, aBytes, swapFromLittleEndianInPlace<T>,
299 Reader<T>::readLE);
300 #endif
301 }
302
303 template<typename T, size_t Count>
304 void
TestBulkInPlaceNoSwap(const T (& aBytes)[Count])305 TestBulkInPlaceNoSwap(const T (&aBytes)[Count])
306 {
307 #if MOZ_LITTLE_ENDIAN
308 TestBulkInPlaceSub(NoSwap, aBytes, swapToLittleEndianInPlace<T>,
309 Reader<T>::readLE);
310 TestBulkInPlaceSub(NoSwap, aBytes, swapFromLittleEndianInPlace<T>,
311 Reader<T>::readLE);
312 #else
313 TestBulkInPlaceSub(NoSwap, aBytes, swapToBigEndianInPlace<T>,
314 Reader<T>::readBE);
315 TestBulkInPlaceSub(NoSwap, aBytes, swapFromBigEndianInPlace<T>,
316 Reader<T>::readBE);
317 TestBulkInPlaceSub(NoSwap, aBytes, swapToNetworkOrderInPlace<T>,
318 Reader<T>::readBE);
319 TestBulkInPlaceSub(NoSwap, aBytes, swapFromNetworkOrderInPlace<T>,
320 Reader<T>::readBE);
321 #endif
322 }
323
324 int
main()325 main()
326 {
327 static const uint8_t unsigned_bytes[16] = {
328 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
329 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8
330 };
331 static const int8_t signed_bytes[16] = {
332 -0x0f, -0x0e, -0x0d, -0x0c, -0x0b, -0x0a, -0x09, -0x08,
333 -0x0f, -0x0e, -0x0d, -0x0c, -0x0b, -0x0a, -0x09, -0x08
334 };
335 static const uint16_t uint16_values[8] = {
336 0x102, 0x304, 0x506, 0x708, 0x102, 0x304, 0x506, 0x708
337 };
338 static const int16_t int16_values[8] = {
339 int16_t(0xf1f2), int16_t(0xf3f4), int16_t(0xf5f6), int16_t(0xf7f8),
340 int16_t(0xf1f2), int16_t(0xf3f4), int16_t(0xf5f6), int16_t(0xf7f8)
341 };
342 static const uint32_t uint32_values[4] = {
343 0x1020304, 0x5060708, 0x1020304, 0x5060708
344 };
345 static const int32_t int32_values[4] = {
346 int32_t(0xf1f2f3f4), int32_t(0xf5f6f7f8),
347 int32_t(0xf1f2f3f4), int32_t(0xf5f6f7f8)
348 };
349 static const uint64_t uint64_values[2] = {
350 0x102030405060708, 0x102030405060708
351 };
352 static const int64_t int64_values[2] = {
353 int64_t(0xf1f2f3f4f5f6f7f8), int64_t(0xf1f2f3f4f5f6f7f8)
354 };
355 uint8_t buffer[8];
356
357 MOZ_RELEASE_ASSERT(LittleEndian::readUint16(&unsigned_bytes[0]) == 0x201);
358 MOZ_RELEASE_ASSERT(BigEndian::readUint16(&unsigned_bytes[0]) == 0x102);
359
360 MOZ_RELEASE_ASSERT(
361 LittleEndian::readUint32(&unsigned_bytes[0]) == 0x4030201U);
362 MOZ_RELEASE_ASSERT(
363 BigEndian::readUint32(&unsigned_bytes[0]) == 0x1020304U);
364
365 MOZ_RELEASE_ASSERT(
366 LittleEndian::readUint64(&unsigned_bytes[0]) == 0x807060504030201ULL);
367 MOZ_RELEASE_ASSERT(
368 BigEndian::readUint64(&unsigned_bytes[0]) == 0x102030405060708ULL);
369
370 LittleEndian::writeUint16(&buffer[0], 0x201);
371 MOZ_RELEASE_ASSERT(
372 memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint16_t)) == 0);
373 BigEndian::writeUint16(&buffer[0], 0x102);
374 MOZ_RELEASE_ASSERT(
375 memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint16_t)) == 0);
376
377 LittleEndian::writeUint32(&buffer[0], 0x4030201U);
378 MOZ_RELEASE_ASSERT(
379 memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint32_t)) == 0);
380 BigEndian::writeUint32(&buffer[0], 0x1020304U);
381 MOZ_RELEASE_ASSERT(
382 memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint32_t)) == 0);
383
384 LittleEndian::writeUint64(&buffer[0], 0x807060504030201ULL);
385 MOZ_RELEASE_ASSERT(
386 memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint64_t)) == 0);
387 BigEndian::writeUint64(&buffer[0], 0x102030405060708ULL);
388 MOZ_RELEASE_ASSERT(
389 memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint64_t)) == 0);
390
391 MOZ_RELEASE_ASSERT(
392 LittleEndian::readInt16(&signed_bytes[0]) == int16_t(0xf2f1));
393 MOZ_RELEASE_ASSERT(
394 BigEndian::readInt16(&signed_bytes[0]) == int16_t(0xf1f2));
395
396 MOZ_RELEASE_ASSERT(
397 LittleEndian::readInt32(&signed_bytes[0]) == int32_t(0xf4f3f2f1));
398 MOZ_RELEASE_ASSERT(
399 BigEndian::readInt32(&signed_bytes[0]) == int32_t(0xf1f2f3f4));
400
401 MOZ_RELEASE_ASSERT(
402 LittleEndian::readInt64(&signed_bytes[0]) == int64_t(0xf8f7f6f5f4f3f2f1LL));
403 MOZ_RELEASE_ASSERT(
404 BigEndian::readInt64(&signed_bytes[0]) == int64_t(0xf1f2f3f4f5f6f7f8LL));
405
406 LittleEndian::writeInt16(&buffer[0], int16_t(0xf2f1));
407 MOZ_RELEASE_ASSERT(
408 memcmp(&signed_bytes[0], &buffer[0], sizeof(int16_t)) == 0);
409 BigEndian::writeInt16(&buffer[0], int16_t(0xf1f2));
410 MOZ_RELEASE_ASSERT(
411 memcmp(&signed_bytes[0], &buffer[0], sizeof(int16_t)) == 0);
412
413 LittleEndian::writeInt32(&buffer[0], 0xf4f3f2f1);
414 MOZ_RELEASE_ASSERT(
415 memcmp(&signed_bytes[0], &buffer[0], sizeof(int32_t)) == 0);
416 BigEndian::writeInt32(&buffer[0], 0xf1f2f3f4);
417 MOZ_RELEASE_ASSERT(
418 memcmp(&signed_bytes[0], &buffer[0], sizeof(int32_t)) == 0);
419
420 LittleEndian::writeInt64(&buffer[0], 0xf8f7f6f5f4f3f2f1LL);
421 MOZ_RELEASE_ASSERT(
422 memcmp(&signed_bytes[0], &buffer[0], sizeof(int64_t)) == 0);
423 BigEndian::writeInt64(&buffer[0], 0xf1f2f3f4f5f6f7f8LL);
424 MOZ_RELEASE_ASSERT(
425 memcmp(&signed_bytes[0], &buffer[0], sizeof(int64_t)) == 0);
426
427 TestSingleSwap(uint16_t(0xf2f1), uint16_t(0xf1f2));
428 TestSingleSwap(uint32_t(0xf4f3f2f1), uint32_t(0xf1f2f3f4));
429 TestSingleSwap(uint64_t(0xf8f7f6f5f4f3f2f1), uint64_t(0xf1f2f3f4f5f6f7f8));
430
431 TestSingleSwap(int16_t(0xf2f1), int16_t(0xf1f2));
432 TestSingleSwap(int32_t(0xf4f3f2f1), int32_t(0xf1f2f3f4));
433 TestSingleSwap(int64_t(0xf8f7f6f5f4f3f2f1), int64_t(0xf1f2f3f4f5f6f7f8));
434
435 TestSingleNoSwap(uint16_t(0xf2f1), uint16_t(0xf2f1));
436 TestSingleNoSwap(uint32_t(0xf4f3f2f1), uint32_t(0xf4f3f2f1));
437 TestSingleNoSwap(uint64_t(0xf8f7f6f5f4f3f2f1), uint64_t(0xf8f7f6f5f4f3f2f1));
438
439 TestSingleNoSwap(int16_t(0xf2f1), int16_t(0xf2f1));
440 TestSingleNoSwap(int32_t(0xf4f3f2f1), int32_t(0xf4f3f2f1));
441 TestSingleNoSwap(int64_t(0xf8f7f6f5f4f3f2f1), int64_t(0xf8f7f6f5f4f3f2f1));
442
443 TestBulkSwap(uint16_values);
444 TestBulkSwap(int16_values);
445 TestBulkSwap(uint32_values);
446 TestBulkSwap(int32_values);
447 TestBulkSwap(uint64_values);
448 TestBulkSwap(int64_values);
449
450 TestBulkNoSwap(uint16_values);
451 TestBulkNoSwap(int16_values);
452 TestBulkNoSwap(uint32_values);
453 TestBulkNoSwap(int32_values);
454 TestBulkNoSwap(uint64_values);
455 TestBulkNoSwap(int64_values);
456
457 TestBulkInPlaceSwap(uint16_values);
458 TestBulkInPlaceSwap(int16_values);
459 TestBulkInPlaceSwap(uint32_values);
460 TestBulkInPlaceSwap(int32_values);
461 TestBulkInPlaceSwap(uint64_values);
462 TestBulkInPlaceSwap(int64_values);
463
464 TestBulkInPlaceNoSwap(uint16_values);
465 TestBulkInPlaceNoSwap(int16_values);
466 TestBulkInPlaceNoSwap(uint32_values);
467 TestBulkInPlaceNoSwap(int32_values);
468 TestBulkInPlaceNoSwap(uint64_values);
469 TestBulkInPlaceNoSwap(int64_values);
470
471 return 0;
472 }
473