• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
2 #![allow(clippy::cast_possible_truncation)]
3 
4 use std::str;
5 use std::sync::atomic::{AtomicUsize, Ordering};
6 use std::sync::Arc;
7 use std::thread;
8 
9 #[test]
10 #[cfg_attr(not(exhaustive), ignore = "requires cfg(exhaustive)")]
test_exhaustive()11 fn test_exhaustive() {
12     const BATCH_SIZE: u32 = 1_000_000;
13     let counter = Arc::new(AtomicUsize::new(0));
14     let finished = Arc::new(AtomicUsize::new(0));
15 
16     let mut workers = Vec::new();
17     for _ in 0..num_cpus::get() {
18         let counter = counter.clone();
19         let finished = finished.clone();
20         workers.push(thread::spawn(move || loop {
21             let batch = counter.fetch_add(1, Ordering::Relaxed) as u32;
22             if batch > u32::max_value() / BATCH_SIZE {
23                 return;
24             }
25 
26             let min = batch * BATCH_SIZE;
27             let max = if batch == u32::max_value() / BATCH_SIZE {
28                 u32::max_value()
29             } else {
30                 min + BATCH_SIZE - 1
31             };
32 
33             let mut bytes = [0u8; 24];
34             let mut buffer = ryu::Buffer::new();
35             for u in min..=max {
36                 let f = f32::from_bits(u);
37                 if !f.is_finite() {
38                     continue;
39                 }
40                 let n = unsafe { ryu::raw::format32(f, &mut bytes[0]) };
41                 assert_eq!(Ok(Ok(f)), str::from_utf8(&bytes[..n]).map(str::parse));
42                 assert_eq!(Ok(f), buffer.format_finite(f).parse());
43             }
44 
45             let increment = (max - min + 1) as usize;
46             let update = finished.fetch_add(increment, Ordering::Relaxed);
47             println!("{}", update + increment);
48         }));
49     }
50 
51     for w in workers {
52         w.join().unwrap();
53     }
54 }
55