1#![cfg_attr(not(feature = "std"), no_std)]
9#![cfg_attr(rustc_nightly, feature(doc_cfg))]
10
11#[cfg(target_arch = "x86")]
12use core::arch::x86::*;
13
14#[cfg(target_arch = "x86_64")]
15use core::arch::x86_64::*;
16
17use core::fmt::Debug;
18
19pub mod decode;
20pub mod encode;
21pub mod num;
22
23#[doc(inline)]
24pub use decode::*;
25#[doc(inline)]
26pub use encode::*;
27pub use num::*;
28
29#[allow(dead_code)]
31fn slice_m128i(n: __m128i) -> [u8; 16] {
32 unsafe { core::mem::transmute(n) }
33}
34
35#[allow(dead_code)]
36fn slice_m256i(n: __m256i) -> [i8; 32] {
37 unsafe { core::mem::transmute(n) }
38}
39
40#[derive(Debug, PartialEq, Eq)]
41pub enum VarIntDecodeError {
42 Overflow,
43 NotEnoughBytes,
44}
45
46impl core::fmt::Display for VarIntDecodeError {
47 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
48 core::fmt::Debug::fmt(self, f)
49 }
50}
51
52#[cfg(feature = "std")]
53impl std::error::Error for VarIntDecodeError {}
54
55#[cfg(test)]
56mod tests {
57 #[cfg(target_feature = "avx2")]
58 use crate::decode_two_wide_unsafe;
59 use crate::{
60 decode, decode_eight_u8_unsafe, decode_four_unsafe, decode_len, decode_two_unsafe, encode,
61 encode_to_slice, VarIntDecodeError, VarIntTarget,
62 };
63
64 use lazy_static::lazy_static;
65
66 #[test]
67 fn it_works() {
68 assert_eq!(2 + 2, 4);
69 }
70
71 fn check<T: VarIntTarget>(value: T, encoded: &[u8]) {
72 let mut expected = [0u8; 16];
73 expected[..encoded.len()].copy_from_slice(encoded);
74
75 let a = encode(value);
76 assert_eq!(a.0, expected);
77 assert_eq!(a.1 as usize, encoded.len());
78
79 let roundtrip: (T, usize) = decode(&expected).unwrap();
80 assert_eq!(roundtrip.0, value);
81 assert_eq!(roundtrip.1 as usize, encoded.len());
82
83 let len = decode_len::<T>(&expected).unwrap();
84 assert_eq!(len, encoded.len());
85 }
86
87 #[test]
90 fn roundtrip_u8() {
91 check(2u8.pow(0) - 1, &[0x00]);
92 check(2u8.pow(0), &[0x01]);
93
94 check(2u8.pow(7) - 1, &[0x7F]);
95 check(2u8.pow(7), &[0x80, 0x01]);
96 }
97
98 #[test]
99 fn roundtrip_u16() {
100 check(2u16.pow(0) - 1, &[0x00]);
101 check(2u16.pow(0), &[0x01]);
102
103 check(2u16.pow(7) - 1, &[0x7F]);
104 check(2u16.pow(7), &[0x80, 0x01]);
105 check(300u16, &[0xAC, 0x02]);
106
107 check(2u16.pow(14) - 1, &[0xFF, 0x7F]);
108 check(2u16.pow(14), &[0x80, 0x80, 0x01]);
109 }
110
111 #[test]
112 fn roundtrip_u32() {
113 check(2u32.pow(0) - 1, &[0x00]);
114 check(2u32.pow(0), &[0x01]);
115
116 check(2u32.pow(7) - 1, &[0x7F]);
117 check(2u32.pow(7), &[0x80, 0x01]);
118 check(300u32, &[0xAC, 0x02]);
119
120 check(2u32.pow(14) - 1, &[0xFF, 0x7F]);
121 check(2u32.pow(14), &[0x80, 0x80, 0x01]);
122
123 check(2u32.pow(21) - 1, &[0xFF, 0xFF, 0x7F]);
124 check(2u32.pow(21), &[0x80, 0x80, 0x80, 0x01]);
125
126 check(2u32.pow(28) - 1, &[0xFF, 0xFF, 0xFF, 0x7F]);
127 check(2u32.pow(28), &[0x80, 0x80, 0x80, 0x80, 0x01]);
128 }
129
130 #[test]
131 fn roundtrip_u64() {
132 check(2u64.pow(0) - 1, &[0x00]);
133 check(2u64.pow(0), &[0x01]);
134
135 check(2u64.pow(7) - 1, &[0x7F]);
136 check(2u64.pow(7), &[0x80, 0x01]);
137 check(300u64, &[0xAC, 0x02]);
138
139 check(2u64.pow(14) - 1, &[0xFF, 0x7F]);
140 check(2u64.pow(14), &[0x80, 0x80, 0x01]);
141
142 check(2u64.pow(21) - 1, &[0xFF, 0xFF, 0x7F]);
143 check(2u64.pow(21), &[0x80, 0x80, 0x80, 0x01]);
144
145 check(2u64.pow(28) - 1, &[0xFF, 0xFF, 0xFF, 0x7F]);
146 check(2u64.pow(28), &[0x80, 0x80, 0x80, 0x80, 0x01]);
147
148 check(2u64.pow(35) - 1, &[0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
149 check(2u64.pow(35), &[0x80, 0x80, 0x80, 0x80, 0x80, 0x01]);
150
151 check(2u64.pow(42) - 1, &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
152 check(2u64.pow(42), &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01]);
153
154 check(
155 2u64.pow(49) - 1,
156 &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F],
157 );
158 check(
159 2u64.pow(49),
160 &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01],
161 );
162
163 check(
164 2u64.pow(56) - 1,
165 &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F],
166 );
167 check(
168 2u64.pow(56),
169 &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01],
170 );
171
172 check(
173 2u64.pow(63) - 1,
174 &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F],
175 );
176 check(
177 2u64.pow(63),
178 &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01],
179 );
180
181 check(
182 u64::MAX,
183 &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01],
184 );
185 }
186
187 #[test]
188 fn overflow_u8() {
189 let encoded = encode(u8::MAX as u16 + 1);
190 decode::<u8>(&encoded.0).expect_err("should overflow");
191 }
192
193 #[test]
194 fn overflow_u16() {
195 let encoded = encode(u16::MAX as u32 + 1);
196 decode::<u16>(&encoded.0).expect_err("should overflow");
197 }
198
199 #[test]
200 fn overflow_u32() {
201 let encoded = encode(u32::MAX as u64 + 1);
202 decode::<u32>(&encoded.0).expect_err("should overflow");
203 }
204
205 #[test]
206 fn overflow_u64() {
207 decode::<u8>(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02])
208 .expect_err("should overflow");
209 }
210
211 #[test]
212 fn truncated() {
213 for i in 1..10 {
214 let encoded = encode(1u64 << 7 * i);
215 for j in 0..=i {
216 assert_eq!(
217 decode::<u64>(&encoded.0[..j]),
218 Err(VarIntDecodeError::NotEnoughBytes)
219 );
220 }
221 }
222 }
223
224 fn check_decode_2x<T: VarIntTarget, U: VarIntTarget>(a: &[T], b: &[U]) {
225 for i in a {
226 for j in b {
227 let mut enc = [0u8; 16];
228
229 let first_len = encode_to_slice(*i, &mut enc);
230 let second_len = encode_to_slice(*j, &mut enc[first_len as usize..]);
231
232 let decoded = unsafe { decode_two_unsafe::<T, U>(enc.as_ptr()) };
233 assert_eq!(decoded.0, *i);
234 assert_eq!(decoded.1, *j);
235 assert_eq!(decoded.2, first_len);
236 assert_eq!(decoded.3, second_len);
237 }
238 }
239 }
240
241 #[cfg(target_feature = "avx2")]
242 fn check_decode_wide_2x<T: VarIntTarget, U: VarIntTarget>(a: &[T], b: &[U]) {
243 for i in a {
244 for j in b {
245 let mut enc = [0u8; 32];
246
247 let first_len = encode_to_slice(*i, &mut enc);
248 let second_len = encode_to_slice(*j, &mut enc[first_len as usize..]);
249
250 let decoded = unsafe { decode_two_wide_unsafe::<T, U>(enc.as_ptr()) };
251 assert_eq!(decoded.0, *i);
252 assert_eq!(decoded.1, *j);
253 assert_eq!(decoded.2, first_len);
254 assert_eq!(decoded.3, second_len);
255 }
256 }
257 }
258
259 fn check_decode_4x<T: VarIntTarget, U: VarIntTarget, V: VarIntTarget, W: VarIntTarget>(
260 a: &[T],
261 b: &[U],
262 c: &[V],
263 d: &[W],
264 ) {
265 for i in a {
266 for j in b {
267 for k in c {
268 for l in d {
269 let mut enc = [0u8; 16];
270
271 let first_len = encode_to_slice(*i, &mut enc);
272 let second_len = encode_to_slice(*j, &mut enc[first_len as usize..]);
273 let third_len =
274 encode_to_slice(*k, &mut enc[(first_len + second_len) as usize..]);
275 let fourth_len = encode_to_slice(
276 *l,
277 &mut enc[(first_len + second_len + third_len) as usize..],
278 );
279
280 let decoded = unsafe { decode_four_unsafe::<T, U, V, W>(enc.as_ptr()) };
281
282 assert_eq!(decoded.0, *i);
283 assert_eq!(decoded.1, *j);
284 assert_eq!(decoded.2, *k);
285 assert_eq!(decoded.3, *l);
286 assert_eq!(decoded.4, first_len);
287 assert_eq!(decoded.5, second_len);
288 assert_eq!(decoded.6, third_len);
289 assert_eq!(decoded.7, fourth_len);
290 assert!(!decoded.8);
291 }
292 }
293 }
294 }
295 }
296
297 lazy_static! {
298 static ref NUMS_U8: [u8; 5] = [
299 2u8.pow(0) - 1,
300 2u8.pow(0),
301 2u8.pow(7) - 1,
302 2u8.pow(7),
303 u8::MAX
304 ];
305 static ref NUMS_U16: [u16; 8] = [
306 2u16.pow(0) - 1,
307 2u16.pow(0),
308 2u16.pow(7) - 1,
309 2u16.pow(7),
310 300,
311 2u16.pow(14) - 1,
312 2u16.pow(14),
313 u16::MAX
314 ];
315 static ref NUMS_U32: [u32; 12] = [
316 2u32.pow(0) - 1,
317 2u32.pow(0),
318 2u32.pow(7) - 1,
319 2u32.pow(7),
320 300,
321 2u32.pow(14) - 1,
322 2u32.pow(14),
323 2u32.pow(21) - 1,
324 2u32.pow(21),
325 2u32.pow(28) - 1,
326 2u32.pow(28),
327 u32::MAX
328 ];
329 static ref NUMS_U64: [u64; 22] = [
330 2u64.pow(0) - 1,
331 2u64.pow(0),
332 2u64.pow(7) - 1,
333 2u64.pow(7),
334 300,
335 2u64.pow(14) - 1,
336 2u64.pow(14),
337 2u64.pow(21) - 1,
338 2u64.pow(21),
339 2u64.pow(28) - 1,
340 2u64.pow(28),
341 2u64.pow(35) - 1,
342 2u64.pow(35),
343 2u64.pow(42) - 1,
344 2u64.pow(42),
345 2u64.pow(49) - 1,
346 2u64.pow(49),
347 2u64.pow(56) - 1,
348 2u64.pow(56),
349 2u64.pow(63) - 1,
350 2u64.pow(63),
351 u64::MAX
352 ];
353 }
354
355 #[test]
356 fn test_decode_2x_u8_x() {
357 check_decode_2x::<u8, u8>(&NUMS_U8[..], &NUMS_U8[..]);
358 check_decode_2x::<u8, u16>(&NUMS_U8[..], &NUMS_U16[..]);
359 check_decode_2x::<u8, u32>(&NUMS_U8[..], &NUMS_U32[..]);
360 check_decode_2x::<u8, u64>(&NUMS_U8[..], &NUMS_U64[..]);
361 }
362
363 #[test]
364 #[cfg(target_feature = "avx2")]
365 fn test_decode_2x_wide_u8_x() {
366 check_decode_wide_2x::<u8, u8>(&NUMS_U8[..], &NUMS_U8[..]);
367 check_decode_wide_2x::<u8, u16>(&NUMS_U8[..], &NUMS_U16[..]);
368 check_decode_wide_2x::<u8, u32>(&NUMS_U8[..], &NUMS_U32[..]);
369 check_decode_wide_2x::<u8, u64>(&NUMS_U8[..], &NUMS_U64[..]);
370 }
371
372 #[test]
373 fn test_decode_2x_u16_x() {
374 check_decode_2x::<u16, u8>(&NUMS_U16[..], &NUMS_U8[..]);
375 check_decode_2x::<u16, u16>(&NUMS_U16[..], &NUMS_U16[..]);
376 check_decode_2x::<u16, u32>(&NUMS_U16[..], &NUMS_U32[..]);
377 check_decode_2x::<u16, u64>(&NUMS_U16[..], &NUMS_U64[..]);
378 }
379
380 #[test]
381 #[cfg(target_feature = "avx2")]
382 fn test_decode_2x_wide_u16_x() {
383 check_decode_wide_2x::<u16, u8>(&NUMS_U16[..], &NUMS_U8[..]);
384 check_decode_wide_2x::<u16, u16>(&NUMS_U16[..], &NUMS_U16[..]);
385 check_decode_wide_2x::<u16, u32>(&NUMS_U16[..], &NUMS_U32[..]);
386 check_decode_wide_2x::<u16, u64>(&NUMS_U16[..], &NUMS_U64[..]);
387 }
388
389 #[test]
390 fn test_decode_2x_u32_x() {
391 check_decode_2x::<u32, u8>(&NUMS_U32[..], &NUMS_U8[..]);
392 check_decode_2x::<u32, u16>(&NUMS_U32[..], &NUMS_U16[..]);
393 check_decode_2x::<u32, u32>(&NUMS_U32[..], &NUMS_U32[..]);
394 check_decode_2x::<u32, u64>(&NUMS_U32[..], &NUMS_U64[..]);
395 }
396
397 #[test]
398 #[cfg(target_feature = "avx2")]
399 fn test_decode_2x_wide_u32_x() {
400 check_decode_wide_2x::<u32, u8>(&NUMS_U32[..], &NUMS_U8[..]);
401 check_decode_wide_2x::<u32, u16>(&NUMS_U32[..], &NUMS_U16[..]);
402 check_decode_wide_2x::<u32, u32>(&NUMS_U32[..], &NUMS_U32[..]);
403 check_decode_wide_2x::<u32, u64>(&NUMS_U32[..], &NUMS_U64[..]);
404 }
405
406 #[test]
407 fn test_decode_2x_u64_x() {
408 check_decode_2x::<u64, u8>(&NUMS_U64[..], &NUMS_U8[..]);
409 check_decode_2x::<u64, u16>(&NUMS_U64[..], &NUMS_U16[..]);
410 check_decode_2x::<u64, u32>(&NUMS_U64[..], &NUMS_U32[..]);
411 }
413
414 #[test]
415 #[cfg(target_feature = "avx2")]
416 fn test_decode_2x_wide_u64_x() {
417 check_decode_wide_2x::<u64, u8>(&NUMS_U64[..], &NUMS_U8[..]);
418 check_decode_wide_2x::<u64, u16>(&NUMS_U64[..], &NUMS_U16[..]);
419 check_decode_wide_2x::<u64, u32>(&NUMS_U64[..], &NUMS_U32[..]);
420 check_decode_wide_2x::<u64, u64>(&NUMS_U64[..], &NUMS_U64[..]);
421 }
422
423 #[test]
424 fn test_decode_4x_u8_u8_x_x() {
425 check_decode_4x::<u8, u8, u8, u8>(&NUMS_U8[..], &NUMS_U8[..], &NUMS_U8[..], &NUMS_U8[..]);
426 check_decode_4x::<u8, u8, u8, u16>(&NUMS_U8[..], &NUMS_U8[..], &NUMS_U8[..], &NUMS_U16[..]);
427 check_decode_4x::<u8, u8, u8, u32>(&NUMS_U8[..], &NUMS_U8[..], &NUMS_U8[..], &NUMS_U32[..]);
428 check_decode_4x::<u8, u8, u8, u64>(&NUMS_U8[..], &NUMS_U8[..], &NUMS_U8[..], &NUMS_U64[..]);
429
430 check_decode_4x::<u8, u8, u16, u8>(&NUMS_U8[..], &NUMS_U8[..], &NUMS_U16[..], &NUMS_U8[..]);
431 check_decode_4x::<u8, u8, u16, u16>(
432 &NUMS_U8[..],
433 &NUMS_U8[..],
434 &NUMS_U16[..],
435 &NUMS_U16[..],
436 );
437 check_decode_4x::<u8, u8, u16, u32>(
438 &NUMS_U8[..],
439 &NUMS_U8[..],
440 &NUMS_U16[..],
441 &NUMS_U32[..],
442 );
443 }
444
445 #[test]
446 fn test_decode_4x_u8_u16_x_x() {
447 check_decode_4x::<u8, u16, u8, u8>(&NUMS_U8[..], &NUMS_U16[..], &NUMS_U8[..], &NUMS_U8[..]);
448 check_decode_4x::<u8, u16, u8, u16>(
449 &NUMS_U8[..],
450 &NUMS_U16[..],
451 &NUMS_U8[..],
452 &NUMS_U16[..],
453 );
454 check_decode_4x::<u8, u16, u8, u32>(
455 &NUMS_U8[..],
456 &NUMS_U16[..],
457 &NUMS_U8[..],
458 &NUMS_U32[..],
459 );
460
461 check_decode_4x::<u8, u16, u16, u8>(
462 &NUMS_U8[..],
463 &NUMS_U16[..],
464 &NUMS_U16[..],
465 &NUMS_U8[..],
466 );
467 check_decode_4x::<u8, u16, u16, u16>(
468 &NUMS_U8[..],
469 &NUMS_U16[..],
470 &NUMS_U16[..],
471 &NUMS_U16[..],
472 );
473 check_decode_4x::<u8, u16, u16, u32>(
474 &NUMS_U8[..],
475 &NUMS_U16[..],
476 &NUMS_U16[..],
477 &NUMS_U32[..],
478 );
479 }
480
481 #[test]
482 fn test_decode_4x_u8_u32_x_x() {
483 check_decode_4x::<u8, u32, u8, u8>(&NUMS_U8[..], &NUMS_U32[..], &NUMS_U8[..], &NUMS_U8[..]);
484 check_decode_4x::<u8, u32, u8, u16>(
485 &NUMS_U8[..],
486 &NUMS_U32[..],
487 &NUMS_U8[..],
488 &NUMS_U16[..],
489 );
490 check_decode_4x::<u8, u32, u8, u32>(
491 &NUMS_U8[..],
492 &NUMS_U32[..],
493 &NUMS_U8[..],
494 &NUMS_U32[..],
495 );
496
497 check_decode_4x::<u8, u32, u16, u8>(
498 &NUMS_U8[..],
499 &NUMS_U32[..],
500 &NUMS_U16[..],
501 &NUMS_U8[..],
502 );
503 check_decode_4x::<u8, u32, u16, u16>(
504 &NUMS_U8[..],
505 &NUMS_U32[..],
506 &NUMS_U16[..],
507 &NUMS_U16[..],
508 );
509 check_decode_4x::<u8, u32, u16, u32>(
510 &NUMS_U8[..],
511 &NUMS_U32[..],
512 &NUMS_U16[..],
513 &NUMS_U32[..],
514 );
515 }
516
517 #[test]
518 fn test_decode_4x_u8_u64_x_x() {
519 check_decode_4x::<u8, u64, u8, u8>(&NUMS_U8[..], &NUMS_U64[..], &NUMS_U8[..], &NUMS_U8[..]);
520 }
521
522 #[test]
523 fn test_decode_4x_u16_u8_x_x() {
524 check_decode_4x::<u16, u8, u8, u8>(&NUMS_U16[..], &NUMS_U8[..], &NUMS_U8[..], &NUMS_U8[..]);
525 check_decode_4x::<u16, u8, u8, u16>(
526 &NUMS_U16[..],
527 &NUMS_U8[..],
528 &NUMS_U8[..],
529 &NUMS_U16[..],
530 );
531 check_decode_4x::<u16, u8, u8, u32>(
532 &NUMS_U16[..],
533 &NUMS_U8[..],
534 &NUMS_U8[..],
535 &NUMS_U32[..],
536 );
537
538 check_decode_4x::<u16, u8, u16, u8>(
539 &NUMS_U16[..],
540 &NUMS_U8[..],
541 &NUMS_U16[..],
542 &NUMS_U8[..],
543 );
544 check_decode_4x::<u16, u8, u16, u16>(
545 &NUMS_U16[..],
546 &NUMS_U8[..],
547 &NUMS_U16[..],
548 &NUMS_U16[..],
549 );
550 check_decode_4x::<u16, u8, u16, u32>(
551 &NUMS_U16[..],
552 &NUMS_U8[..],
553 &NUMS_U16[..],
554 &NUMS_U32[..],
555 );
556 }
557
558 #[test]
559 fn test_decode_4x_u16_u16_x_x() {
560 check_decode_4x::<u16, u16, u8, u8>(
561 &NUMS_U16[..],
562 &NUMS_U16[..],
563 &NUMS_U8[..],
564 &NUMS_U8[..],
565 );
566 check_decode_4x::<u16, u16, u8, u16>(
567 &NUMS_U16[..],
568 &NUMS_U16[..],
569 &NUMS_U8[..],
570 &NUMS_U16[..],
571 );
572 check_decode_4x::<u16, u16, u8, u32>(
573 &NUMS_U16[..],
574 &NUMS_U16[..],
575 &NUMS_U8[..],
576 &NUMS_U32[..],
577 );
578
579 check_decode_4x::<u16, u16, u16, u8>(
580 &NUMS_U16[..],
581 &NUMS_U16[..],
582 &NUMS_U16[..],
583 &NUMS_U8[..],
584 );
585 check_decode_4x::<u16, u16, u16, u16>(
586 &NUMS_U16[..],
587 &NUMS_U16[..],
588 &NUMS_U16[..],
589 &NUMS_U16[..],
590 );
591 check_decode_4x::<u16, u16, u16, u32>(
592 &NUMS_U16[..],
593 &NUMS_U16[..],
594 &NUMS_U16[..],
595 &NUMS_U32[..],
596 );
597 }
598
599 #[test]
600 fn test_decode_4x_u16_u32_x_x() {
601 check_decode_4x::<u16, u32, u8, u8>(
602 &NUMS_U16[..],
603 &NUMS_U32[..],
604 &NUMS_U8[..],
605 &NUMS_U8[..],
606 );
607 check_decode_4x::<u16, u32, u8, u16>(
608 &NUMS_U16[..],
609 &NUMS_U32[..],
610 &NUMS_U8[..],
611 &NUMS_U16[..],
612 );
613 check_decode_4x::<u16, u32, u8, u32>(
614 &NUMS_U16[..],
615 &NUMS_U32[..],
616 &NUMS_U8[..],
617 &NUMS_U32[..],
618 );
619
620 check_decode_4x::<u16, u32, u16, u8>(
621 &NUMS_U16[..],
622 &NUMS_U32[..],
623 &NUMS_U16[..],
624 &NUMS_U8[..],
625 );
626 check_decode_4x::<u16, u32, u16, u16>(
627 &NUMS_U16[..],
628 &NUMS_U32[..],
629 &NUMS_U16[..],
630 &NUMS_U16[..],
631 );
632 check_decode_4x::<u16, u32, u16, u32>(
633 &NUMS_U16[..],
634 &NUMS_U32[..],
635 &NUMS_U16[..],
636 &NUMS_U32[..],
637 );
638 }
639
640 #[test]
641 fn test_decode_4x_u32_u8_x_x() {
642 check_decode_4x::<u32, u8, u8, u8>(&NUMS_U32[..], &NUMS_U8[..], &NUMS_U8[..], &NUMS_U8[..]);
643 check_decode_4x::<u32, u8, u8, u16>(
644 &NUMS_U32[..],
645 &NUMS_U8[..],
646 &NUMS_U8[..],
647 &NUMS_U16[..],
648 );
649 check_decode_4x::<u32, u8, u8, u32>(
650 &NUMS_U32[..],
651 &NUMS_U8[..],
652 &NUMS_U8[..],
653 &NUMS_U32[..],
654 );
655
656 check_decode_4x::<u32, u8, u16, u8>(
657 &NUMS_U32[..],
658 &NUMS_U8[..],
659 &NUMS_U16[..],
660 &NUMS_U8[..],
661 );
662 check_decode_4x::<u32, u8, u16, u16>(
663 &NUMS_U32[..],
664 &NUMS_U8[..],
665 &NUMS_U16[..],
666 &NUMS_U16[..],
667 );
668 check_decode_4x::<u32, u8, u16, u32>(
669 &NUMS_U32[..],
670 &NUMS_U8[..],
671 &NUMS_U16[..],
672 &NUMS_U32[..],
673 );
674 }
675
676 #[test]
677 fn test_decode_4x_u32_u16_x_x() {
678 check_decode_4x::<u32, u16, u8, u8>(
679 &NUMS_U32[..],
680 &NUMS_U16[..],
681 &NUMS_U8[..],
682 &NUMS_U8[..],
683 );
684 check_decode_4x::<u32, u16, u8, u16>(
685 &NUMS_U32[..],
686 &NUMS_U16[..],
687 &NUMS_U8[..],
688 &NUMS_U16[..],
689 );
690 check_decode_4x::<u32, u16, u8, u32>(
691 &NUMS_U32[..],
692 &NUMS_U16[..],
693 &NUMS_U8[..],
694 &NUMS_U32[..],
695 );
696
697 check_decode_4x::<u32, u16, u16, u8>(
698 &NUMS_U32[..],
699 &NUMS_U16[..],
700 &NUMS_U16[..],
701 &NUMS_U8[..],
702 );
703 check_decode_4x::<u32, u16, u16, u16>(
704 &NUMS_U32[..],
705 &NUMS_U16[..],
706 &NUMS_U16[..],
707 &NUMS_U16[..],
708 );
709 check_decode_4x::<u32, u16, u16, u32>(
710 &NUMS_U32[..],
711 &NUMS_U16[..],
712 &NUMS_U16[..],
713 &NUMS_U32[..],
714 );
715 }
716
717 #[test]
718 fn test_decode_4x_u32_u32_x_x() {
719 check_decode_4x::<u32, u32, u8, u8>(
720 &NUMS_U32[..],
721 &NUMS_U32[..],
722 &NUMS_U8[..],
723 &NUMS_U8[..],
724 );
725 check_decode_4x::<u32, u32, u8, u16>(
726 &NUMS_U32[..],
727 &NUMS_U32[..],
728 &NUMS_U8[..],
729 &NUMS_U16[..],
730 );
731
732 check_decode_4x::<u32, u32, u16, u8>(
733 &NUMS_U32[..],
734 &NUMS_U32[..],
735 &NUMS_U16[..],
736 &NUMS_U8[..],
737 );
738 check_decode_4x::<u32, u32, u16, u16>(
739 &NUMS_U32[..],
740 &NUMS_U32[..],
741 &NUMS_U16[..],
742 &NUMS_U16[..],
743 );
744 }
745
746 #[test]
747 fn test_decode_4x_u64_u8_x_x() {
748 check_decode_4x::<u64, u8, u8, u8>(&NUMS_U64[..], &NUMS_U8[..], &NUMS_U8[..], &NUMS_U8[..]);
749 }
750
751 fn check_decode_8x_u8(a: &[u8]) {
752 for i in a {
753 for j in a {
754 for k in a {
755 for l in a {
756 for m in a {
757 for n in a {
758 for o in a {
759 for p in a {
760 let mut enc = [0u8; 16];
761
762 let first_len = encode_to_slice(*i, &mut enc);
763 let second_len =
764 encode_to_slice(*j, &mut enc[first_len as usize..]);
765 let third_len = encode_to_slice(
766 *k,
767 &mut enc[(first_len + second_len) as usize..],
768 );
769 let fourth_len = encode_to_slice(
770 *l,
771 &mut enc
772 [(first_len + second_len + third_len) as usize..],
773 );
774 let fifth_len = encode_to_slice(
775 *m,
776 &mut enc[(first_len
777 + second_len
778 + third_len
779 + fourth_len)
780 as usize..],
781 );
782 let sixth_len = encode_to_slice(
783 *n,
784 &mut enc[(first_len
785 + second_len
786 + third_len
787 + fourth_len
788 + fifth_len)
789 as usize..],
790 );
791 let seventh_len = encode_to_slice(
792 *o,
793 &mut enc[(first_len
794 + second_len
795 + third_len
796 + fourth_len
797 + fifth_len
798 + sixth_len)
799 as usize..],
800 );
801 let eighth_len = encode_to_slice(
802 *p,
803 &mut enc[(first_len
804 + second_len
805 + third_len
806 + fourth_len
807 + fifth_len
808 + sixth_len
809 + seventh_len)
810 as usize..],
811 );
812
813 let decoded =
814 unsafe { decode_eight_u8_unsafe(enc.as_ptr()) };
815
816 assert_eq!(decoded.0, [*i, *j, *k, *l, *m, *n, *o, *p]);
817 assert_eq!(
818 decoded.1,
819 first_len
820 + second_len
821 + third_len
822 + fourth_len
823 + fifth_len
824 + sixth_len
825 + seventh_len
826 + eighth_len
827 );
828 }
829 }
830 }
831 }
832 }
833 }
834 }
835 }
836 }
837
838 #[test]
839 fn test_decode_8x_u8() {
840 check_decode_8x_u8(&NUMS_U8[..]);
841 }
842
843 }