12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- use std::env;
- use std::error::Error;
- use std::fs::File;
- use std::io::Write;
- use std::path::Path;
- fn main() {
- let pointer_width = env::var("CARGO_CFG_TARGET_POINTER_WIDTH");
- let u64_digit = pointer_width.as_ref().map(String::as_str) == Ok("64");
- if u64_digit {
- autocfg::emit("u64_digit");
- }
- let ac = autocfg::new();
- let std = if ac.probe_sysroot_crate("std") {
- "std"
- } else {
- "core"
- };
- if ac.probe_path(&format!("{}::convert::TryFrom", std)) {
- autocfg::emit("has_try_from");
- }
- if let Ok(target_arch) = env::var("CARGO_CFG_TARGET_ARCH") {
- if target_arch == "x86_64" || target_arch == "x86" {
- let digit = if u64_digit { "u64" } else { "u32" };
- let addcarry = format!("{}::arch::{}::_addcarry_{}", std, target_arch, digit);
- if ac.probe_path(&addcarry) {
- autocfg::emit("use_addcarry");
- }
- }
- }
- autocfg::rerun_path("build.rs");
- write_radix_bases().unwrap();
- }
- /// Write tables of the greatest power of each radix for the given bit size. These are returned
- /// from `biguint::get_radix_base` to batch the multiplication/division of radix conversions on
- /// full `BigUint` values, operating on primitive integers as much as possible.
- ///
- /// e.g. BASES_16[3] = (59049, 10) // 3¹⁰ fits in u16, but 3¹¹ is too big
- /// BASES_32[3] = (3486784401, 20)
- /// BASES_64[3] = (12157665459056928801, 40)
- ///
- /// Powers of two are not included, just zeroed, as they're implemented with shifts.
- fn write_radix_bases() -> Result<(), Box<dyn Error>> {
- let out_dir = env::var("OUT_DIR")?;
- let dest_path = Path::new(&out_dir).join("radix_bases.rs");
- let mut f = File::create(&dest_path)?;
- for &bits in &[16, 32, 64] {
- let max = if bits < 64 {
- (1 << bits) - 1
- } else {
- std::u64::MAX
- };
- writeln!(f, "#[deny(overflowing_literals)]")?;
- writeln!(
- f,
- "pub(crate) static BASES_{bits}: [(u{bits}, usize); 257] = [",
- bits = bits
- )?;
- for radix in 0u64..257 {
- let (base, power) = if radix == 0 || radix.is_power_of_two() {
- (0, 0)
- } else {
- let mut power = 1;
- let mut base = radix;
- while let Some(b) = base.checked_mul(radix) {
- if b > max {
- break;
- }
- base = b;
- power += 1;
- }
- (base, power)
- };
- writeln!(f, " ({}, {}), // {}", base, power, radix)?;
- }
- writeln!(f, "];")?;
- }
- Ok(())
- }
|