build.rs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
  1. use rand::seq::SliceRandom;
  2. use rand::Rng;
  3. use std::collections::HashMap;
  4. use std::fmt;
  5. use std::fmt::Write as FmtWrite;
  6. use std::fs::{self, OpenOptions};
  7. use std::hash::{Hash, Hasher};
  8. use std::io::Write;
  9. use std::path::PathBuf;
  10. use std::{env, mem};
  11. const NTESTS: usize = 1_000;
  12. fn main() {
  13. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  14. let out_file = out_dir.join("generated.rs");
  15. drop(fs::remove_file(&out_file));
  16. let target = env::var("TARGET").unwrap();
  17. let target_arch_arm = target.contains("arm") || target.contains("thumb");
  18. let target_arch_mips = target.contains("mips");
  19. // TODO accept NaNs. We don't do that right now because we can't check
  20. // for NaN-ness on the thumb targets (due to missing intrinsics)
  21. // float/add.rs
  22. gen(
  23. |(a, b): (MyF64, MyF64)| {
  24. let c = a.0 + b.0;
  25. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  26. None
  27. } else {
  28. Some(c)
  29. }
  30. },
  31. "builtins::float::add::__adddf3(a, b)",
  32. );
  33. gen(
  34. |(a, b): (MyF32, MyF32)| {
  35. let c = a.0 + b.0;
  36. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  37. None
  38. } else {
  39. Some(c)
  40. }
  41. },
  42. "builtins::float::add::__addsf3(a, b)",
  43. );
  44. if target_arch_arm {
  45. gen(
  46. |(a, b): (MyF64, MyF64)| {
  47. let c = a.0 + b.0;
  48. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  49. None
  50. } else {
  51. Some(c)
  52. }
  53. },
  54. "builtins::float::add::__adddf3vfp(a, b)",
  55. );
  56. gen(
  57. |(a, b): (LargeF32, LargeF32)| {
  58. let c = a.0 + b.0;
  59. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  60. None
  61. } else {
  62. Some(c)
  63. }
  64. },
  65. "builtins::float::add::__addsf3vfp(a, b)",
  66. );
  67. }
  68. // float/cmp.rs
  69. gen(
  70. |(a, b): (MyF64, MyF64)| {
  71. let (a, b) = (a.0, b.0);
  72. if a.is_nan() || b.is_nan() {
  73. return None;
  74. }
  75. if a.is_nan() || b.is_nan() {
  76. Some(-1)
  77. } else if a < b {
  78. Some(-1)
  79. } else if a > b {
  80. Some(1)
  81. } else {
  82. Some(0)
  83. }
  84. },
  85. "builtins::float::cmp::__gedf2(a, b)",
  86. );
  87. gen(
  88. |(a, b): (MyF32, MyF32)| {
  89. let (a, b) = (a.0, b.0);
  90. if a.is_nan() || b.is_nan() {
  91. return None;
  92. }
  93. if a.is_nan() || b.is_nan() {
  94. Some(-1)
  95. } else if a < b {
  96. Some(-1)
  97. } else if a > b {
  98. Some(1)
  99. } else {
  100. Some(0)
  101. }
  102. },
  103. "builtins::float::cmp::__gesf2(a, b)",
  104. );
  105. gen(
  106. |(a, b): (MyF64, MyF64)| {
  107. let (a, b) = (a.0, b.0);
  108. if a.is_nan() || b.is_nan() {
  109. return None;
  110. }
  111. if a.is_nan() || b.is_nan() {
  112. Some(1)
  113. } else if a < b {
  114. Some(-1)
  115. } else if a > b {
  116. Some(1)
  117. } else {
  118. Some(0)
  119. }
  120. },
  121. "builtins::float::cmp::__ledf2(a, b)",
  122. );
  123. gen(
  124. |(a, b): (MyF32, MyF32)| {
  125. let (a, b) = (a.0, b.0);
  126. if a.is_nan() || b.is_nan() {
  127. return None;
  128. }
  129. if a.is_nan() || b.is_nan() {
  130. Some(1)
  131. } else if a < b {
  132. Some(-1)
  133. } else if a > b {
  134. Some(1)
  135. } else {
  136. Some(0)
  137. }
  138. },
  139. "builtins::float::cmp::__lesf2(a, b)",
  140. );
  141. gen(
  142. |(a, b): (MyF32, MyF32)| {
  143. let c = a.0.is_nan() || b.0.is_nan();
  144. Some(c as i32)
  145. },
  146. "builtins::float::cmp::__unordsf2(a, b)",
  147. );
  148. gen(
  149. |(a, b): (MyF64, MyF64)| {
  150. let c = a.0.is_nan() || b.0.is_nan();
  151. Some(c as i32)
  152. },
  153. "builtins::float::cmp::__unorddf2(a, b)",
  154. );
  155. if target_arch_arm {
  156. gen(
  157. |(a, b): (MyF32, MyF32)| {
  158. if a.0.is_nan() || b.0.is_nan() {
  159. return None;
  160. }
  161. let c = (a.0 <= b.0) as i32;
  162. Some(c)
  163. },
  164. "builtins::float::cmp::__aeabi_fcmple(a, b)",
  165. );
  166. gen(
  167. |(a, b): (MyF32, MyF32)| {
  168. if a.0.is_nan() || b.0.is_nan() {
  169. return None;
  170. }
  171. let c = (a.0 >= b.0) as i32;
  172. Some(c)
  173. },
  174. "builtins::float::cmp::__aeabi_fcmpge(a, b)",
  175. );
  176. gen(
  177. |(a, b): (MyF32, MyF32)| {
  178. if a.0.is_nan() || b.0.is_nan() {
  179. return None;
  180. }
  181. let c = (a.0 == b.0) as i32;
  182. Some(c)
  183. },
  184. "builtins::float::cmp::__aeabi_fcmpeq(a, b)",
  185. );
  186. gen(
  187. |(a, b): (MyF32, MyF32)| {
  188. if a.0.is_nan() || b.0.is_nan() {
  189. return None;
  190. }
  191. let c = (a.0 < b.0) as i32;
  192. Some(c)
  193. },
  194. "builtins::float::cmp::__aeabi_fcmplt(a, b)",
  195. );
  196. gen(
  197. |(a, b): (MyF32, MyF32)| {
  198. if a.0.is_nan() || b.0.is_nan() {
  199. return None;
  200. }
  201. let c = (a.0 > b.0) as i32;
  202. Some(c)
  203. },
  204. "builtins::float::cmp::__aeabi_fcmpgt(a, b)",
  205. );
  206. gen(
  207. |(a, b): (MyF64, MyF64)| {
  208. if a.0.is_nan() || b.0.is_nan() {
  209. return None;
  210. }
  211. let c = (a.0 <= b.0) as i32;
  212. Some(c)
  213. },
  214. "builtins::float::cmp::__aeabi_dcmple(a, b)",
  215. );
  216. gen(
  217. |(a, b): (MyF64, MyF64)| {
  218. if a.0.is_nan() || b.0.is_nan() {
  219. return None;
  220. }
  221. let c = (a.0 >= b.0) as i32;
  222. Some(c)
  223. },
  224. "builtins::float::cmp::__aeabi_dcmpge(a, b)",
  225. );
  226. gen(
  227. |(a, b): (MyF64, MyF64)| {
  228. if a.0.is_nan() || b.0.is_nan() {
  229. return None;
  230. }
  231. let c = (a.0 == b.0) as i32;
  232. Some(c)
  233. },
  234. "builtins::float::cmp::__aeabi_dcmpeq(a, b)",
  235. );
  236. gen(
  237. |(a, b): (MyF64, MyF64)| {
  238. if a.0.is_nan() || b.0.is_nan() {
  239. return None;
  240. }
  241. let c = (a.0 < b.0) as i32;
  242. Some(c)
  243. },
  244. "builtins::float::cmp::__aeabi_dcmplt(a, b)",
  245. );
  246. gen(
  247. |(a, b): (MyF64, MyF64)| {
  248. if a.0.is_nan() || b.0.is_nan() {
  249. return None;
  250. }
  251. let c = (a.0 > b.0) as i32;
  252. Some(c)
  253. },
  254. "builtins::float::cmp::__aeabi_dcmpgt(a, b)",
  255. );
  256. gen(
  257. |(a, b): (LargeF32, LargeF32)| {
  258. if a.0.is_nan() || b.0.is_nan() {
  259. return None;
  260. }
  261. Some((a.0 >= b.0) as i32)
  262. },
  263. "builtins::float::cmp::__gesf2vfp(a, b)",
  264. );
  265. gen(
  266. |(a, b): (MyF64, MyF64)| {
  267. if a.0.is_nan() || b.0.is_nan() {
  268. return None;
  269. }
  270. Some((a.0 >= b.0) as i32)
  271. },
  272. "builtins::float::cmp::__gedf2vfp(a, b)",
  273. );
  274. gen(
  275. |(a, b): (LargeF32, LargeF32)| {
  276. if a.0.is_nan() || b.0.is_nan() {
  277. return None;
  278. }
  279. Some((a.0 > b.0) as i32)
  280. },
  281. "builtins::float::cmp::__gtsf2vfp(a, b)",
  282. );
  283. gen(
  284. |(a, b): (MyF64, MyF64)| {
  285. if a.0.is_nan() || b.0.is_nan() {
  286. return None;
  287. }
  288. Some((a.0 > b.0) as i32)
  289. },
  290. "builtins::float::cmp::__gtdf2vfp(a, b)",
  291. );
  292. gen(
  293. |(a, b): (LargeF32, LargeF32)| {
  294. if a.0.is_nan() || b.0.is_nan() {
  295. return None;
  296. }
  297. Some((a.0 < b.0) as i32)
  298. },
  299. "builtins::float::cmp::__ltsf2vfp(a, b)",
  300. );
  301. gen(
  302. |(a, b): (MyF64, MyF64)| {
  303. if a.0.is_nan() || b.0.is_nan() {
  304. return None;
  305. }
  306. Some((a.0 < b.0) as i32)
  307. },
  308. "builtins::float::cmp::__ltdf2vfp(a, b)",
  309. );
  310. gen(
  311. |(a, b): (LargeF32, LargeF32)| {
  312. if a.0.is_nan() || b.0.is_nan() {
  313. return None;
  314. }
  315. Some((a.0 <= b.0) as i32)
  316. },
  317. "builtins::float::cmp::__lesf2vfp(a, b)",
  318. );
  319. gen(
  320. |(a, b): (MyF64, MyF64)| {
  321. if a.0.is_nan() || b.0.is_nan() {
  322. return None;
  323. }
  324. Some((a.0 <= b.0) as i32)
  325. },
  326. "builtins::float::cmp::__ledf2vfp(a, b)",
  327. );
  328. gen(
  329. |(a, b): (LargeF32, LargeF32)| {
  330. if a.0.is_nan() || b.0.is_nan() {
  331. return None;
  332. }
  333. Some((a.0 != b.0) as i32)
  334. },
  335. "builtins::float::cmp::__nesf2vfp(a, b)",
  336. );
  337. gen(
  338. |(a, b): (MyF64, MyF64)| {
  339. if a.0.is_nan() || b.0.is_nan() {
  340. return None;
  341. }
  342. Some((a.0 != b.0) as i32)
  343. },
  344. "builtins::float::cmp::__nedf2vfp(a, b)",
  345. );
  346. gen(
  347. |(a, b): (LargeF32, LargeF32)| {
  348. if a.0.is_nan() || b.0.is_nan() {
  349. return None;
  350. }
  351. Some((a.0 == b.0) as i32)
  352. },
  353. "builtins::float::cmp::__eqsf2vfp(a, b)",
  354. );
  355. gen(
  356. |(a, b): (MyF64, MyF64)| {
  357. if a.0.is_nan() || b.0.is_nan() {
  358. return None;
  359. }
  360. Some((a.0 == b.0) as i32)
  361. },
  362. "builtins::float::cmp::__eqdf2vfp(a, b)",
  363. );
  364. }
  365. // float/extend.rs
  366. gen(
  367. |a: MyF32| {
  368. if a.0.is_nan() {
  369. return None;
  370. }
  371. Some(f64::from(a.0))
  372. },
  373. "builtins::float::extend::__extendsfdf2(a)",
  374. );
  375. if target_arch_arm {
  376. gen(
  377. |a: LargeF32| {
  378. if a.0.is_nan() {
  379. return None;
  380. }
  381. Some(f64::from(a.0))
  382. },
  383. "builtins::float::extend::__extendsfdf2vfp(a)",
  384. );
  385. }
  386. // float/conv.rs
  387. gen(
  388. |a: MyF64| i64::cast(a.0),
  389. "builtins::float::conv::__fixdfdi(a)",
  390. );
  391. gen(
  392. |a: MyF64| i32::cast(a.0),
  393. "builtins::float::conv::__fixdfsi(a)",
  394. );
  395. gen(
  396. |a: MyF32| i64::cast(a.0),
  397. "builtins::float::conv::__fixsfdi(a)",
  398. );
  399. gen(
  400. |a: MyF32| i32::cast(a.0),
  401. "builtins::float::conv::__fixsfsi(a)",
  402. );
  403. gen(
  404. |a: MyF32| i128::cast(a.0),
  405. "builtins::float::conv::__fixsfti(a)",
  406. );
  407. gen(
  408. |a: MyF64| i128::cast(a.0),
  409. "builtins::float::conv::__fixdfti(a)",
  410. );
  411. gen(
  412. |a: MyF64| u64::cast(a.0),
  413. "builtins::float::conv::__fixunsdfdi(a)",
  414. );
  415. gen(
  416. |a: MyF64| u32::cast(a.0),
  417. "builtins::float::conv::__fixunsdfsi(a)",
  418. );
  419. gen(
  420. |a: MyF32| u64::cast(a.0),
  421. "builtins::float::conv::__fixunssfdi(a)",
  422. );
  423. gen(
  424. |a: MyF32| u32::cast(a.0),
  425. "builtins::float::conv::__fixunssfsi(a)",
  426. );
  427. gen(
  428. |a: MyF32| u128::cast(a.0),
  429. "builtins::float::conv::__fixunssfti(a)",
  430. );
  431. gen(
  432. |a: MyF64| u128::cast(a.0),
  433. "builtins::float::conv::__fixunsdfti(a)",
  434. );
  435. gen(
  436. |a: MyI64| Some(a.0 as f64),
  437. "builtins::float::conv::__floatdidf(a)",
  438. );
  439. gen(
  440. |a: MyI32| Some(a.0 as f64),
  441. "builtins::float::conv::__floatsidf(a)",
  442. );
  443. gen(
  444. |a: MyI32| Some(a.0 as f32),
  445. "builtins::float::conv::__floatsisf(a)",
  446. );
  447. gen(
  448. |a: MyU64| Some(a.0 as f64),
  449. "builtins::float::conv::__floatundidf(a)",
  450. );
  451. gen(
  452. |a: MyU32| Some(a.0 as f64),
  453. "builtins::float::conv::__floatunsidf(a)",
  454. );
  455. gen(
  456. |a: MyU32| Some(a.0 as f32),
  457. "builtins::float::conv::__floatunsisf(a)",
  458. );
  459. gen(
  460. |a: MyU128| Some(a.0 as f32),
  461. "builtins::float::conv::__floatuntisf(a)",
  462. );
  463. if !target_arch_mips {
  464. gen(
  465. |a: MyI128| Some(a.0 as f32),
  466. "builtins::float::conv::__floattisf(a)",
  467. );
  468. gen(
  469. |a: MyI128| Some(a.0 as f64),
  470. "builtins::float::conv::__floattidf(a)",
  471. );
  472. gen(
  473. |a: MyU128| Some(a.0 as f64),
  474. "builtins::float::conv::__floatuntidf(a)",
  475. );
  476. }
  477. // float/pow.rs
  478. gen(
  479. |(a, b): (MyF64, MyI32)| {
  480. let c = a.0.powi(b.0);
  481. if a.0.is_nan() || c.is_nan() {
  482. None
  483. } else {
  484. Some(c)
  485. }
  486. },
  487. "builtins::float::pow::__powidf2(a, b)",
  488. );
  489. gen(
  490. |(a, b): (MyF32, MyI32)| {
  491. let c = a.0.powi(b.0);
  492. if a.0.is_nan() || c.is_nan() {
  493. None
  494. } else {
  495. Some(c)
  496. }
  497. },
  498. "builtins::float::pow::__powisf2(a, b)",
  499. );
  500. // float/sub.rs
  501. gen(
  502. |(a, b): (MyF64, MyF64)| {
  503. let c = a.0 - b.0;
  504. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  505. None
  506. } else {
  507. Some(c)
  508. }
  509. },
  510. "builtins::float::sub::__subdf3(a, b)",
  511. );
  512. gen(
  513. |(a, b): (MyF32, MyF32)| {
  514. let c = a.0 - b.0;
  515. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  516. None
  517. } else {
  518. Some(c)
  519. }
  520. },
  521. "builtins::float::sub::__subsf3(a, b)",
  522. );
  523. if target_arch_arm {
  524. gen(
  525. |(a, b): (MyF64, MyF64)| {
  526. let c = a.0 - b.0;
  527. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  528. None
  529. } else {
  530. Some(c)
  531. }
  532. },
  533. "builtins::float::sub::__subdf3vfp(a, b)",
  534. );
  535. gen(
  536. |(a, b): (LargeF32, LargeF32)| {
  537. let c = a.0 - b.0;
  538. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  539. None
  540. } else {
  541. Some(c)
  542. }
  543. },
  544. "builtins::float::sub::__subsf3vfp(a, b)",
  545. );
  546. }
  547. // float/mul.rs
  548. gen(
  549. |(a, b): (MyF64, MyF64)| {
  550. let c = a.0 * b.0;
  551. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  552. None
  553. } else {
  554. Some(c)
  555. }
  556. },
  557. "builtins::float::mul::__muldf3(a, b)",
  558. );
  559. gen(
  560. |(a, b): (LargeF32, LargeF32)| {
  561. let c = a.0 * b.0;
  562. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  563. None
  564. } else {
  565. Some(c)
  566. }
  567. },
  568. "builtins::float::mul::__mulsf3(a, b)",
  569. );
  570. if target_arch_arm {
  571. gen(
  572. |(a, b): (MyF64, MyF64)| {
  573. let c = a.0 * b.0;
  574. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  575. None
  576. } else {
  577. Some(c)
  578. }
  579. },
  580. "builtins::float::mul::__muldf3vfp(a, b)",
  581. );
  582. gen(
  583. |(a, b): (LargeF32, LargeF32)| {
  584. let c = a.0 * b.0;
  585. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  586. None
  587. } else {
  588. Some(c)
  589. }
  590. },
  591. "builtins::float::mul::__mulsf3vfp(a, b)",
  592. );
  593. }
  594. // float/div.rs
  595. gen(
  596. |(a, b): (MyF64, MyF64)| {
  597. if b.0 == 0.0 {
  598. return None;
  599. }
  600. let c = a.0 / b.0;
  601. if a.0.is_nan()
  602. || b.0.is_nan()
  603. || c.is_nan()
  604. || c.abs() <= f64::from_bits(4503599627370495u64)
  605. {
  606. None
  607. } else {
  608. Some(c)
  609. }
  610. },
  611. "builtins::float::div::__divdf3(a, b)",
  612. );
  613. gen(
  614. |(a, b): (LargeF32, LargeF32)| {
  615. if b.0 == 0.0 {
  616. return None;
  617. }
  618. let c = a.0 / b.0;
  619. if a.0.is_nan() || b.0.is_nan() || c.is_nan() || c.abs() <= f32::from_bits(16777215u32)
  620. {
  621. None
  622. } else {
  623. Some(c)
  624. }
  625. },
  626. "builtins::float::div::__divsf3(a, b)",
  627. );
  628. if target_arch_arm {
  629. gen(
  630. |(a, b): (MyF64, MyF64)| {
  631. if b.0 == 0.0 {
  632. return None;
  633. }
  634. let c = a.0 / b.0;
  635. if a.0.is_nan()
  636. || b.0.is_nan()
  637. || c.is_nan()
  638. || c.abs() <= f64::from_bits(4503599627370495u64)
  639. {
  640. None
  641. } else {
  642. Some(c)
  643. }
  644. },
  645. "builtins::float::div::__divdf3vfp(a, b)",
  646. );
  647. gen(
  648. |(a, b): (LargeF32, LargeF32)| {
  649. if b.0 == 0.0 {
  650. return None;
  651. }
  652. let c = a.0 / b.0;
  653. if a.0.is_nan()
  654. || b.0.is_nan()
  655. || c.is_nan()
  656. || c.abs() <= f32::from_bits(16777215u32)
  657. {
  658. None
  659. } else {
  660. Some(c)
  661. }
  662. },
  663. "builtins::float::div::__divsf3vfp(a, b)",
  664. );
  665. }
  666. // int/addsub.rs
  667. gen(
  668. |(a, b): (MyU128, MyU128)| Some(a.0.wrapping_add(b.0)),
  669. "builtins::int::addsub::__rust_u128_add(a, b)",
  670. );
  671. gen(
  672. |(a, b): (MyI128, MyI128)| Some(a.0.wrapping_add(b.0)),
  673. "builtins::int::addsub::__rust_i128_add(a, b)",
  674. );
  675. gen(
  676. |(a, b): (MyU128, MyU128)| Some(a.0.overflowing_add(b.0)),
  677. "builtins::int::addsub::__rust_u128_addo(a, b)",
  678. );
  679. gen(
  680. |(a, b): (MyI128, MyI128)| Some(a.0.overflowing_add(b.0)),
  681. "builtins::int::addsub::__rust_i128_addo(a, b)",
  682. );
  683. gen(
  684. |(a, b): (MyU128, MyU128)| Some(a.0.wrapping_sub(b.0)),
  685. "builtins::int::addsub::__rust_u128_sub(a, b)",
  686. );
  687. gen(
  688. |(a, b): (MyI128, MyI128)| Some(a.0.wrapping_sub(b.0)),
  689. "builtins::int::addsub::__rust_i128_sub(a, b)",
  690. );
  691. gen(
  692. |(a, b): (MyU128, MyU128)| Some(a.0.overflowing_sub(b.0)),
  693. "builtins::int::addsub::__rust_u128_subo(a, b)",
  694. );
  695. gen(
  696. |(a, b): (MyI128, MyI128)| Some(a.0.overflowing_sub(b.0)),
  697. "builtins::int::addsub::__rust_i128_subo(a, b)",
  698. );
  699. // int/mul.rs
  700. gen(
  701. |(a, b): (MyU64, MyU64)| Some(a.0.wrapping_mul(b.0)),
  702. "builtins::int::mul::__muldi3(a, b)",
  703. );
  704. gen(
  705. |(a, b): (MyI64, MyI64)| Some(a.0.overflowing_mul(b.0)),
  706. "{
  707. let mut o = 2;
  708. let c = builtins::int::mul::__mulodi4(a, b, &mut o);
  709. (c, match o { 0 => false, 1 => true, _ => panic!() })
  710. }",
  711. );
  712. gen(
  713. |(a, b): (MyI32, MyI32)| Some(a.0.overflowing_mul(b.0)),
  714. "{
  715. let mut o = 2;
  716. let c = builtins::int::mul::__mulosi4(a, b, &mut o);
  717. (c, match o { 0 => false, 1 => true, _ => panic!() })
  718. }",
  719. );
  720. gen(
  721. |(a, b): (MyI128, MyI128)| Some(a.0.wrapping_mul(b.0)),
  722. "builtins::int::mul::__multi3(a, b)",
  723. );
  724. gen(
  725. |(a, b): (MyI128, MyI128)| Some(a.0.overflowing_mul(b.0)),
  726. "{
  727. let mut o = 2;
  728. let c = builtins::int::mul::__muloti4(a, b, &mut o);
  729. (c, match o { 0 => false, 1 => true, _ => panic!() })
  730. }",
  731. );
  732. // int/sdiv.rs
  733. gen(
  734. |(a, b): (MyI64, MyI64)| {
  735. if b.0 == 0 {
  736. None
  737. } else {
  738. Some(a.0 / b.0)
  739. }
  740. },
  741. "builtins::int::sdiv::__divdi3(a, b)",
  742. );
  743. gen(
  744. |(a, b): (MyI64, MyI64)| {
  745. if b.0 == 0 {
  746. None
  747. } else {
  748. Some((a.0 / b.0, a.0 % b.0))
  749. }
  750. },
  751. "{
  752. let mut r = 0;
  753. (builtins::int::sdiv::__divmoddi4(a, b, &mut r), r)
  754. }",
  755. );
  756. gen(
  757. |(a, b): (MyI32, MyI32)| {
  758. if b.0 == 0 {
  759. None
  760. } else {
  761. Some((a.0 / b.0, a.0 % b.0))
  762. }
  763. },
  764. "{
  765. let mut r = 0;
  766. (builtins::int::sdiv::__divmodsi4(a, b, &mut r), r)
  767. }",
  768. );
  769. gen(
  770. |(a, b): (MyI128, MyI128)| {
  771. if b.0 == 0 {
  772. None
  773. } else {
  774. Some((a.0 / b.0, a.0 % b.0))
  775. }
  776. },
  777. "{
  778. let mut r = 0;
  779. (builtins::int::sdiv::__divmodti4(a, b, &mut r), r)
  780. }",
  781. );
  782. gen(
  783. |(a, b): (MyI32, MyI32)| {
  784. if b.0 == 0 {
  785. None
  786. } else {
  787. Some(a.0 / b.0)
  788. }
  789. },
  790. "builtins::int::sdiv::__divsi3(a, b)",
  791. );
  792. gen(
  793. |(a, b): (MyI32, MyI32)| {
  794. if b.0 == 0 {
  795. None
  796. } else {
  797. Some(a.0 % b.0)
  798. }
  799. },
  800. "builtins::int::sdiv::__modsi3(a, b)",
  801. );
  802. gen(
  803. |(a, b): (MyI64, MyI64)| {
  804. if b.0 == 0 {
  805. None
  806. } else {
  807. Some(a.0 % b.0)
  808. }
  809. },
  810. "builtins::int::sdiv::__moddi3(a, b)",
  811. );
  812. gen(
  813. |(a, b): (MyI128, MyI128)| {
  814. if b.0 == 0 {
  815. None
  816. } else {
  817. Some(a.0 / b.0)
  818. }
  819. },
  820. "builtins::int::sdiv::__divti3(a, b)",
  821. );
  822. gen(
  823. |(a, b): (MyI128, MyI128)| {
  824. if b.0 == 0 {
  825. None
  826. } else {
  827. Some(a.0 % b.0)
  828. }
  829. },
  830. "builtins::int::sdiv::__modti3(a, b)",
  831. );
  832. // int/shift.rs
  833. gen(
  834. |(a, b): (MyU32, MyU32)| Some(a.0 << (b.0 % 32)),
  835. "builtins::int::shift::__ashlsi3(a, b % 32)",
  836. );
  837. gen(
  838. |(a, b): (MyU64, MyU32)| Some(a.0 << (b.0 % 64)),
  839. "builtins::int::shift::__ashldi3(a, b % 64)",
  840. );
  841. gen(
  842. |(a, b): (MyU128, MyU32)| Some(a.0 << (b.0 % 128)),
  843. "builtins::int::shift::__ashlti3(a, b % 128)",
  844. );
  845. gen(
  846. |(a, b): (MyI32, MyU32)| Some(a.0 >> (b.0 % 32)),
  847. "builtins::int::shift::__ashrsi3(a, b % 32)",
  848. );
  849. gen(
  850. |(a, b): (MyI64, MyU32)| Some(a.0 >> (b.0 % 64)),
  851. "builtins::int::shift::__ashrdi3(a, b % 64)",
  852. );
  853. gen(
  854. |(a, b): (MyI128, MyU32)| Some(a.0 >> (b.0 % 128)),
  855. "builtins::int::shift::__ashrti3(a, b % 128)",
  856. );
  857. gen(
  858. |(a, b): (MyU32, MyU32)| Some(a.0 >> (b.0 % 32)),
  859. "builtins::int::shift::__lshrsi3(a, b % 32)",
  860. );
  861. gen(
  862. |(a, b): (MyU64, MyU32)| Some(a.0 >> (b.0 % 64)),
  863. "builtins::int::shift::__lshrdi3(a, b % 64)",
  864. );
  865. gen(
  866. |(a, b): (MyU128, MyU32)| Some(a.0 >> (b.0 % 128)),
  867. "builtins::int::shift::__lshrti3(a, b % 128)",
  868. );
  869. // int/udiv.rs
  870. gen(
  871. |(a, b): (MyU64, MyU64)| {
  872. if b.0 == 0 {
  873. None
  874. } else {
  875. Some(a.0 / b.0)
  876. }
  877. },
  878. "builtins::int::udiv::__udivdi3(a, b)",
  879. );
  880. gen(
  881. |(a, b): (MyU64, MyU64)| {
  882. if b.0 == 0 {
  883. None
  884. } else {
  885. Some((a.0 / b.0, a.0 % b.0))
  886. }
  887. },
  888. "{
  889. let mut r = 0;
  890. (builtins::int::udiv::__udivmoddi4(a, b, Some(&mut r)), r)
  891. }",
  892. );
  893. gen(
  894. |(a, b): (MyU32, MyU32)| {
  895. if b.0 == 0 {
  896. None
  897. } else {
  898. Some((a.0 / b.0, a.0 % b.0))
  899. }
  900. },
  901. "{
  902. let mut r = 0;
  903. (builtins::int::udiv::__udivmodsi4(a, b, Some(&mut r)), r)
  904. }",
  905. );
  906. gen(
  907. |(a, b): (MyU32, MyU32)| {
  908. if b.0 == 0 {
  909. None
  910. } else {
  911. Some(a.0 / b.0)
  912. }
  913. },
  914. "builtins::int::udiv::__udivsi3(a, b)",
  915. );
  916. gen(
  917. |(a, b): (MyU32, MyU32)| {
  918. if b.0 == 0 {
  919. None
  920. } else {
  921. Some(a.0 % b.0)
  922. }
  923. },
  924. "builtins::int::udiv::__umodsi3(a, b)",
  925. );
  926. gen(
  927. |(a, b): (MyU64, MyU64)| {
  928. if b.0 == 0 {
  929. None
  930. } else {
  931. Some(a.0 % b.0)
  932. }
  933. },
  934. "builtins::int::udiv::__umoddi3(a, b)",
  935. );
  936. gen(
  937. |(a, b): (MyU128, MyU128)| {
  938. if b.0 == 0 {
  939. None
  940. } else {
  941. Some(a.0 / b.0)
  942. }
  943. },
  944. "builtins::int::udiv::__udivti3(a, b)",
  945. );
  946. gen(
  947. |(a, b): (MyU128, MyU128)| {
  948. if b.0 == 0 {
  949. None
  950. } else {
  951. Some(a.0 % b.0)
  952. }
  953. },
  954. "builtins::int::udiv::__umodti3(a, b)",
  955. );
  956. gen(
  957. |(a, b): (MyU128, MyU128)| {
  958. if b.0 == 0 {
  959. None
  960. } else {
  961. Some((a.0 / b.0, a.0 % b.0))
  962. }
  963. },
  964. "{
  965. let mut r = 0;
  966. (builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r)
  967. }",
  968. );
  969. }
  970. macro_rules! gen_float {
  971. ($name:ident,
  972. $fty:ident,
  973. $uty:ident,
  974. $bits:expr,
  975. $significand_bits:expr) => {
  976. pub fn $name<R>(rng: &mut R) -> $fty
  977. where
  978. R: Rng + ?Sized,
  979. {
  980. const BITS: u8 = $bits;
  981. const SIGNIFICAND_BITS: u8 = $significand_bits;
  982. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  983. const SIGN_MASK: $uty = (1 << (BITS - 1));
  984. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  985. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  986. unsafe {
  987. mem::transmute(
  988. ((sign as $uty) << (BITS - 1))
  989. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  990. | (significand & SIGNIFICAND_MASK),
  991. )
  992. }
  993. }
  994. if rng.gen_range(0, 10) == 1 {
  995. // Special values
  996. *[
  997. -0.0,
  998. 0.0,
  999. ::std::$fty::MIN,
  1000. ::std::$fty::MIN_POSITIVE,
  1001. ::std::$fty::MAX,
  1002. ::std::$fty::NAN,
  1003. ::std::$fty::INFINITY,
  1004. -::std::$fty::INFINITY,
  1005. ]
  1006. .choose(rng)
  1007. .unwrap()
  1008. } else if rng.gen_range(0, 10) == 1 {
  1009. // NaN patterns
  1010. mk_f32(rng.gen(), rng.gen(), 0)
  1011. } else if rng.gen() {
  1012. // Denormalized
  1013. mk_f32(rng.gen(), 0, rng.gen())
  1014. } else {
  1015. // Random anything
  1016. mk_f32(rng.gen(), rng.gen(), rng.gen())
  1017. }
  1018. }
  1019. };
  1020. }
  1021. gen_float!(gen_f32, f32, u32, 32, 23);
  1022. gen_float!(gen_f64, f64, u64, 64, 52);
  1023. macro_rules! gen_large_float {
  1024. ($name:ident,
  1025. $fty:ident,
  1026. $uty:ident,
  1027. $bits:expr,
  1028. $significand_bits:expr) => {
  1029. pub fn $name<R>(rng: &mut R) -> $fty
  1030. where
  1031. R: Rng + ?Sized,
  1032. {
  1033. const BITS: u8 = $bits;
  1034. const SIGNIFICAND_BITS: u8 = $significand_bits;
  1035. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  1036. const SIGN_MASK: $uty = (1 << (BITS - 1));
  1037. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  1038. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  1039. unsafe {
  1040. mem::transmute(
  1041. ((sign as $uty) << (BITS - 1))
  1042. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  1043. | (significand & SIGNIFICAND_MASK),
  1044. )
  1045. }
  1046. }
  1047. if rng.gen_range(0, 10) == 1 {
  1048. // Special values
  1049. *[
  1050. -0.0,
  1051. 0.0,
  1052. ::std::$fty::MIN,
  1053. ::std::$fty::MIN_POSITIVE,
  1054. ::std::$fty::MAX,
  1055. ::std::$fty::NAN,
  1056. ::std::$fty::INFINITY,
  1057. -::std::$fty::INFINITY,
  1058. ]
  1059. .choose(rng)
  1060. .unwrap()
  1061. } else if rng.gen_range(0, 10) == 1 {
  1062. // NaN patterns
  1063. mk_f32(rng.gen(), rng.gen(), 0)
  1064. } else if rng.gen() {
  1065. // Denormalized
  1066. mk_f32(rng.gen(), 0, rng.gen())
  1067. } else {
  1068. // Random anything
  1069. rng.gen::<$fty>()
  1070. }
  1071. }
  1072. };
  1073. }
  1074. gen_large_float!(gen_large_f32, f32, u32, 32, 23);
  1075. gen_large_float!(gen_large_f64, f64, u64, 64, 52);
  1076. trait TestInput: Hash + Eq + fmt::Debug {
  1077. fn ty_name() -> String;
  1078. fn generate_lets(container: &str, cnt: &mut u8) -> String;
  1079. fn generate_static(&self, dst: &mut String);
  1080. }
  1081. trait TestOutput {
  1082. fn ty_name() -> String;
  1083. fn generate_static(&self, dst: &mut String);
  1084. fn generate_expr(container: &str) -> String;
  1085. }
  1086. fn gen<F, A, R>(mut generate: F, test: &str)
  1087. where
  1088. F: FnMut(A) -> Option<R>,
  1089. A: TestInput + Copy,
  1090. R: TestOutput,
  1091. rand::distributions::Standard: rand::distributions::Distribution<A>,
  1092. {
  1093. let rng = &mut rand::thread_rng();
  1094. let testname = test.split("::").last().unwrap().split("(").next().unwrap();
  1095. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  1096. let out_file = out_dir.join("generated.rs");
  1097. let mut testcases = HashMap::new();
  1098. let mut n = NTESTS;
  1099. while n > 0 {
  1100. let input: A = rng.gen();
  1101. if testcases.contains_key(&input) {
  1102. continue;
  1103. }
  1104. let output = match generate(input) {
  1105. Some(o) => o,
  1106. None => continue,
  1107. };
  1108. testcases.insert(input, output);
  1109. n -= 1;
  1110. }
  1111. let mut contents = String::new();
  1112. contents.push_str(&format!("mod {} {{\nuse super::*;\n", testname));
  1113. contents.push_str("#[test]\n");
  1114. contents.push_str("fn test() {\n");
  1115. contents.push_str(&format!(
  1116. "static TESTS: [({}, {}); {}] = [\n",
  1117. A::ty_name(),
  1118. R::ty_name(),
  1119. NTESTS
  1120. ));
  1121. for (input, output) in testcases {
  1122. contents.push_str(" (");
  1123. input.generate_static(&mut contents);
  1124. contents.push_str(", ");
  1125. output.generate_static(&mut contents);
  1126. contents.push_str("),\n");
  1127. }
  1128. contents.push_str("];\n");
  1129. contents.push_str(&format!(
  1130. r#"
  1131. for &(inputs, output) in TESTS.iter() {{
  1132. {}
  1133. assert_eq!({}, {}, "inputs {{:?}}", inputs)
  1134. }}
  1135. "#,
  1136. A::generate_lets("inputs", &mut 0),
  1137. R::generate_expr("output"),
  1138. test,
  1139. ));
  1140. contents.push_str("\n}\n");
  1141. contents.push_str("\n}\n");
  1142. OpenOptions::new()
  1143. .write(true)
  1144. .append(true)
  1145. .create(true)
  1146. .open(out_file)
  1147. .unwrap()
  1148. .write_all(contents.as_bytes())
  1149. .unwrap();
  1150. }
  1151. macro_rules! my_float {
  1152. ($(struct $name:ident($inner:ident) = $gen:ident;)*) => ($(
  1153. #[derive(Debug, Clone, Copy)]
  1154. struct $name($inner);
  1155. impl TestInput for $name {
  1156. fn ty_name() -> String {
  1157. format!("u{}", &stringify!($inner)[1..])
  1158. }
  1159. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1160. let me = *cnt;
  1161. *cnt += 1;
  1162. format!("let {} = {}::from_bits({});\n",
  1163. (b'a' + me) as char,
  1164. stringify!($inner),
  1165. container)
  1166. }
  1167. fn generate_static(&self, dst: &mut String) {
  1168. write!(dst, "{}", self.0.to_bits()).unwrap();
  1169. }
  1170. }
  1171. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1172. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1173. $name($gen(r))
  1174. }
  1175. }
  1176. impl Hash for $name {
  1177. fn hash<H: Hasher>(&self, h: &mut H) {
  1178. self.0.to_bits().hash(h)
  1179. }
  1180. }
  1181. impl PartialEq for $name {
  1182. fn eq(&self, other: &$name) -> bool {
  1183. self.0.to_bits() == other.0.to_bits()
  1184. }
  1185. }
  1186. impl Eq for $name {}
  1187. )*)
  1188. }
  1189. my_float! {
  1190. struct MyF64(f64) = gen_f64;
  1191. struct LargeF64(f64) = gen_large_f64;
  1192. struct MyF32(f32) = gen_f32;
  1193. struct LargeF32(f32) = gen_large_f32;
  1194. }
  1195. macro_rules! my_integer {
  1196. ($(struct $name:ident($inner:ident);)*) => ($(
  1197. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
  1198. struct $name($inner);
  1199. impl TestInput for $name {
  1200. fn ty_name() -> String {
  1201. stringify!($inner).to_string()
  1202. }
  1203. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1204. let me = *cnt;
  1205. *cnt += 1;
  1206. format!("let {} = {};\n",
  1207. (b'a' + me) as char,
  1208. container)
  1209. }
  1210. fn generate_static(&self, dst: &mut String) {
  1211. write!(dst, "{}", self.0).unwrap();
  1212. }
  1213. }
  1214. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1215. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1216. let bits = (0 as $inner).count_zeros();
  1217. let mut mk = || {
  1218. if r.gen_range(0, 10) == 1 {
  1219. *[
  1220. ::std::$inner::MAX >> (bits / 2),
  1221. 0,
  1222. ::std::$inner::MIN >> (bits / 2),
  1223. ].choose(r).unwrap()
  1224. } else {
  1225. r.gen::<$inner>()
  1226. }
  1227. };
  1228. let a = mk();
  1229. let b = mk();
  1230. $name((a << (bits / 2)) | (b & (!0 << (bits / 2))))
  1231. }
  1232. }
  1233. )*)
  1234. }
  1235. my_integer! {
  1236. struct MyI32(i32);
  1237. struct MyI64(i64);
  1238. struct MyI128(i128);
  1239. struct MyU16(u16);
  1240. struct MyU32(u32);
  1241. struct MyU64(u64);
  1242. struct MyU128(u128);
  1243. }
  1244. impl<A, B> TestInput for (A, B)
  1245. where
  1246. A: TestInput,
  1247. B: TestInput,
  1248. {
  1249. fn ty_name() -> String {
  1250. format!("({}, {})", A::ty_name(), B::ty_name())
  1251. }
  1252. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1253. format!(
  1254. "{}{}",
  1255. A::generate_lets(&format!("{}.0", container), cnt),
  1256. B::generate_lets(&format!("{}.1", container), cnt)
  1257. )
  1258. }
  1259. fn generate_static(&self, dst: &mut String) {
  1260. dst.push_str("(");
  1261. self.0.generate_static(dst);
  1262. dst.push_str(", ");
  1263. self.1.generate_static(dst);
  1264. dst.push_str(")");
  1265. }
  1266. }
  1267. impl TestOutput for f64 {
  1268. fn ty_name() -> String {
  1269. "u64".to_string()
  1270. }
  1271. fn generate_static(&self, dst: &mut String) {
  1272. write!(dst, "{}", self.to_bits()).unwrap();
  1273. }
  1274. fn generate_expr(container: &str) -> String {
  1275. format!("f64::from_bits({})", container)
  1276. }
  1277. }
  1278. impl TestOutput for f32 {
  1279. fn ty_name() -> String {
  1280. "u32".to_string()
  1281. }
  1282. fn generate_static(&self, dst: &mut String) {
  1283. write!(dst, "{}", self.to_bits()).unwrap();
  1284. }
  1285. fn generate_expr(container: &str) -> String {
  1286. format!("f32::from_bits({})", container)
  1287. }
  1288. }
  1289. macro_rules! plain_test_output {
  1290. ($($i:tt)*) => ($(
  1291. impl TestOutput for $i {
  1292. fn ty_name() -> String {
  1293. stringify!($i).to_string()
  1294. }
  1295. fn generate_static(&self, dst: &mut String) {
  1296. write!(dst, "{}", self).unwrap();
  1297. }
  1298. fn generate_expr(container: &str) -> String {
  1299. container.to_string()
  1300. }
  1301. }
  1302. )*)
  1303. }
  1304. plain_test_output!(i32 i64 i128 u32 u64 u128 bool);
  1305. impl<A, B> TestOutput for (A, B)
  1306. where
  1307. A: TestOutput,
  1308. B: TestOutput,
  1309. {
  1310. fn ty_name() -> String {
  1311. format!("({}, {})", A::ty_name(), B::ty_name())
  1312. }
  1313. fn generate_static(&self, dst: &mut String) {
  1314. dst.push_str("(");
  1315. self.0.generate_static(dst);
  1316. dst.push_str(", ");
  1317. self.1.generate_static(dst);
  1318. dst.push_str(")");
  1319. }
  1320. fn generate_expr(container: &str) -> String {
  1321. container.to_string()
  1322. }
  1323. }
  1324. trait FromFloat<T>: Sized {
  1325. fn cast(src: T) -> Option<Self>;
  1326. }
  1327. macro_rules! from_float {
  1328. ($($src:ident => $($dst:ident),+);+;) => {
  1329. $(
  1330. $(
  1331. impl FromFloat<$src> for $dst {
  1332. fn cast(src: $src) -> Option<$dst> {
  1333. use std::{$dst, $src};
  1334. if src.is_nan() ||
  1335. src.is_infinite() ||
  1336. src < std::$dst::MIN as $src ||
  1337. src > std::$dst::MAX as $src
  1338. {
  1339. None
  1340. } else {
  1341. Some(src as $dst)
  1342. }
  1343. }
  1344. }
  1345. )+
  1346. )+
  1347. }
  1348. }
  1349. from_float! {
  1350. f32 => i32, i64, i128, u32, u64, u128;
  1351. f64 => i32, i64, i128, u32, u64, u128;
  1352. }