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    }