diff --git a/.trinity/seals/t27o_T27oRust.json b/.trinity/seals/t27o_T27oRust.json index 92494d9929..ce1ed15a37 100644 --- a/.trinity/seals/t27o_T27oRust.json +++ b/.trinity/seals/t27o_T27oRust.json @@ -1,24 +1,24 @@ { - "built_by": "t27c-bootstrap@0.5.2+9b556b7c3", + "built_by": "t27c-bootstrap@0.5.2+ea35d9b72", "closure": [], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:f216bb9d9ee61310da89f4d1114da4f4afa9a880dc5a77164860bdd96c2fcc3f", - "gen_hash_rust": "sha256:c025cfe293fedf700a7d7f966bc31d19c1de3460819c32b50174de95a73e2030", - "gen_hash_verilog": "sha256:8d463b642b44413987840eb20795b578a52ff0ee0dd493aa9555f14818e19f74", - "gen_hash_zig": "sha256:66f6cec03c60836e7c41041e52bae957b4545550bf70251b1e1a7731c52fffab", + "gen_hash_c": "sha256:08df0e325d4acb3d37cda78c58f0752a3454fdd64190e33bd7719233129e986a", + "gen_hash_rust": "sha256:ae90e0046b61cf596e6114e14c62abeaed343a834d5131d981058727a54ba933", + "gen_hash_verilog": "sha256:e0f53958647f52ef5b82d57d3553e4bada519d5ce98e78a861d2cbb74bcf1d49", + "gen_hash_zig": "sha256:1d85bad0405fe228eae8ad363edb6fb76b26e9ee87cf7aa0fadac43c49483f4a", "module": "T27oRust", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T20:43:31Z", + "sealed_at": "2026-10-19T02:57:39Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:7960832212d5781ccfec0c213b5829caebf2c13ab27e01fc06b8c5b0a1ec60de", + "spec_hash": "sha256:11f3aefa0a152d9ca963773018e35b1e39730ac53b25604be67252aaf85522a3", "spec_path": "specs/tools/t27o/rust_convert.t27", "tests": { "failed": 0, "failing": [], "forced": false, - "passed": 107, - "total": 107, + "passed": 128, + "total": 128, "vacuous": 0 }, "toolchain": { diff --git a/.trinity/seals/t27o_T27oRustStd.json b/.trinity/seals/t27o_T27oRustStd.json index c9298463cc..e7402c6cdb 100644 --- a/.trinity/seals/t27o_T27oRustStd.json +++ b/.trinity/seals/t27o_T27oRustStd.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+9b556b7c3", + "built_by": "t27c-bootstrap@0.5.2+ea35d9b72", "closure": [ { "spec": "specs/hosting/toolchain.t27", @@ -15,23 +15,23 @@ } ], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:e2f3310cb7a4bc69c3719299098b247d1b4deac743249978de470617b8abc7f1", - "gen_hash_rust": "sha256:054308d17bce7b04be20ef206e53be8ec05ff7174609b2598bcadc2dc38cdbd7", - "gen_hash_verilog": "sha256:ae1350281fd19042bc344b29572b65a18760f4d1d7f0a7703b1b03be9cd7137e", - "gen_hash_zig": "sha256:df61571a23405733bc65b2641f0e32e59098be2cc60f857c963c3a1bfeadb556", + "gen_hash_c": "sha256:cef0604f716d2aa7f0a21b5dabb8af9eac42cfd7528bf0aaf5c140fd00723739", + "gen_hash_rust": "sha256:fa9767acc5685bdce7cd03f7d542545c60e718a44f4b75533aac9856dcf2234d", + "gen_hash_verilog": "sha256:6ce3da44fac0d82bcc12c8c522641b21edd45b0ed84abcfc65fb2321bf0b8557", + "gen_hash_zig": "sha256:3a854380824358f5e294a1c9a0e180717706e4b0f89be2b65635b9443b56326e", "module": "T27oRustStd", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T17:04:56Z", + "sealed_at": "2026-10-19T02:57:25Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:ee1cf77e327861bfa2fe6ae0d4179a610f24e5603d028a53b075739448c0e73a", + "spec_hash": "sha256:66a569db8a5e54879d6958aa47e96942e80615d5d5ac5a9b03b8a6222da6e024", "spec_path": "specs/tools/t27o/rust_std.t27", "tests": { "failed": 0, "failing": [], "forced": false, - "passed": 11, - "total": 11, + "passed": 61, + "total": 61, "vacuous": 0 }, "toolchain": { diff --git a/gen/rust/tools/t27o/rust_convert.rs b/gen/rust/tools/t27o/rust_convert.rs index 91974c8794..bd8baf3bc3 100644 --- a/gen/rust/tools/t27o/rust_convert.rs +++ b/gen/rust/tools/t27o/rust_convert.rs @@ -1,6 +1,6 @@ // Generated from .t27 spec // DO NOT EDIT — generated by t27c -// NOT LOWERED BY THIS BACKEND: 107 test(s), 0 invariant(s), 0 function(s) with no body. +// NOT LOWERED BY THIS BACKEND: 128 test(s), 0 invariant(s), 0 function(s) with no body. // This backend emits declarations only. The spec's checks live in // the Zig and Verilog outputs; do not read this file as verified. @@ -300,6 +300,8 @@ pub const R_VECMOVE: usize = 35; pub const R_VECTYPE: usize = 36; +pub const R_LIBM: usize = 37; + pub const VU_READ: usize = 0; pub const VU_CHANGED: usize = 1; @@ -374,6 +376,8 @@ pub const B_RBRACKET: u8 = 93; pub const B_CARET: u8 = 94; +pub const B_AT: u8 = 64; + pub const B_UNDERSCORE: u8 = 95; pub const B_LOWER_A: u8 = 97; @@ -2567,7 +2571,9 @@ pub fn unit_result_fn(src: &[u8], st: &mut [usize], a: usize, b: usize) -> bool pub fn type_class(src: &[u8], st: &mut [usize], d: usize) -> u8 { let mut q: usize = d; + let mut by_ref: bool = false; while (tok_is(src, q, b"&") || tok_is(src, q, b"&&")) { + by_ref = true; q = skip_ws(src, tok_end(src, q)); if ((q < src.len()) && (src[(q) as usize] == B_APOS)) { q = skip_ws(src, tok_end(src, q)); @@ -2596,7 +2602,7 @@ pub fn type_class(src: &[u8], st: &mut [usize], d: usize) -> u8 { let mut el: usize = src.len(); if word_is(src, q, e, b"[") { el = skip_ws(src, e); - if (find_at(src, el, B_SEMI) < find_at(src, el, B_RBRACKET)) { + if ((find_at(src, el, B_SEMI) < find_at(src, el, B_RBRACKET)) && !(by_ref)) { st[(TYARR) as usize] = 1; } } @@ -2839,6 +2845,54 @@ pub fn str_chain(src: &[u8], st: &mut [usize], a: usize, b: usize) -> bool { return true; } +pub fn cast_class(src: &[u8], st: &mut [usize], lp: usize) -> u8 { + let close: usize = (block_end(src, lp) - 1); + let mut as_at: usize = src.len(); + let mut q: usize = skip_ws(src, (lp + 1)); + while (q < close) { + let e: usize = tok_end(src, q); + if ((e == (q + 1)) && is_open(src[(q) as usize])) { + q = skip_ws(src, block_end(src, q)); + } else { + if word_is(src, q, e, b"as") { + as_at = q; + } + q = skip_ws(src, e); + } + } + if (as_at >= src.len()) { + return C_ANY; + } + let t: usize = skip_ws(src, tok_end(src, as_at)); + if (skip_ws(src, tok_end(src, t)) != close) { + return C_ANY; + } + let c: u8 = type_class(src, st, t); + if ((c == C_INT) || (c == C_FLOAT)) { + return c; + } + return C_ANY; +} + +pub fn len_tail(src: &[u8], ra: usize, rb: usize) -> usize { + let mut t1: usize = src.len(); + let mut t2: usize = src.len(); + let mut t3: usize = src.len(); + let mut t4: usize = src.len(); + let mut q: usize = ra; + while ((q < rb) && (q < src.len())) { + t1 = t2; + t2 = t3; + t3 = t4; + t4 = q; + q = skip_ws(src, tok_end(src, q)); + } + if (((((t1 < src.len()) && tok_is(src, t4, b")")) && tok_is(src, t3, b"(")) && word_is(src, t2, tok_end(src, t2), b"len")) && tok_is(src, t1, b".")) { + return t2; + } + return src.len(); +} + pub fn recv_class(src: &[u8], st: &mut [usize], ra: usize, rb: usize) -> u8 { st[(TYLO) as usize] = 0; st[(TYHI) as usize] = 0; @@ -2846,6 +2900,23 @@ pub fn recv_class(src: &[u8], st: &mut [usize], ra: usize, rb: usize) -> u8 { if ((ra >= rb) || (ra >= src.len())) { return C_ANY; } + if ((src[(ra) as usize] == B_LPAREN) && (skip_ws(src, block_end(src, ra)) >= rb)) { + let cast: u8 = cast_class(src, st, ra); + if (cast != C_ANY) { + return cast; + } + } + let lt: usize = len_tail(src, ra, rb); + if (lt < src.len()) { + let own: u8 = ret_class(src, st, lt, tok_end(src, lt)); + st[(TYLO) as usize] = 0; + st[(TYHI) as usize] = 0; + st[(TYARR) as usize] = 0; + if (own == C_NONE) { + st[(TYARR) as usize] = 2; + return C_INT; + } + } let e: usize = tok_end(src, ra); let nx: usize = skip_ws(src, e); if (nx >= rb) { @@ -2914,6 +2985,9 @@ pub fn recv_class(src: &[u8], st: &mut [usize], ra: usize, rb: usize) -> u8 { while (q < rb) { let qe: usize = tok_end(src, q); let mut k: u8 = C_ANY; + st[(TYLO) as usize] = 0; + st[(TYHI) as usize] = 0; + st[(TYARR) as usize] = 0; if is_digit(src[(q) as usize]) { k = literal_class(src, st, q); } else { @@ -2949,7 +3023,7 @@ pub fn recv_class(src: &[u8], st: &mut [usize], ra: usize, rb: usize) -> u8 { } pub fn std_bool(src: &[u8], a: usize, b: usize) -> bool { - let w: &'static str = " is_empty starts_with ends_with contains is_some is_none is_ok is_err eq is_ascii_alphabetic is_ascii_alphanumeric is_ascii_digit all "; + let w: &'static str = " is_empty starts_with ends_with contains is_some is_none is_ok is_err eq is_ascii_alphabetic is_ascii_alphanumeric is_ascii_digit all is_finite is_ascii "; return listed(w, &src[(a) as usize..(b) as usize]); } @@ -3345,19 +3419,19 @@ pub const STD_MODS: [&'static str; 5] = ["", "tools::t27o::rust_std", "hosting:: pub const MOD_TTEXT: u8 = 4; -pub const STD_N: usize = 55; +pub const STD_N: usize = 75; -pub const STD_NAME: [&'static str; 55] = ["len", "is_empty", "as_bytes", "as_str", "as_slice", "clone", "abs", "abs", "min", "max", "cmp::min", "cmp::max", "wrapping_add", "wrapping_sub", "wrapping_mul", "checked_add", "checked_sub", "checked_mul", "trim", "trim_start", "trim_end", "starts_with", "ends_with", "contains", "contains", "parse", "iter.sum", "iter.count", "unwrap", "expect", "is_some", "is_none", "is_ok", "is_err", "is_ok", "is_err", "ok", "ok_or", "context", "eq", "is_ascii_alphabetic", "is_ascii_alphanumeric", "is_ascii_digit", "chars", "find", "find", "trim_start_matches", "trim_start_matches", "trim_end_matches", "trim_end_matches", "strip_prefix", "strip_prefix", "strip_suffix", "strip_suffix", "starts_with"]; +pub const STD_NAME: [&'static str; 75] = ["len", "is_empty", "as_bytes", "as_str", "as_slice", "clone", "abs", "abs", "min", "max", "cmp::min", "cmp::max", "wrapping_add", "wrapping_sub", "wrapping_mul", "checked_add", "checked_sub", "checked_mul", "trim", "trim_start", "trim_end", "starts_with", "ends_with", "contains", "contains", "parse", "iter.sum", "iter.count", "unwrap", "expect", "is_some", "is_none", "is_ok", "is_err", "is_ok", "is_err", "ok", "ok_or", "context", "eq", "is_ascii_alphabetic", "is_ascii_alphanumeric", "is_ascii_digit", "chars", "find", "find", "trim_start_matches", "trim_start_matches", "trim_end_matches", "trim_end_matches", "strip_prefix", "strip_prefix", "strip_suffix", "strip_suffix", "starts_with", "count_ones", "leading_zeros", "trailing_zeros", "pow", "saturating_add", "saturating_sub", "saturating_mul", "div_ceil", "sqrt", "is_finite", "to_bits", "is_ascii", "is_ascii", "is_ascii", "to_ascii_lowercase", "to_ascii_uppercase", "get", "contains", "contains.char", "unwrap_or"]; -pub const STD_CLASS: [u8; 55] = [0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]; +pub const STD_CLASS: [u8; 75] = [0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 4, 2, 2, 2, 4, 4, 3, 0]; -pub const STD_ARGS: [u8; 55] = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +pub const STD_ARGS: [u8; 75] = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]; -pub const STD_FORM: [&'static str; 55] = ["#.len", "(#.len == 0)", "#", "#", "#", "#", "@abs(#)", "rust_std::abs_%(#)", "@min(#, $)", "@max(#, $)", "@min(#)", "@max(#)", "(# +% $)", "(# -% $)", "(# *% $)", "rust_std::checked_add_%(#, $)", "rust_std::checked_sub_%(#, $)", "rust_std::checked_mul_%(#, $)", "#[type_text::trim_lo(#, 0, #.len) .. type_text::trim_hi(#, type_text::trim_lo(#, 0, #.len), #.len)]", "#[type_text::trim_lo(#, 0, #.len) .. #.len]", "#[0 .. type_text::trim_hi(#, 0, #.len)]", "toolchain::starts_with(#, $)", "toolchain::ends_with(#, $t)", "rust_std::str_contains(#, $t)", "rust_std::bytes_contain(#, $)", "rust_std::parse_%(#)", "rust_std::sum_%(#)", "#.len", "#.?", "#.?", "(# != null)", "(# == null)", "#", "(# == false)", "(# != null)", "(# == null)", "#", "#", "#", "type_text::same(#, $)", "type_text::alpha(#)", "rust_std::alnum(#)", "type_text::digit(#)", "#", "rust_std::find_text(#, $)", "rust_std::find_byte(#, $)", "rust_std::trim_start_matches_text(#, $)", "rust_std::trim_start_matches_byte(#, $)", "rust_std::trim_end_matches_text(#, $)", "rust_std::trim_end_matches_byte(#, $)", "rust_std::strip_prefix_text(#, $)", "rust_std::strip_prefix_byte(#, $)", "rust_std::strip_suffix_text(#, $)", "rust_std::strip_suffix_byte(#, $)", "rust_std::starts_with_byte(#, $)"]; +pub const STD_FORM: [&'static str; 75] = ["#.len", "(#.len == 0)", "#", "#", "#", "#", "@abs(#)", "rust_std::abs_%(#)", "@min(#, $)", "@max(#, $)", "@min(#)", "@max(#)", "(# +% $)", "(# -% $)", "(# *% $)", "rust_std::checked_add_%(#, $)", "rust_std::checked_sub_%(#, $)", "rust_std::checked_mul_%(#, $)", "#[type_text::trim_lo(#, 0, #.len) .. type_text::trim_hi(#, type_text::trim_lo(#, 0, #.len), #.len)]", "#[type_text::trim_lo(#, 0, #.len) .. #.len]", "#[0 .. type_text::trim_hi(#, 0, #.len)]", "toolchain::starts_with(#, $)", "toolchain::ends_with(#, $t)", "rust_std::str_contains(#, $t)", "rust_std::bytes_contain(#, $)", "rust_std::parse_%(#)", "rust_std::sum_%(#)", "#.len", "#.?", "#.?", "(# != null)", "(# == null)", "#", "(# == false)", "(# != null)", "(# == null)", "#", "#", "#", "type_text::same(#, $)", "type_text::alpha(#)", "rust_std::alnum(#)", "type_text::digit(#)", "#", "rust_std::find_text(#, $)", "rust_std::find_byte(#, $)", "rust_std::trim_start_matches_text(#, $)", "rust_std::trim_start_matches_byte(#, $)", "rust_std::trim_end_matches_text(#, $)", "rust_std::trim_end_matches_byte(#, $)", "rust_std::strip_prefix_text(#, $)", "rust_std::strip_prefix_byte(#, $)", "rust_std::strip_suffix_text(#, $)", "rust_std::strip_suffix_byte(#, $)", "rust_std::starts_with_byte(#, $)", "rust_std::count_ones_%(#)", "rust_std::leading_zeros_%(#)", "rust_std::trailing_zeros_%(#)", "rust_std::pow_%(#, $)", "rust_std::saturating_add_%(#, $)", "rust_std::saturating_sub_%(#, $)", "rust_std::saturating_mul_%(#, $)", "rust_std::div_ceil_%(#, $)", "@sqrt(#)", "rust_std::is_finite_%(#)", "rust_std::to_bits_%(#)", "rust_std::is_ascii_text(#)", "rust_std::is_ascii_text(#)", "rust_std::is_ascii_%(#)", "rust_std::to_ascii_lowercase_%(#)", "rust_std::to_ascii_uppercase_%(#)", "rust_std::get_%(#, $)", "rust_std::contains_%(#, $)", "rust_std::str_contains_char(#, $)", "if (# != null) { ^.? } else { $ }"]; -pub const STD_TYPES: [&'static str; 55] = ["", "", "", "", "", "", "", " i8 i16 i32 i64 ", "", "", "", "", "", "", "", " u32 u64 usize i32 i64 ", " u32 u64 usize i32 i64 ", " u32 u64 usize i32 i64 ", "", "", "", "", "", "", " u8 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u32 u64 usize i32 i64 f32 f64 ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]; +pub const STD_TYPES: [&'static str; 75] = ["", "", "", "", "", "", "", " i8 i16 i32 i64 ", "", "", "", "", "", "", "", " u32 u64 usize i32 i64 ", " u32 u64 usize i32 i64 ", " u32 u64 usize i32 i64 ", "", "", "", "", "", "", " u8 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u32 u64 usize i32 i64 f32 f64 ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize ", "", " f32 f64 ", " f32 f64 ", "", " u8 ", " u8 ", " u8 ", " u8 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 f32 f64 ", " u16 u32 u64 usize i8 i16 i32 i64 f32 f64 ", "", ""]; -pub const STD_USE: [u8; 55] = [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 4, 4, 4, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +pub const STD_USE: [u8; 75] = [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 4, 4, 4, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]; pub fn listed(w: &'static str, t: &[u8]) -> bool { if (t.len() == 0) { @@ -3440,9 +3514,84 @@ pub fn wrap_pct(form: &'static str, i: usize) -> bool { return ((i > 0) && (((form.as_bytes()[((i - 1)) as usize] == B_PLUS) || (form.as_bytes()[((i - 1)) as usize] == B_MINUS)) || (form.as_bytes()[((i - 1)) as usize] == B_STAR))); } +pub fn out_holds(out: &[u8], at: usize, s: &[u8]) -> bool { + if ((at + s.len()) > out.len()) { + return false; + } + let mut k: usize = 0; + while (k < s.len()) { + if (out[((at + k)) as usize] != s[(k) as usize]) { + return false; + } + k = (k + 1); + } + return true; +} + +pub fn pure_callee(out: &[u8], j: usize) -> bool { + if (out[(j) as usize] == B_AT) { + return true; + } + if out_holds(out, j, b"rust_std::append_") { + return false; + } + return ((out_holds(out, j, b"rust_std::") || out_holds(out, j, b"type_text::")) || out_holds(out, j, b"toolchain::")); +} + +pub fn pure_out(out: &[u8], a: usize, b: usize) -> bool { + if (b > out.len()) { + return true; + } + let mut i: usize = a; + while (i < b) { + if (out[(i) as usize] == B_LPAREN) { + let mut j: usize = i; + while ((j > a) && (((is_alpha(out[((j - 1)) as usize]) || is_digit(out[((j - 1)) as usize])) || (out[((j - 1)) as usize] == B_COLON)) || (out[((j - 1)) as usize] == B_AT))) { + j = (j - 1); + } + if ((j < i) && !(pure_callee(out, j))) { + return false; + } + } + i = (i + 1); + } + return true; +} + +pub fn find_ty(name: &[u8], cls: u8, src: &[u8], tyl: usize, tyh: usize, usz: bool) -> usize { + if usz { + return find(name, cls, b"usize"); + } + return find(name, cls, &src[(tyl) as usize..(tyh) as usize]); +} + +pub fn alone_as_value(src: &[u8], out: &[u8], start: usize, lp: usize) -> bool { + let mut ok: bool = false; + if (start <= out.len()) { + let mut i: usize = start; + while ((i > 0) && (out[((i - 1)) as usize] == B_SPACE)) { + i = (i - 1); + } + if ((i == 0) || (out[((i - 1)) as usize] == B_NL)) { + ok = true; + } + } + if ((start >= 4) && out_holds(out, (start - 3), b" = ")) { + let op: u8 = out[((start - 4)) as usize]; + ok = ((((((((((((op != B_EQ) && (op != B_BANG)) && (op != B_LT)) && (op != B_GT)) && (op != B_PLUS)) && (op != B_MINUS)) && (op != B_STAR)) && (op != B_SLASH)) && (op != B_PCT)) && (op != B_AMP)) && (op != B_PIPE)) && (op != B_CARET)); + } + if !(ok) { + return false; + } + let after: usize = skip_ws(src, block_end(src, lp)); + return ((tok_is(src, after, b";") || tok_is(src, after, b",")) || tok_is(src, after, b"}")); +} + pub fn expand(src: &[u8], st: &mut [usize], out: &mut [u8], start: usize, k: usize, ra: usize, rb: usize, tyl: usize, tyh: usize, cls: u8) -> () { let form: &'static str = STD_FORM[(k) as usize]; let nargs: u8 = STD_ARGS[(k) as usize]; + let rlen: usize = (st[(W) as usize] - start); + let usz: bool = (st[(TYARR) as usize] == 2); let mut h: usize = 0; while ((h < form.len()) && (form.as_bytes()[(h) as usize] != B_HASH)) { h = (h + 1); @@ -3450,16 +3599,22 @@ pub fn expand(src: &[u8], st: &mut [usize], out: &mut [u8], start: usize, k: usi let mut pos: usize = start; let mut i: usize = 0; while (i < h) { - if ((form.as_bytes()[(i) as usize] == B_PCT) && !(wrap_pct(form, i))) { - insert_src(src, st, out, pos, tyl, tyh); - pos = (pos + (tyh - tyl)); + if (((form.as_bytes()[(i) as usize] == B_PCT) && !(wrap_pct(form, i))) && usz) { + insert(st, out, pos, b"usize"); + pos = (pos + 5); } else { - insert_byte(st, out, pos, form.as_bytes()[(i) as usize]); - pos = (pos + 1); + if ((form.as_bytes()[(i) as usize] == B_PCT) && !(wrap_pct(form, i))) { + insert_src(src, st, out, pos, tyl, tyh); + pos = (pos + (tyh - tyl)); + } else { + insert_byte(st, out, pos, form.as_bytes()[(i) as usize]); + pos = (pos + 1); + } } i = (i + 1); } - if (((cls == C_SLICE) && (st[(TYARR) as usize] == 1)) && (h > 0)) { + let rpos: usize = pos; + if ((((cls == C_SLICE) && (st[(TYARR) as usize] == 1)) && (h > 0)) && (STD_CLASS[(k) as usize] != C_ANY)) { insert(st, out, pos, b"&"); } if (nargs == 0) { @@ -3492,13 +3647,30 @@ pub fn expand(src: &[u8], st: &mut [usize], out: &mut [u8], start: usize, k: usi } used = true; } else { - if ((c == B_PCT) && !(wrap_pct(form, j))) { - put_src(src, st, out, tyl, tyh); + if (((c == B_PCT) && !(wrap_pct(form, j))) && usz) { + puts(st, out, b"usize"); } else { - if ((c == B_HASH) && (ra < rb)) { - put_src(src, st, out, ra, rb); + if ((c == B_PCT) && !(wrap_pct(form, j))) { + put_src(src, st, out, tyl, tyh); } else { - put(st, out, c); + if (c == B_CARET) { + let mut r: usize = 0; + while (r < rlen) { + let rb2: usize = (rpos + r); + if (rb2 < out.len()) { + put(st, out, out[(rb2) as usize]); + } else { + put(st, out, 0); + } + r = (r + 1); + } + } else { + if ((c == B_HASH) && (ra < rb)) { + put_src(src, st, out, ra, rb); + } else { + put(st, out, c); + } + } } } } @@ -3666,6 +3838,21 @@ pub fn digit_closure(src: &[u8], p: usize) -> bool { return (all_closure(src, p) == 1); } +pub fn char_var(src: &[u8], flo: usize, ar: usize) -> bool { + if ((ar >= src.len()) || !(is_alpha(src[(ar) as usize]))) { + return false; + } + let e: usize = tok_end(src, ar); + if !(tok_is(src, skip_ws(src, e), b")")) { + return false; + } + let d: usize = decl_type(src, flo, ar, ar, e); + if (d >= src.len()) { + return false; + } + return word_is(src, d, tok_end(src, d), b"char"); +} + pub fn method(src: &[u8], st: &mut [usize], out: &mut [u8], start: usize, ra: usize, rb: usize, na: usize, nb: usize, tla: usize, tlb: usize) -> () { if ((st[(FORHDR) as usize] == 1) && (word_is(src, na, nb, b"iter") || word_is(src, na, nb, b"enumerate"))) { if word_is(src, na, nb, b"enumerate") { @@ -3763,6 +3950,7 @@ pub fn method(src: &[u8], st: &mut [usize], out: &mut [u8], start: usize, ra: us return (); } let cls: u8 = recv_class(src, st, ra, rb); + let usz: bool = (st[(TYARR) as usize] == 2); let mut tyl: usize = st[(TYLO) as usize]; let mut tyh: usize = st[(TYHI) as usize]; if (cb > ca) { @@ -3774,20 +3962,34 @@ pub fn method(src: &[u8], st: &mut [usize], out: &mut [u8], start: usize, ra: us tyl = li; tyh = tok_end(src, li); } + if ((!(chain) && word_is(src, na, nb, b"unwrap_or")) && (!(pure_out(out, start, st[(W) as usize])) || !(alone_as_value(src, out, start, st[(P) as usize])))) { + refuse(st, R_METHOD, ka, ka, kb); + return (); + } let mut k: usize = STD_N; if chain { if word_is(src, ka, kb, b"sum") { - k = find(b"iter.sum", cls, &src[(tyl) as usize..(tyh) as usize]); + k = find_ty(b"iter.sum", cls, src, tyl, tyh, usz); } else { - k = find(b"iter.count", cls, &src[(tyl) as usize..(tyh) as usize]); + k = find_ty(b"iter.count", cls, src, tyl, tyh, usz); } } else { - k = find(&src[(na) as usize..(nb) as usize], cls, &src[(tyl) as usize..(tyh) as usize]); + k = find_ty(&src[(na) as usize..(nb) as usize], cls, src, tyl, tyh, usz); } if (k >= STD_N) { + if word_is(src, na, nb, b"ln") { + refuse(st, R_LIBM, ka, ka, kb); + return (); + } refuse(st, R_METHOD, ka, ka, kb); return (); } + if (((!(chain) && word_is(src, na, nb, b"contains")) && (cls == C_STR)) && char_var(src, st[(FLO) as usize], skip_ws(src, (st[(P) as usize] + 1)))) { + let kc: usize = find(b"contains.char", C_STR, b""); + if (kc < STD_N) { + k = kc; + } + } if (!(chain) && (STD_ARGS[(k) as usize] == 1)) { let ar: usize = skip_ws(src, (st[(P) as usize] + 1)); if ((ar < src.len()) && (src[(ar) as usize] == B_APOS)) { @@ -3814,7 +4016,13 @@ pub fn method(src: &[u8], st: &mut [usize], out: &mut [u8], start: usize, ra: us k = hit; } } + if usz { + st[(TYARR) as usize] = 2; + } expand(src, st, out, start, k, ra, rb, tyl, tyh, cls); + if ((!(chain) && word_is(src, na, nb, b"unwrap_or")) && !(pure_out(out, start, st[(W) as usize]))) { + refuse(st, R_METHOD, ka, ka, kb); + } } pub fn bit(n: usize) -> usize { @@ -6735,10 +6943,14 @@ pub fn put_reason(src: &[u8], st: &mut [usize], out: &mut [u8]) -> () { if (c == R_VECTYPE) { puts(st, out, b"a vec! whose element type or length t27o cannot tell"); } else { - if (c == R_SPLICE) { - puts(st, out, b"a used module's own use t27c does not splice (its type_text:: names stay unresolved, the gap specs/compiler/int_type_names.t27 records)"); + if (c == R_LIBM) { + puts(st, out, b"libm function not bit-exact"); } else { - puts(st, out, b"syntax"); + if (c == R_SPLICE) { + puts(st, out, b"a used module's own use t27c does not splice (its type_text:: names stay unresolved, the gap specs/compiler/int_type_names.t27 records)"); + } else { + puts(st, out, b"syntax"); + } } } } diff --git a/specs/tools/t27o/rust_convert.t27 b/specs/tools/t27o/rust_convert.t27 index c3b5e0a4fc..9c56619878 100644 --- a/specs/tools/t27o/rust_convert.t27 +++ b/specs/tools/t27o/rust_convert.t27 @@ -321,6 +321,8 @@ pub const R_NOTYPE : usize = 33; pub const R_VECMUT : usize = 34; pub const R_VECMOVE : usize = 35; pub const R_VECTYPE : usize = 36; +/// A float function Rust gets from the platform's libm: its last bit is the library's, not IEEE 754's. +pub const R_LIBM : usize = 37; /// How a fn uses a vec! local: VU_READ only reads it, VU_CHANGED changes it, VU_MOVED hands it on. pub const VU_READ : usize = 0; pub const VU_CHANGED : usize = 1; @@ -361,6 +363,7 @@ pub const B_LBRACKET : u8 = 91; pub const B_BACKSLASH : u8 = 92; pub const B_RBRACKET : u8 = 93; pub const B_CARET : u8 = 94; +pub const B_AT : u8 = 64; pub const B_UNDERSCORE : u8 = 95; pub const B_LOWER_A : u8 = 97; pub const B_LOWER_B : u8 = 98; @@ -2294,7 +2297,9 @@ pub fn unit_result_fn(src: []const u8, st: []usize, a: usize, b: usize) -> bool /// to st[TYLO .. TYHI], and st[TYARR] says whether it is an array. pub fn type_class(src: []const u8, st: []usize, d: usize) -> u8 { var q : usize = d; + var by_ref : bool = false; while (tok_is(src, q, "&") or tok_is(src, q, "&&")) { + by_ref = true; q = skip_ws(src, tok_end(src, q)); if (q < src.len and src[q] == B_APOS) { q = skip_ws(src, tok_end(src, q)); } if (tok_is(src, q, "mut")) { q = skip_ws(src, tok_end(src, q)); } @@ -2315,7 +2320,9 @@ pub fn type_class(src: []const u8, st: []usize, d: usize) -> u8 { var el : usize = src.len; if (word_is(src, q, e, "[")) { el = skip_ws(src, e); - if (find_at(src, el, B_SEMI) < find_at(src, el, B_RBRACKET)) { st[TYARR] = 1; } + // `&[T; N]` is written as a slice (&T as T would make it an array, a parameter is a slice), so only an + // array held by value is passed on to a slice parameter by address + if (find_at(src, el, B_SEMI) < find_at(src, el, B_RBRACKET) and !by_ref) { st[TYARR] = 1; } } if (word_is(src, q, e, "Vec") and tok_is(src, skip_ws(src, e), "<")) { el = skip_ws(src, skip_ws(src, e) + 1); } if (el < src.len) { @@ -2514,6 +2521,48 @@ pub fn str_chain(src: []const u8, st: []usize, a: usize, b: usize) -> bool { return true; } +/// The class of `(.. as T)`, the group opening at the `(` src[lp], when the cast is its last step: +/// T's, its type token in st[TYLO .. TYHI]. C_ANY for any other group, and for a cast to a type that is +/// neither an integer nor a float. `(n as u64).pow(2)` is a u64 whatever type `n` is declared with. +pub fn cast_class(src: []const u8, st: []usize, lp: usize) -> u8 { + const close : usize = block_end(src, lp) - 1; + var as_at : usize = src.len; + var q : usize = skip_ws(src, lp + 1); + while (q < close) { + const e : usize = tok_end(src, q); + if (e == q + 1 and is_open(src[q])) { + q = skip_ws(src, block_end(src, q)); + } else { + if (word_is(src, q, e, "as")) { as_at = q; } + q = skip_ws(src, e); + } + } + if (as_at >= src.len) { return C_ANY; } + const t : usize = skip_ws(src, tok_end(src, as_at)); + if (skip_ws(src, tok_end(src, t)) != close) { return C_ANY; } + const c : u8 = type_class(src, st, t); + if (c == C_INT or c == C_FLOAT) { return c; } + return C_ANY; +} + +/// The position of the `len` token when the receiver src[ra .. rb] ends in `.len()`, src.len otherwise. +pub fn len_tail(src: []const u8, ra: usize, rb: usize) -> usize { + var t1 : usize = src.len; + var t2 : usize = src.len; + var t3 : usize = src.len; + var t4 : usize = src.len; + var q : usize = ra; + while (q < rb and q < src.len) { + t1 = t2; + t2 = t3; + t3 = t4; + t4 = q; + q = skip_ws(src, tok_end(src, q)); + } + if (t1 < src.len and tok_is(src, t4, ")") and tok_is(src, t3, "(") and word_is(src, t2, tok_end(src, t2), "len") and tok_is(src, t1, ".")) { return t2; } + return src.len; +} + /// The class of the receiver src[ra .. rb]: a literal, a name, `self.f`, a call of this file's fn by /// its return type, or any other expression: a float when a float literal, float name or `as f64` is in /// it, else an integer when an integer name is. C_BOOL is a call of a fn returning Result<(), E>. @@ -2522,6 +2571,24 @@ pub fn recv_class(src: []const u8, st: []usize, ra: usize, rb: usize) -> u8 { st[TYHI] = 0; st[TYARR] = 0; if (ra >= rb or ra >= src.len) { return C_ANY; } + // `(expr as T)`: the cast names the receiver's type, whatever the names inside it are declared as + if (src[ra] == B_LPAREN and skip_ws(src, block_end(src, ra)) >= rb) { + const cast : u8 = cast_class(src, st, ra); + if (cast != C_ANY) { return cast; } + } + // `x.len()` is a usize whatever x is, unless the file declares a fn `len` of its own: st[TYARR] 2 says the + // type is usize (there is no `usize` in the source to point TYLO .. TYHI at) + const lt : usize = len_tail(src, ra, rb); + if (lt < src.len) { + const own : u8 = ret_class(src, st, lt, tok_end(src, lt)); + st[TYLO] = 0; + st[TYHI] = 0; + st[TYARR] = 0; + if (own == C_NONE) { + st[TYARR] = 2; + return C_INT; + } + } const e : usize = tok_end(src, ra); const nx : usize = skip_ws(src, e); if (nx >= rb) { @@ -2578,6 +2645,11 @@ pub fn recv_class(src: []const u8, st: []usize, ra: usize, rb: usize) -> u8 { while (q < rb) { const qe : usize = tok_end(src, q); var k : u8 = C_ANY; + // a token's type is the one its own lookup names: an unsuffixed literal after a typed name must not inherit + // that name's span (`(v.len() - 1)` with `v: &[u8]` read as u8) + st[TYLO] = 0; + st[TYHI] = 0; + st[TYARR] = 0; if (is_digit(src[q])) { k = literal_class(src, st, q); } else if (is_alpha(src[q]) and !tok_is(src, prev, ".") and !tok_is(src, prev, "::")) { @@ -2607,7 +2679,7 @@ pub fn recv_class(src: []const u8, st: []usize, ra: usize, rb: usize) -> u8 { /// Is the Rust method src[a .. b] one of the std methods t27o converts whose result is a bool? pub fn std_bool(src: []const u8, a: usize, b: usize) -> bool { - const w : str = " is_empty starts_with ends_with contains is_some is_none is_ok is_err eq is_ascii_alphabetic is_ascii_alphanumeric is_ascii_digit all "; + const w : str = " is_empty starts_with ends_with contains is_some is_none is_ok is_err eq is_ascii_alphabetic is_ascii_alphanumeric is_ascii_digit all is_finite is_ascii "; return listed(w, src[a .. b]); } @@ -2910,10 +2982,17 @@ pub fn let_int(src: []const u8, st: []usize, d: usize) -> usize { // first and its char-needle sibling later in the table; method() bumps to the first later row of // the same name and class when the needle is a char literal. Not mapped, so refused: `@abs` of an // integer type t27o cannot name, contains on a slice of texts (t27 has no slice of slices; a -// constant array is unrolled instead), saturating arithmetic (hosting::panel's saturating_add would -// `use` 28 modules). `@min` / `@max` of an integer and a bare literal is NOT refused: Zig gives the +// constant array is unrolled instead). `@min` / `@max` of an integer and a bare literal is NOT refused: Zig gives the // peer type of the pair, not the literal's narrow type (@max(u32_var, 1) is u32 -- probed on the // lab, /root/t27o9100/pmax.zig). +// The pure methods of #10764 (rust_std.t27 proves each against rustc): count_ones, leading_zeros, trailing_zeros, +// pow, saturating_add / sub / mul and div_ceil (unsigned) name _ for the receiver's integer type; sqrt is +// the builtin; is_finite and to_bits name _ of f32 / f64 (to_bits is an @bitCast that gen-rust prints +// as written); is_ascii, to_ascii_lowercase and to_ascii_uppercase map on a u8 and (is_ascii) on a text or a byte +// slice; get(i) and contains(&x) map on a slice of scalars; unwrap_or is an `if` where it stands alone as a value. +// Refused, each for a reason: `ln` (R_LIBM: the platform libm's last bit is not IEEE 754's), a text's or a char's +// to_ascii_lowercase (an owned String; no char class), the signed div_ceil (unstable in Rust), a get with a +// range, and an unwrap_or inside an expression or on a receiver that calls a fn of the file. /// The receiver classes an entry asks for. pub const C_ANY : u8 = 0; @@ -2940,16 +3019,16 @@ pub const CK_INDEX : usize = 8; pub const STD_MODS : [5]str = ["", "tools::t27o::rust_std", "hosting::toolchain", "tri::mutate::plant", "tri::t27b::type_text"]; pub const MOD_TTEXT : u8 = 4; -pub const STD_N : usize = 55; +pub const STD_N : usize = 75; /// The Rust method (`iter.sum` is `.iter().sum()`, `cmp::max` a path call). -pub const STD_NAME : [55]str = ["len", "is_empty", "as_bytes", "as_str", "as_slice", "clone", "abs", "abs", "min", "max", "cmp::min", "cmp::max", "wrapping_add", "wrapping_sub", "wrapping_mul", "checked_add", "checked_sub", "checked_mul", "trim", "trim_start", "trim_end", "starts_with", "ends_with", "contains", "contains", "parse", "iter.sum", "iter.count", "unwrap", "expect", "is_some", "is_none", "is_ok", "is_err", "is_ok", "is_err", "ok", "ok_or", "context", "eq", "is_ascii_alphabetic", "is_ascii_alphanumeric", "is_ascii_digit", "chars", "find", "find", "trim_start_matches", "trim_start_matches", "trim_end_matches", "trim_end_matches", "strip_prefix", "strip_prefix", "strip_suffix", "strip_suffix", "starts_with"]; -pub const STD_CLASS : [55]u8 = [0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]; +pub const STD_NAME : [75]str = ["len", "is_empty", "as_bytes", "as_str", "as_slice", "clone", "abs", "abs", "min", "max", "cmp::min", "cmp::max", "wrapping_add", "wrapping_sub", "wrapping_mul", "checked_add", "checked_sub", "checked_mul", "trim", "trim_start", "trim_end", "starts_with", "ends_with", "contains", "contains", "parse", "iter.sum", "iter.count", "unwrap", "expect", "is_some", "is_none", "is_ok", "is_err", "is_ok", "is_err", "ok", "ok_or", "context", "eq", "is_ascii_alphabetic", "is_ascii_alphanumeric", "is_ascii_digit", "chars", "find", "find", "trim_start_matches", "trim_start_matches", "trim_end_matches", "trim_end_matches", "strip_prefix", "strip_prefix", "strip_suffix", "strip_suffix", "starts_with", "count_ones", "leading_zeros", "trailing_zeros", "pow", "saturating_add", "saturating_sub", "saturating_mul", "div_ceil", "sqrt", "is_finite", "to_bits", "is_ascii", "is_ascii", "is_ascii", "to_ascii_lowercase", "to_ascii_uppercase", "get", "contains", "contains.char", "unwrap_or"]; +pub const STD_CLASS : [75]u8 = [0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 4, 2, 2, 2, 4, 4, 3, 0]; /// How many arguments the method takes. -pub const STD_ARGS : [55]u8 = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; -pub const STD_FORM : [55]str = ["#.len", "(#.len == 0)", "#", "#", "#", "#", "@abs(#)", "rust_std::abs_%(#)", "@min(#, $)", "@max(#, $)", "@min(#)", "@max(#)", "(# +% $)", "(# -% $)", "(# *% $)", "rust_std::checked_add_%(#, $)", "rust_std::checked_sub_%(#, $)", "rust_std::checked_mul_%(#, $)", "#[type_text::trim_lo(#, 0, #.len) .. type_text::trim_hi(#, type_text::trim_lo(#, 0, #.len), #.len)]", "#[type_text::trim_lo(#, 0, #.len) .. #.len]", "#[0 .. type_text::trim_hi(#, 0, #.len)]", "toolchain::starts_with(#, $)", "toolchain::ends_with(#, $t)", "rust_std::str_contains(#, $t)", "rust_std::bytes_contain(#, $)", "rust_std::parse_%(#)", "rust_std::sum_%(#)", "#.len", "#.?", "#.?", "(# != null)", "(# == null)", "#", "(# == false)", "(# != null)", "(# == null)", "#", "#", "#", "type_text::same(#, $)", "type_text::alpha(#)", "rust_std::alnum(#)", "type_text::digit(#)", "#", "rust_std::find_text(#, $)", "rust_std::find_byte(#, $)", "rust_std::trim_start_matches_text(#, $)", "rust_std::trim_start_matches_byte(#, $)", "rust_std::trim_end_matches_text(#, $)", "rust_std::trim_end_matches_byte(#, $)", "rust_std::strip_prefix_text(#, $)", "rust_std::strip_prefix_byte(#, $)", "rust_std::strip_suffix_text(#, $)", "rust_std::strip_suffix_byte(#, $)", "rust_std::starts_with_byte(#, $)"]; +pub const STD_ARGS : [75]u8 = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]; +pub const STD_FORM : [75]str = ["#.len", "(#.len == 0)", "#", "#", "#", "#", "@abs(#)", "rust_std::abs_%(#)", "@min(#, $)", "@max(#, $)", "@min(#)", "@max(#)", "(# +% $)", "(# -% $)", "(# *% $)", "rust_std::checked_add_%(#, $)", "rust_std::checked_sub_%(#, $)", "rust_std::checked_mul_%(#, $)", "#[type_text::trim_lo(#, 0, #.len) .. type_text::trim_hi(#, type_text::trim_lo(#, 0, #.len), #.len)]", "#[type_text::trim_lo(#, 0, #.len) .. #.len]", "#[0 .. type_text::trim_hi(#, 0, #.len)]", "toolchain::starts_with(#, $)", "toolchain::ends_with(#, $t)", "rust_std::str_contains(#, $t)", "rust_std::bytes_contain(#, $)", "rust_std::parse_%(#)", "rust_std::sum_%(#)", "#.len", "#.?", "#.?", "(# != null)", "(# == null)", "#", "(# == false)", "(# != null)", "(# == null)", "#", "#", "#", "type_text::same(#, $)", "type_text::alpha(#)", "rust_std::alnum(#)", "type_text::digit(#)", "#", "rust_std::find_text(#, $)", "rust_std::find_byte(#, $)", "rust_std::trim_start_matches_text(#, $)", "rust_std::trim_start_matches_byte(#, $)", "rust_std::trim_end_matches_text(#, $)", "rust_std::trim_end_matches_byte(#, $)", "rust_std::strip_prefix_text(#, $)", "rust_std::strip_prefix_byte(#, $)", "rust_std::strip_suffix_text(#, $)", "rust_std::strip_suffix_byte(#, $)", "rust_std::starts_with_byte(#, $)", "rust_std::count_ones_%(#)", "rust_std::leading_zeros_%(#)", "rust_std::trailing_zeros_%(#)", "rust_std::pow_%(#, $)", "rust_std::saturating_add_%(#, $)", "rust_std::saturating_sub_%(#, $)", "rust_std::saturating_mul_%(#, $)", "rust_std::div_ceil_%(#, $)", "@sqrt(#)", "rust_std::is_finite_%(#)", "rust_std::to_bits_%(#)", "rust_std::is_ascii_text(#)", "rust_std::is_ascii_text(#)", "rust_std::is_ascii_%(#)", "rust_std::to_ascii_lowercase_%(#)", "rust_std::to_ascii_uppercase_%(#)", "rust_std::get_%(#, $)", "rust_std::contains_%(#, $)", "rust_std::str_contains_char(#, $)", "if (# != null) { ^.? } else { $ }"]; /// The types `%` may be, space-separated; empty when the template has no `%`. -pub const STD_TYPES : [55]str = ["", "", "", "", "", "", "", " i8 i16 i32 i64 ", "", "", "", "", "", "", "", " u32 u64 usize i32 i64 ", " u32 u64 usize i32 i64 ", " u32 u64 usize i32 i64 ", "", "", "", "", "", "", " u8 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u32 u64 usize i32 i64 f32 f64 ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]; -pub const STD_USE : [55]u8 = [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 4, 4, 4, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +pub const STD_TYPES : [75]str = ["", "", "", "", "", "", "", " i8 i16 i32 i64 ", "", "", "", "", "", "", "", " u32 u64 usize i32 i64 ", " u32 u64 usize i32 i64 ", " u32 u64 usize i32 i64 ", "", "", "", "", "", "", " u8 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u32 u64 usize i32 i64 f32 f64 ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 ", " u8 u16 u32 u64 usize ", "", " f32 f64 ", " f32 f64 ", "", " u8 ", " u8 ", " u8 ", " u8 ", " u8 u16 u32 u64 usize i8 i16 i32 i64 f32 f64 ", " u16 u32 u64 usize i8 i16 i32 i64 f32 f64 ", "", ""]; +pub const STD_USE : [75]u8 = [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 4, 4, 4, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]; /// Is t a word of the space-separated list w (" u32 u64 ")? pub fn listed(w: str, t: []const u8) -> bool { @@ -3025,6 +3104,71 @@ pub fn wrap_pct(form : str, i : usize) -> bool { return i > 0 and (form[i - 1] == B_PLUS or form[i - 1] == B_MINUS or form[i - 1] == B_STAR); } +/// Does the output hold the text s at out[at]? +pub fn out_holds(out: []const u8, at: usize, s: []const u8) -> bool { + if (at + s.len > out.len) { return false; } + var k : usize = 0; + while (k < s.len) { + if (out[at + k] != s[k]) { return false; } + k = k + 1; + } + return true; +} + +/// Is the callee written at out[j] one of the pure helpers the std table names: a builtin `@name`, or a fn of +/// rust_std, type_text or toolchain (rust_std's appends write into a buffer, so they are not)? +pub fn pure_callee(out: []const u8, j: usize) -> bool { + if (out[j] == B_AT) { return true; } + if (out_holds(out, j, "rust_std::append_")) { return false; } + return out_holds(out, j, "rust_std::") or out_holds(out, j, "type_text::") or out_holds(out, j, "toolchain::"); +} + +/// Does the output out[a .. b] call nothing but those pure helpers? Every `(` is a plain group or follows such a +/// callee. A form that writes its receiver twice (`unwrap_or`: the test and the value) may only do it when the +/// receiver does nothing a second time would change. A text past the end of the buffer cannot be judged, and the +/// retry with a bigger buffer will. +pub fn pure_out(out: []const u8, a: usize, b: usize) -> bool { + if (b > out.len) { return true; } + var i : usize = a; + while (i < b) { + if (out[i] == B_LPAREN) { + var j : usize = i; + while (j > a and (is_alpha(out[j - 1]) or is_digit(out[j - 1]) or out[j - 1] == B_COLON or out[j - 1] == B_AT)) { j = j - 1; } + if (j < i and !pure_callee(out, j)) { return false; } + } + i = i + 1; + } + return true; +} + +/// find, for a receiver whose type is src[tyl .. tyh], or usize (a `.len()`) when usz. +pub fn find_ty(name: []const u8, cls: u8, src: []const u8, tyl: usize, tyh: usize, usz: bool) -> usize { + if (usz) { return find(name, cls, "usize"); } + return find(name, cls, src[tyl .. tyh]); +} + +/// Is the call whose receiver the output holds from `start` on, and whose argument list opens at the `(` src[lp], +/// the whole value of a `let`, an assignment or a field (the output before `start` ends a single ` = `), or the whole +/// statement (only spaces before it on its line: a tail expression, which becomes a `return`), and followed by `;`, +/// `,` or `}`? An `if` used as a value is printed by the reference without parentheses, so its last arm takes in +/// what follows it: `(if ..) * 2.0` is mistyped by Zig and refused by t27b (ExprIf as a left operand). In the +/// positions above nothing follows it. +pub fn alone_as_value(src: []const u8, out: []const u8, start: usize, lp: usize) -> bool { + var ok : bool = false; + if (start <= out.len) { + var i : usize = start; + while (i > 0 and out[i - 1] == B_SPACE) { i = i - 1; } + if (i == 0 or out[i - 1] == B_NL) { ok = true; } + } + if (start >= 4 and out_holds(out, start - 3, " = ")) { + const op : u8 = out[start - 4]; + ok = op != B_EQ and op != B_BANG and op != B_LT and op != B_GT and op != B_PLUS and op != B_MINUS and op != B_STAR and op != B_SLASH and op != B_PCT and op != B_AMP and op != B_PIPE and op != B_CARET; + } + if (!ok) { return false; } + const after : usize = skip_ws(src, block_end(src, lp)); + return tok_is(src, after, ";") or tok_is(src, after, ",") or tok_is(src, after, "}"); +} + /// Write entry k of the table for the call whose receiver was written from `start` on; st[P] is at the /// `(` of its arguments; src[tyl .. tyh] is what a `%` of the form writes. src[ra .. rb] is the /// receiver's source -- a `#` after the first one writes it again (the trims index the slice they @@ -3032,12 +3176,19 @@ pub fn wrap_pct(form : str, i : usize) -> bool { pub fn expand(src: []const u8, st: []usize, out: []u8, start: usize, k: usize, ra: usize, rb: usize, tyl: usize, tyh: usize, cls: u8) -> void { const form : str = STD_FORM[k]; const nargs : u8 = STD_ARGS[k]; + // how much the receiver took in the output, for a form that writes it again (`^`) + const rlen : usize = st[W] - start; + // the receiver's type is usize with no word of the source to say so (a `.len()`) + const usz : bool = st[TYARR] == 2; var h : usize = 0; while (h < form.len and form[h] != B_HASH) { h = h + 1; } var pos : usize = start; var i : usize = 0; while (i < h) { - if (form[i] == B_PCT and !wrap_pct(form, i)) { + if (form[i] == B_PCT and !wrap_pct(form, i) and usz) { + insert(st, out, pos, "usize"); + pos = pos + 5; + } else if (form[i] == B_PCT and !wrap_pct(form, i)) { insert_src(src, st, out, pos, tyl, tyh); pos = pos + (tyh - tyl); } else { @@ -3046,8 +3197,10 @@ pub fn expand(src: []const u8, st: []usize, out: []u8, start: usize, k: usize, r } i = i + 1; } - // an array receiver goes to a slice parameter by address - if (cls == C_SLICE and st[TYARR] == 1 and h > 0) { insert(st, out, pos, "&"); } + const rpos : usize = pos; + // an array receiver goes to a slice parameter by address (a row of any class has the receiver itself as its + // subject; one of a slice class takes it as the argument) + if (cls == C_SLICE and st[TYARR] == 1 and h > 0 and STD_CLASS[k] != C_ANY) { insert(st, out, pos, "&"); } if (nargs == 0) { no_args(src, st); } else { want(src, st, "("); } var used : bool = false; var j : usize = h + 1; @@ -3074,8 +3227,18 @@ pub fn expand(src: []const u8, st: []usize, out: []u8, start: usize, k: usize, r if (opctx and !keep_bare(l, L_ADD, false)) { wrap(st, out, rs); } } used = true; + } else if (c == B_PCT and !wrap_pct(form, j) and usz) { + puts(st, out, "usize"); } else if (c == B_PCT and !wrap_pct(form, j)) { put_src(src, st, out, tyl, tyh); + } else if (c == B_CARET) { + // `^`: the receiver as it was written in the output, once more (unwrap_or: the test, then the value) + var r : usize = 0; + while (r < rlen) { + const rb2 : usize = rpos + r; + if (rb2 < out.len) { put(st, out, out[rb2]); } else { put(st, out, 0); } + r = r + 1; + } } else if (c == B_HASH and ra < rb) { // a second # of the form writes the receiver again: the trims index their slice with // trim_lo / trim_hi calls on it -- the receiver is both the slice subject and the argument @@ -3203,6 +3366,18 @@ pub fn digit_closure(src: []const u8, p: usize) -> bool { return all_closure(src, p) == 1; } +/// Is the argument that starts at src[ar] (the token after the `(` of a call) one name, declared with the type +/// `char` (a parameter or a typed let, searched from the fn's start, flo)? Such a needle is a u32 scalar value, not +/// the one-byte text a char literal is. +pub fn char_var(src: []const u8, flo: usize, ar: usize) -> bool { + if (ar >= src.len or !is_alpha(src[ar])) { return false; } + const e : usize = tok_end(src, ar); + if (!tok_is(src, skip_ws(src, e), ")")) { return false; } + const d : usize = decl_type(src, flo, ar, ar, e); + if (d >= src.len) { return false; } + return word_is(src, d, tok_end(src, d), "char"); +} + /// The method call recv.name(..) whose receiver was written from `start` on and is src[ra .. rb]; st[P] /// is at `(`; tla .. tlb is a turbofish's type (`parse::()`), empty when there is none. pub fn method(src: []const u8, st: []usize, out: []u8, start: usize, ra: usize, rb: usize, na: usize, nb: usize, tla: usize, tlb: usize) -> void { @@ -3299,6 +3474,7 @@ pub fn method(src: []const u8, st: []usize, out: []u8, start: usize, ra: usize, } if (word_is(src, na, nb, "contains") and unroll_contains(src, st, out, start, ra, rb)) { return; } const cls : u8 = recv_class(src, st, ra, rb); + const usz : bool = st[TYARR] == 2; var tyl : usize = st[TYLO]; var tyh : usize = st[TYHI]; if (cb > ca) { @@ -3310,16 +3486,37 @@ pub fn method(src: []const u8, st: []usize, out: []u8, start: usize, ra: usize, tyl = li; tyh = tok_end(src, li); } + // `r.unwrap_or(d)` is `if (r != null) { r.? } else { d }` (t27 has no `orelse`), which reads r twice and d only + // when r is null: r and d must do nothing a second (or no) evaluation would change, so a receiver that calls + // anything but the std table's pure helpers is refused here and the default after the form is written; and it + // must stand alone as a value (alone_as_value), for the reference prints an `if` without its parentheses + if (!chain and word_is(src, na, nb, "unwrap_or") and (!pure_out(out, start, st[W]) or !alone_as_value(src, out, start, st[P]))) { + refuse(st, R_METHOD, ka, ka, kb); + return; + } var k : usize = STD_N; if (chain) { - if (word_is(src, ka, kb, "sum")) { k = find("iter.sum", cls, src[tyl .. tyh]); } else { k = find("iter.count", cls, src[tyl .. tyh]); } + if (word_is(src, ka, kb, "sum")) { k = find_ty("iter.sum", cls, src, tyl, tyh, usz); } else { k = find_ty("iter.count", cls, src, tyl, tyh, usz); } } else { - k = find(src[na .. nb], cls, src[tyl .. tyh]); + k = find_ty(src[na .. nb], cls, src, tyl, tyh, usz); } if (k >= STD_N) { + // `ln` is the platform libm's log in Rust and Zig's own port of one in t27 (@log): the two agree on + // the 200000 inputs probed (#10764) but IEEE 754 does not fix the last bit of a log, so a bit-exact + // conversion cannot be promised; gen-rust also spells @log `.log()`, which takes a base (E0061) + if (word_is(src, na, nb, "ln")) { + refuse(st, R_LIBM, ka, ka, kb); + return; + } refuse(st, R_METHOD, ka, ka, kb); return; } + // a char held in a variable is a u32 scalar, not the one-byte text a char literal is: contains takes the + // row that encodes it (the read of the argument is the same, `$`) + if (!chain and word_is(src, na, nb, "contains") and cls == C_STR and char_var(src, st[FLO], skip_ws(src, st[P] + 1))) { + const kc : usize = find("contains.char", C_STR, ""); + if (kc < STD_N) { k = kc; } + } // a needle-polymorphic method found its text-needle row first; a char-literal needle takes the // byte sibling: the first later row of the same name and class (the names are read through // locals -- gen-rust indexes a local `str` as bytes, an array element it does not) @@ -3342,7 +3539,9 @@ pub fn method(src: []const u8, st: []usize, out: []u8, start: usize, ra: usize, k = hit; } } + if (usz) { st[TYARR] = 2; } expand(src, st, out, start, k, ra, rb, tyl, tyh, cls); + if (!chain and word_is(src, na, nb, "unwrap_or") and !pure_out(out, start, st[W])) { refuse(st, R_METHOD, ka, ka, kb); } } /// 2 to the power n: the bit of module n of STD_MODS in st[USES]. @@ -5919,6 +6118,8 @@ pub fn put_reason(src: []const u8, st: []usize, out: []u8) -> void { puts(st, out, "a vec! the fn hands on or returns"); } else if (c == R_VECTYPE) { puts(st, out, "a vec! whose element type or length t27o cannot tell"); + } else if (c == R_LIBM) { + puts(st, out, "libm function not bit-exact"); } else if (c == R_SPLICE) { puts(st, out, "a used module's own use t27c does not splice (its type_text:: names stay unresolved, the gap specs/compiler/int_type_names.t27 records)"); } else { @@ -9785,8 +9986,8 @@ test negative_control_an_unknown_element_type_or_length_and_a_vec_that_is_no_let test negative_control_a_test_that_reaches_a_refused_fn_through_super_is_refused_with_it { var out : [4096]u8 = undefined; var st : [1024]usize = [0] ** 1024; - const n : usize = body("fn bad(s: &str) -> usize { s.len().saturating_sub(1) }\nfn good(s: &str) -> usize { s.len() }\n#[cfg(test)]\nmod tests {\n #[test]\n fn through_super_to_a_refused_fn() { assert_eq!(super::bad(\"ab\"), 1); }\n #[test]\n fn through_super_to_a_converted_fn() { assert_eq!(super::good(\"ab\"), 2); }\n #[test]\n fn through_super_to_a_fn_nobody_here_declares() { assert_eq!(super::elsewhere(\"ab\"), 2); }\n}", &out, &st); - assert(out_is(n, &out, 0, "// t27o: refused fn bad (line 1): method `saturating_sub` at line 1\n\nfn bad(s: []const u8) -> usize {\n}\n\nfn good(s: []const u8) -> usize {\n return s.len;\n}\n\n// t27o: refused fn through_super_to_a_refused_fn (line 6): uses refused `bad` at line 6\n\ntest through_super_to_a_converted_fn {\n assert(good(\"ab\") == 2);\n}\n\n// t27o: refused fn through_super_to_a_fn_nobody_here_declares (line 10): undeclared `elsewhere` at line 10\n\n")); + const n : usize = body("fn bad(s: &str) -> usize { s.len().abs_diff(1) }\nfn good(s: &str) -> usize { s.len() }\n#[cfg(test)]\nmod tests {\n #[test]\n fn through_super_to_a_refused_fn() { assert_eq!(super::bad(\"ab\"), 1); }\n #[test]\n fn through_super_to_a_converted_fn() { assert_eq!(super::good(\"ab\"), 2); }\n #[test]\n fn through_super_to_a_fn_nobody_here_declares() { assert_eq!(super::elsewhere(\"ab\"), 2); }\n}", &out, &st); + assert(out_is(n, &out, 0, "// t27o: refused fn bad (line 1): method `abs_diff` at line 1\n\nfn bad(s: []const u8) -> usize {\n}\n\nfn good(s: []const u8) -> usize {\n return s.len;\n}\n\n// t27o: refused fn through_super_to_a_refused_fn (line 6): uses refused `bad` at line 6\n\ntest through_super_to_a_converted_fn {\n assert(good(\"ab\") == 2);\n}\n\n// t27o: refused fn through_super_to_a_fn_nobody_here_declares (line 10): undeclared `elsewhere` at line 10\n\n")); assert(st[NOK] == 2); } @@ -10171,3 +10372,198 @@ test the_index_names_the_impl_that_owns_a_method_and_the_last_let_that_types_a_n assert(impl_around(src, &st, src.len - 40)); assert(word_is(src, st[OLO], st[OHI], "Q")); } + +/// The bit counts (#10764) name the fn of the receiver's width: count_ones_, leading_zeros_ and +/// trailing_zeros_ of rust_std, one per integer type; the result is u32, as Rust's. +test std_bit_counts_go_through_the_table { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn pc(a: u32, b: i8, c: usize, d: u64) -> u32 {\n a.count_ones() + b.leading_zeros() + c.trailing_zeros() + (d & 0xff).count_ones()\n}\nfn lz(x: u16) -> u32 {\n 32 - x.leading_zeros()\n}\nfn bm(value: u64) -> u8 {\n value.count_ones() as u8\n}", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\nfn pc(a: u32, b: i8, c: usize, d: u64) -> u32 {\n return rust_std::count_ones_u32(a) + rust_std::leading_zeros_i8(b) + rust_std::trailing_zeros_usize(c) + rust_std::count_ones_u64((d & 0xff));\n}\n\nfn lz(x: u16) -> u32 {\n return 32 - rust_std::leading_zeros_u16(x);\n}\n\nfn bm(value: u64) -> u8 {\n return rust_std::count_ones_u64(value) as u8;\n}\n\n")); + assert(st[NOK] == 3); +} + +test negative_control_a_bit_count_of_a_float_stays_refused { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn unk(x: f64) -> u32 {\n x.count_ones()\n}", &out, &st); + assert(out_is(n, &out, 0, "// t27o: refused fn unk (line 1): method `count_ones` at line 2\n\nfn unk(x: f64) -> u32 {\n}\n\n")); + assert(st[NOK] == 0); +} + +/// pow (#10764) names pow_ of rust_std. The fn multiplies as Rust does, so an overflow traps where a debug +/// build panics (t27b: integer overflow; Zig: panic). The receiver '(n as u64)' is a u64 whatever type n has. +test std_pow_goes_through_the_table_and_a_cast_names_the_receiver_type { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn sq(n: u32) -> u64 {\n (n as u64).pow(2) + 10u64.pow(n) + 3usize.pow(4) as u64\n}\nfn area(side: i32, k: u32) -> i32 {\n side.pow(k)\n}", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\nfn sq(n: u32) -> u64 {\n return rust_std::pow_u64((n as u64), 2) + rust_std::pow_u64(@as(u64, 10), n) + (rust_std::pow_usize(@as(usize, 3), 4) as u64);\n}\n\nfn area(side: i32, k: u32) -> i32 {\n return rust_std::pow_i32(side, k);\n}\n\n")); + assert(st[NOK] == 2); +} + +test negative_control_pow_of_a_float_stays_refused { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn flt(x: f64) -> f64 {\n x.pow(2)\n}", &out, &st); + assert(out_is(n, &out, 0, "// t27o: refused fn flt (line 1): method `pow` at line 2\n\nfn flt(x: f64) -> f64 {\n}\n\n")); + assert(st[NOK] == 0); +} + +/// saturating_add / sub / mul (#10764) name _ of rust_std for the receiver's type, a field of a struct of the +/// file and a chain of them included. A fn of hosting::panel has the u64 add, but its use would splice 28 modules. +test std_saturating_calls_go_through_the_table { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("struct Win { start: u64, size: u32 }\nfn end(w: &Win) -> u64 { w.start.saturating_add(w.size as u64) }\nfn left(now: u64, w: &Win) -> u64 { now.saturating_sub(w.start) }\nfn grow(n: u8) -> u8 { n.saturating_mul(2).saturating_add(250) }\nfn back(a: i32, b: i32) -> i32 { a.saturating_sub(b) }\nfn idx(i: usize) -> usize { i.saturating_sub(2) }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\nconst Win = struct {\n start : u64,\n size : u32,\n};\n\nfn end(w: Win) -> u64 {\n return rust_std::saturating_add_u64(w.start, w.size as u64);\n}\n\nfn left(now: u64, w: Win) -> u64 {\n return rust_std::saturating_sub_u64(now, w.start);\n}\n\nfn grow(n: u8) -> u8 {\n return rust_std::saturating_add_u8(rust_std::saturating_mul_u8(n, 2), 250);\n}\n\nfn back(a: i32, b: i32) -> i32 {\n return rust_std::saturating_sub_i32(a, b);\n}\n\nfn idx(i: usize) -> usize {\n return rust_std::saturating_sub_usize(i, 2);\n}\n\n")); + assert(st[NOK] == 5); +} + +/// div_ceil (#10764) is unsigned only: the signed div_ceil is unstable in Rust, so a signed receiver has no row. +test std_div_ceil_goes_through_the_table_for_unsigned_types { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn bursts(len: u32, burst: u32) -> u32 { len.div_ceil(burst) }\nfn bytes(bits: u64) -> usize { bits.div_ceil(8) as usize }\nfn half(x: u16) -> u16 { x.div_ceil(2) }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\nfn bursts(len: u32, burst: u32) -> u32 {\n return rust_std::div_ceil_u32(len, burst);\n}\n\nfn bytes(bits: u64) -> usize {\n return rust_std::div_ceil_u64(bits, 8) as usize;\n}\n\nfn half(x: u16) -> u16 {\n return rust_std::div_ceil_u16(x, 2);\n}\n\n")); + assert(st[NOK] == 3); +} + +test negative_control_a_signed_div_ceil_stays_refused { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn sg(x: i32) -> i32 { x.div_ceil(2) }", &out, &st); + assert(out_is(n, &out, 0, "// t27o: refused fn sg (line 1): method `div_ceil` at line 1\n\nfn sg(x: i32) -> i32 {\n}\n\n")); + assert(st[NOK] == 0); +} + +/// sqrt (#10764) is the builtin @sqrt, correctly rounded in IEEE 754 whatever the backend; is_finite and to_bits name the +/// fn of the float's width (f32, f64). +test std_float_methods_go_through_the_table { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn phi() -> f64 { (1.0 + 5.0_f64.sqrt()) / 2.0 }\nfn norm(x: f64, n: usize) -> f64 { x / (n as f64).sqrt() }\nfn ok(value: f64) -> bool { !value.is_finite() || value < 0.0 }\nfn ok32(v: f32) -> bool { v.is_finite() }\nfn bits(x: f64) -> u64 { x.to_bits() }\nfn bits32(x: f32) -> u32 { x.to_bits() }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\nfn phi() -> f64 {\n return (1.0 + @sqrt(@as(f64, 5.0))) / 2.0;\n}\n\nfn norm(x: f64, n: usize) -> f64 {\n return x / @sqrt((n as f64));\n}\n\nfn ok(value: f64) -> bool {\n return !rust_std::is_finite_f64(value) or value < 0.0;\n}\n\nfn ok32(v: f32) -> bool {\n return rust_std::is_finite_f32(v);\n}\n\nfn bits(x: f64) -> u64 {\n return rust_std::to_bits_f64(x);\n}\n\nfn bits32(x: f32) -> u32 {\n return rust_std::to_bits_f32(x);\n}\n\n")); + assert(st[NOK] == 6); +} + +/// ln is refused with its own reason: Rust calls the platform libm, and IEEE 754 does not fix a log's last bit. +test negative_control_ln_is_refused_for_its_libm_and_sqrt_of_an_integer_stays_a_method { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn lg(x: f64) -> f64 { x.ln() }\nfn bad(n: u32) -> f64 { n.sqrt() }", &out, &st); + assert(out_is(n, &out, 0, "// t27o: refused fn lg (line 1): libm function not bit-exact `ln` at line 1\n\nfn lg(x: f64) -> f64 {\n}\n\n// t27o: refused fn bad (line 2): method `sqrt` at line 2\n\nfn bad(n: u32) -> f64 {\n}\n\n")); + assert(st[NOK] == 0); +} + +/// is_ascii (#10764) on a text, a byte slice or a u8; to_ascii_lowercase and to_ascii_uppercase on a u8. +test std_ascii_methods_go_through_the_table { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn check(v: &str, bytes: &[u8], b: u8) -> bool {\n v.is_ascii() && bytes.is_ascii() && b.is_ascii()\n}\nfn lower(b: u8) -> u8 { b.to_ascii_lowercase() + b.to_ascii_uppercase() }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\nfn check(v: []const u8, bytes: []const u8, b: u8) -> bool {\n return rust_std::is_ascii_text(v) and rust_std::is_ascii_text(bytes) and rust_std::is_ascii_u8(b);\n}\n\nfn lower(b: u8) -> u8 {\n return rust_std::to_ascii_lowercase_u8(b) + rust_std::to_ascii_uppercase_u8(b);\n}\n\n")); + assert(st[NOK] == 2); +} + +/// A text's to_ascii_lowercase returns an owned String, and t27o holds no char class, so neither converts. +test negative_control_to_ascii_case_of_a_text_or_a_char_stays_refused { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn up(s: &str) -> bool { s.to_ascii_lowercase().len() > 0 }\nfn ch(c: char) -> char { c.to_ascii_lowercase() }", &out, &st); + assert(out_is(n, &out, 0, "// t27o: refused fn up (line 1): method `to_ascii_lowercase` at line 1\n\nfn up(s: []const u8) -> bool {\n}\n\n// t27o: refused fn ch (line 2): method `to_ascii_lowercase` at line 2\n\nfn ch(c: u32) -> u32 {\n}\n\n")); + assert(st[NOK] == 0); +} + +/// get(i) (#10764) on a slice, a Vec or an array of scalars is get_ of rust_std, an Option<&T> being ?T. A reference to an array +/// is written as a slice, so it goes to the fn as it is; an array held by value goes by address. +test std_slice_get_goes_through_the_table { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn b(v: &[u32], i: usize) -> bool { v.get(i).is_some() }\nfn d(v: &Vec, i: usize) -> bool { v.get(i + 1).is_none() }\nfn e(v: &[f64]) -> bool { v.get(0).is_some() }\nfn g(v: &[u8; 4], i: usize) -> bool { v.get(i).is_some() }\nfn h(v: [u8; 4], i: usize) -> bool { v.get(i).is_some() }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\nfn b(v: []const u32, i: usize) -> bool {\n return (rust_std::get_u32(v, i) != null);\n}\n\nfn d(v: []const i64, i: usize) -> bool {\n return (rust_std::get_i64(v, i + 1) == null);\n}\n\nfn e(v: []const f64) -> bool {\n return (rust_std::get_f64(v, 0) != null);\n}\n\nfn g(v: []const u8, i: usize) -> bool {\n return (rust_std::get_u8(v, i) != null);\n}\n\nfn h(v: [4]u8, i: usize) -> bool {\n return (rust_std::get_u8(&v, i) != null);\n}\n\n")); + assert(st[NOK] == 5); +} + +/// A range argument (get(a..b) is an Option<&[T]>) and a text's get are not the element fn. +test negative_control_get_with_a_range_or_on_a_text_stays_refused { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn c(v: &[u32]) -> bool { v.get(1..3).is_some() }\nfn f(s: &str) -> bool { s.get(0..1).is_some() }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\n// t27o: refused fn c (line 1): syntax `..` at line 1\n\nfn c(v: []const u32) -> bool {\n}\n\n// t27o: refused fn f (line 2): method `get` at line 2\n\nfn f(s: []const u8) -> bool {\n}\n\n")); + assert(st[NOK] == 0); +} + +/// contains (#10764) on a slice of any scalar type is contains_ (bytes_contain for u8). A text's contains with a char held in a +/// variable takes str_contains_char (the char is a u32, not the one-byte text a literal is); a char literal still takes str_contains. +test std_contains_of_scalars_and_of_a_char_variable_go_through_the_table { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn b(v: &[u32], x: u32) -> bool { v.contains(&x) }\nfn c(s: &str, ch: char) -> bool { s.contains(ch) }\nfn d(s: &str) -> bool { s.contains('x') }\nfn g(v: &Vec, x: u16) -> bool { v.contains(&x) }\nfn k(v: &[f64], x: f64) -> bool { v.contains(&x) }\nfn m(v: &[u8; 4], x: u8) -> bool { v.contains(&x) }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\nfn b(v: []const u32, x: u32) -> bool {\n return rust_std::contains_u32(v, x);\n}\n\nfn c(s: []const u8, ch: u32) -> bool {\n return rust_std::str_contains_char(s, ch);\n}\n\nfn d(s: []const u8) -> bool {\n return rust_std::str_contains(s, \"x\");\n}\n\nfn g(v: []const u16, x: u16) -> bool {\n return rust_std::contains_u16(v, x);\n}\n\nfn k(v: []const f64, x: f64) -> bool {\n return rust_std::contains_f64(v, x);\n}\n\nfn m(v: []const u8, x: u8) -> bool {\n return rust_std::bytes_contain(v, x);\n}\n\n")); + assert(st[NOK] == 6); +} + +/// t27 holds no slice of slices: a slice of texts has no row (a constant array is unrolled instead). +test negative_control_contains_on_a_slice_of_texts_stays_refused { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn n(v: &[String], x: &String) -> bool { v.contains(x) }", &out, &st); + assert(out_is(n, &out, 0, "// t27o: refused fn n (line 1): type `String` at line 1\n\n")); + assert(st[NOK] == 0); +} + +/// unwrap_or (#10764) is `if (r != null) { r.? } else { d }` (t27 has no orelse), for an Option and a Result alike (both are ?T) +/// and for any T: the value of a let, an assignment or the whole tail of a fn. +test std_unwrap_or_is_an_if_where_it_stands_alone_as_a_value { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn a(head: Option<&str>) -> &str { head.unwrap_or(\"HEAD\") }\nfn c(t: &str) -> &str { t.strip_prefix(\"pub \").unwrap_or(t) }\nfn d(inner: &str) -> u32 { let count: u32 = inner.parse().unwrap_or(1); count }\nfn k(r: Result) -> u8 { r.unwrap_or(7) }\nfn q(x: Option) -> u32 { let mut y = 0; y = x.unwrap_or(5); y }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\nuse tri::t27b::type_text;\n\nfn a(head: ?[]const u8) -> []const u8 {\n return if (head != null) { head.? } else { \"HEAD\" };\n}\n\nfn c(t: []const u8) -> []const u8 {\n return if (rust_std::strip_prefix_text(t, \"pub \") != null) { rust_std::strip_prefix_text(t, \"pub \").? } else { t };\n}\n\nfn d(inner: []const u8) -> u32 {\n const count : u32 = if (rust_std::parse_u32(inner) != null) { rust_std::parse_u32(inner).? } else { 1 };\n return count;\n}\n\nfn k(r: ?u8) -> u8 {\n return if (r != null) { r.? } else { 7 };\n}\n\nfn q(x: ?u32) -> u32 {\n var y = 0;\n y = if (x != null) { x.? } else { 5 };\n return y;\n}\n\n")); + assert(st[NOK] == 5); +} + +/// An if used as a value is printed by the reference without parentheses, so its last arm takes in what follows (`(if ..) * 2.0`), +/// and the receiver is written twice: so the call must stand alone as a value, and the receiver must call only the std table's pure helpers +/// (a fn of the file may do anything, `next(s)` here). +test negative_control_unwrap_or_inside_an_expression_or_on_a_call_stays_refused { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn e(limit: Option) -> u32 { 1 + limit.unwrap_or(5) }\nfn f(x: Option) -> f64 { x.unwrap_or(0.5) * 2.0 }\nfn h(s: &str) -> usize { next(s).unwrap_or(0) }\nfn next(s: &str) -> Option { s.find('y') }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\n// t27o: refused fn e (line 1): method `unwrap_or` at line 1\n\nfn e(limit: ?u32) -> u32 {\n}\n\n// t27o: refused fn f (line 2): method `unwrap_or` at line 2\n\nfn f(x: ?f64) -> f64 {\n}\n\n// t27o: refused fn h (line 3): method `unwrap_or` at line 3\n\nfn h(s: []const u8) -> usize {\n}\n\nfn next(s: []const u8) -> ?usize {\n return rust_std::find_byte(s, 'y');\n}\n\n")); + assert(st[NOK] == 1); +} + +/// is_empty has the receiver itself as its subject, so an array receiver is not passed by address (it was: `(&a.len == 0)`). +test an_array_held_by_value_is_empty_by_its_length_not_by_its_address { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn e1(a: [u8; 3]) -> bool { a.is_empty() }", &out, &st); + assert(out_is(n, &out, 0, "fn e1(a: [3]u8) -> bool {\n return (a.len == 0);\n}\n\n")); + assert(st[NOK] == 1); +} + +/// x.len() is a usize whatever x is (#10764), so the integer rows apply to it: saturating_sub, div_ceil, pow, count_ones. +test a_len_call_types_its_receiver_as_usize { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn b(v: &[u8]) -> usize { v.len().saturating_sub(1) }\nfn c(b: &[u8]) -> usize { b.len().div_ceil(3) * 4 }\nfn d(s: &str) -> bool { s.len().pow(2) > 10 }\nfn e(v: &[u8]) -> u32 { v.len().count_ones() }\nfn m(v: &[u8]) -> usize { v.len().min(3) }", &out, &st); + assert(out_is(n, &out, 0, "use tools::t27o::rust_std;\n\nfn b(v: []const u8) -> usize {\n return rust_std::saturating_sub_usize(v.len, 1);\n}\n\nfn c(b: []const u8) -> usize {\n return rust_std::div_ceil_usize(b.len, 3) * 4;\n}\n\nfn d(s: []const u8) -> bool {\n return rust_std::pow_usize(s.len, 2) > 10;\n}\n\nfn e(v: []const u8) -> u32 {\n return rust_std::count_ones_usize(v.len);\n}\n\nfn m(v: []const u8) -> usize {\n return @min(v.len, 3);\n}\n\n")); + assert(st[NOK] == 5); +} + +/// When the file declares a fn or method named len, x.len() may be that one and return another type: the receiver is not typed. +test negative_control_a_len_the_file_declares_leaves_a_len_receiver_untyped { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("struct Q { n: u32 }\nimpl Q {\n pub fn len(&self) -> u32 { self.n }\n}\nfn k(q: &Q) -> u32 { q.len().saturating_sub(1) }", &out, &st); + assert(out_is(n, &out, 0, "const Q = struct {\n n : u32,\n};\n\npub fn Q_len(self: Q) -> u32 {\n return self.n;\n}\n\n// t27o: refused fn k (line 5): method `saturating_sub` at line 5\n\nfn k(q: Q) -> u32 {\n}\n\n")); + assert(st[NOK] == 1); +} + +/// (v.len() - 1) with v: &[u8] was typed u8 by the literal; no span, no row. +test negative_control_an_unsuffixed_literal_does_not_inherit_the_previous_names_element_type { + var out : [2048]u8 = undefined; + var st : [1024]usize = [0] ** 1024; + const n : usize = body("fn g(v: &[u8]) -> usize { (v.len() - 1).saturating_sub(2) }", &out, &st); + assert(out_is(n, &out, 0, "// t27o: refused fn g (line 1): method `saturating_sub` at line 1\n\nfn g(v: []const u8) -> usize {\n}\n\n")); + assert(st[NOK] == 0); +} diff --git a/specs/tools/t27o/rust_std.t27 b/specs/tools/t27o/rust_std.t27 index fd32d895e6..651c7efd0a 100644 --- a/specs/tools/t27o/rust_std.t27 +++ b/specs/tools/t27o/rust_std.t27 @@ -8,7 +8,9 @@ ; starts_with / ends_with, tri::t27b::type_text's same for `==` on texts and alpha / digit -- or a ; builtin every backend lowers (`.len`, `@abs` / `@min` / `@max` of floats, `+%`). Only the rest is ; written here, once: contains, parse, sum, integer abs, the checked arithmetic, #9100's needle fns -; and #9098's appends. +; and #9098's appends, and (#10764) the bit counts, pow, the saturating family, div_ceil, the float and +; ASCII helpers, a slice's get and contains. The ones that take an integer type are one fn per width +; (t27 has no generics), named _; the table's `%` writes T. ; Rust's three trims are NOT fns anywhere in this table's output: a t27 fn that returns `[]const u8` ; is emitted by gen-rust as `-> &'static str`, and a fn whose body hands back a slice of its parameter ; cannot satisfy that (E0308, the four stale copies of #9226). The trim entries lower to the slice @@ -23,6 +25,34 @@ ; abs (i8..i64) abs_ std_sum_abs_min_max_and_wrapping ; wrapping_add / sub / mul `+%`, `-%`, `*%` std_sum_abs_min_max_and_wrapping ; checked_add / sub / mul (u32 u64 usize i32 i64) checked__ std_checked_arithmetic +; count_ones, leading_zeros, trailing_zeros (u8 u16 u32 u64 usize i8 i16 i32 i64) +; count_ones_ / leading_zeros_ / trailing_zeros_, u32 +; (#10764) std_bit_counts_are_rusts +; saturating_add / sub / mul (the same nine types) saturating__; hosting::panel has the u64 add, a +; `use` of it splices 28 modules (#7176) so it is written here +; (#10764) std_saturating_arithmetic_of__is_rusts +; div_ceil (u8 u16 u32 u64 usize) div_ceil_; a zero divisor traps as Rust's panics; the signed +; div_ceil is unstable in Rust (#10764) std_div_ceil_of__is_rusts +; sqrt (f32, f64) `@sqrt` (IEEE 754 square root, correctly rounded) +; std_f64_sqrt_is_finite_and_to_bits_are_rusts +; is_finite, to_bits (f32, f64) is_finite_, to_bits_ (`(x - x) == 0.0`, `@bitCast`; the second is +; printed as written by gen-rust, which rustc does not read) (#10764) +; std_f32_sqrt_is_finite_and_to_bits_are_rusts +; ln refused: a libm function, see R_LIBM in rust_convert.t27 +; is_ascii (text, byte slice, u8) is_ascii_text, is_ascii_u8 std_ascii_methods_are_rusts +; to_ascii_lowercase / uppercase (u8) to_ascii_lowercase_u8 / _uppercase_u8 (a text's returns an owned +; String and t27o has no char class: both stay refused) (#10764) +; get(i) on a slice of scalars (u8 .. i64, usize, f32, f64) get_, ?T (#10764) std_get_of__is_rusts +; contains(&x) on a slice of u16 .. i64, usize, f32, f64 contains_ (u8 is bytes_contain) +; contains(c) on a text, c a char in a variable str_contains_char: the char's UTF-8 bytes (#10764) +; std_contains_of__is_rusts, +; std_contains_of_a_char_is_rusts +; unwrap_or(d) on an Option or a Result `if (r != null) { r.? } else { d }` -- t27 has no `orelse`; the +; receiver is written twice (a pure std helper only) and the form +; stands alone as a value, for the reference prints an `if` without +; parentheses (#10764) std_unwrap_or_is_rusts +; pow (u8 u16 u32 u64 usize i8 i16 i32 i64) pow_: Rust's loop, so an overflow traps where a +; debug build panics (#10764) std_pow_of__is_rusts ; trim, trim_start, trim_end the slice `s[trim_lo(..) .. trim_hi(..)]` written at the use ; site (a fn returning []const u8 cannot be emitted; the ; vectors live in type_text's trim test) std_trim_is_rusts_white_space_trim @@ -474,6 +504,760 @@ pub fn checked_mul_i64(a: i64, b: i64) -> ?i64 { return a * b; } +// ---------------------------------------------------------------- bit counts + +/// u64::count_ones: how many bits of x are set. The narrower unsigned types widen to it (zero bits +/// add nothing); a signed one counts the two's complement pattern through count_ones_i64. +pub fn count_ones_u64(x: u64) -> u32 { + var c : u32 = 0; + var y : u64 = x; + while (y != 0) { + c = c + ((y & 1) as u32); + y = y >> 1; + } + return c; +} + +pub fn count_ones_u8(x: u8) -> u32 { + return count_ones_u64(x as u64); +} + +pub fn count_ones_u16(x: u16) -> u32 { + return count_ones_u64(x as u64); +} + +pub fn count_ones_u32(x: u32) -> u32 { + return count_ones_u64(x as u64); +} + +/// usize is the 64-bit host's (as the oracle's rustc builds for). +pub fn count_ones_usize(x: usize) -> u32 { + return count_ones_u64(x as u64); +} + +/// A negative i64 has 64 - (ones of its complement) set bits; its complement is -1 - x, which is +/// never negative and never overflows (x = MIN gives MAX). +pub fn count_ones_i64(x: i64) -> u32 { + if (x < 0) { return 64 - count_ones_u64((-1 - x) as u64); } + return count_ones_u64(x as u64); +} + +/// A narrower signed type sign-extends to i64, which adds (64 - width) set bits when it is negative. +pub fn count_ones_i8(x: i8) -> u32 { + const w : u32 = count_ones_i64(x as i64); + if (x < 0) { return w - 56; } + return w; +} + +pub fn count_ones_i16(x: i16) -> u32 { + const w : u32 = count_ones_i64(x as i64); + if (x < 0) { return w - 48; } + return w; +} + +pub fn count_ones_i32(x: i32) -> u32 { + const w : u32 = count_ones_i64(x as i64); + if (x < 0) { return w - 32; } + return w; +} + +/// u64::leading_zeros: the zero bits above the highest set bit, 64 for 0. +pub fn leading_zeros_u64(x: u64) -> u32 { + var c : u32 = 0; + var y : u64 = x; + while (c < 64 and (y & 9223372036854775808) == 0) { + y = y << 1; + c = c + 1; + } + return c; +} + +/// The narrower unsigned types widen to u64, which puts (64 - width) more zeros on top. +pub fn leading_zeros_u8(x: u8) -> u32 { + return leading_zeros_u64(x as u64) - 56; +} + +pub fn leading_zeros_u16(x: u16) -> u32 { + return leading_zeros_u64(x as u64) - 48; +} + +pub fn leading_zeros_u32(x: u32) -> u32 { + return leading_zeros_u64(x as u64) - 32; +} + +pub fn leading_zeros_usize(x: usize) -> u32 { + return leading_zeros_u64(x as u64); +} + +/// A negative signed value has its sign bit set, so no zero above it; otherwise it counts as the +/// unsigned type of its width does. +pub fn leading_zeros_i8(x: i8) -> u32 { + if (x < 0) { return 0; } + return leading_zeros_u64(x as u64) - 56; +} + +pub fn leading_zeros_i16(x: i16) -> u32 { + if (x < 0) { return 0; } + return leading_zeros_u64(x as u64) - 48; +} + +pub fn leading_zeros_i32(x: i32) -> u32 { + if (x < 0) { return 0; } + return leading_zeros_u64(x as u64) - 32; +} + +pub fn leading_zeros_i64(x: i64) -> u32 { + if (x < 0) { return 0; } + return leading_zeros_u64(x as u64); +} + +/// u64::trailing_zeros: the zero bits below the lowest set bit, 64 for 0. +pub fn trailing_zeros_u64(x: u64) -> u32 { + if (x == 0) { return 64; } + var c : u32 = 0; + var y : u64 = x; + while ((y & 1) == 0) { + y = y >> 1; + c = c + 1; + } + return c; +} + +/// A zero has its whole width as trailing zeros; any other narrower unsigned value counts as its u64 (widening adds +/// zeros only on top). +pub fn trailing_zeros_u8(x: u8) -> u32 { + if (x == 0) { return 8; } + return trailing_zeros_u64(x as u64); +} + +pub fn trailing_zeros_u16(x: u16) -> u32 { + if (x == 0) { return 16; } + return trailing_zeros_u64(x as u64); +} + +pub fn trailing_zeros_u32(x: u32) -> u32 { + if (x == 0) { return 32; } + return trailing_zeros_u64(x as u64); +} + +pub fn trailing_zeros_usize(x: usize) -> u32 { + return trailing_zeros_u64(x as u64); +} + +/// A signed value is read by halving, which is exact while the low bit is clear (a negative even +/// number halves without remainder), so MIN needs no unsigned cast. +pub fn trailing_zeros_i64(x: i64) -> u32 { + if (x == 0) { return 64; } + var c : u32 = 0; + var y : i64 = x; + while ((y & 1) == 0) { + y = y / 2; + c = c + 1; + } + return c; +} + +/// Sign extension keeps the low bits, so a narrower signed type counts as its i64. +pub fn trailing_zeros_i8(x: i8) -> u32 { + if (x == 0) { return 8; } + return trailing_zeros_i64(x as i64); +} + +pub fn trailing_zeros_i16(x: i16) -> u32 { + if (x == 0) { return 16; } + return trailing_zeros_i64(x as i64); +} + +pub fn trailing_zeros_i32(x: i32) -> u32 { + if (x == 0) { return 32; } + return trailing_zeros_i64(x as i64); +} + +// ---------------------------------------------------------------- integer pow + +/// Rust's `pow` for an integer type, step for step: the squarings and products it makes are the ones +/// below, so the overflow they trap on (a panic in a debug build, a trap here as for every `*` t27o +/// converts) is the same. The exponent is a u32 whatever the base. checked_pow and wrapping_pow are the +/// same loop over checked_mul and `*%`. +pub fn pow_u8(x: u8, e: u32) -> u8 { + if (e == 0) { return 1; } + var acc : u8 = 1; + var base : u8 = x; + var n : u32 = e; + while (n > 1) { + if ((n & 1) == 1) { acc = acc * base; } + n = n / 2; + base = base * base; + } + return acc * base; +} + +pub fn pow_u16(x: u16, e: u32) -> u16 { + if (e == 0) { return 1; } + var acc : u16 = 1; + var base : u16 = x; + var n : u32 = e; + while (n > 1) { + if ((n & 1) == 1) { acc = acc * base; } + n = n / 2; + base = base * base; + } + return acc * base; +} + +pub fn pow_u32(x: u32, e: u32) -> u32 { + if (e == 0) { return 1; } + var acc : u32 = 1; + var base : u32 = x; + var n : u32 = e; + while (n > 1) { + if ((n & 1) == 1) { acc = acc * base; } + n = n / 2; + base = base * base; + } + return acc * base; +} + +pub fn pow_u64(x: u64, e: u32) -> u64 { + if (e == 0) { return 1; } + var acc : u64 = 1; + var base : u64 = x; + var n : u32 = e; + while (n > 1) { + if ((n & 1) == 1) { acc = acc * base; } + n = n / 2; + base = base * base; + } + return acc * base; +} + +pub fn pow_usize(x: usize, e: u32) -> usize { + if (e == 0) { return 1; } + var acc : usize = 1; + var base : usize = x; + var n : u32 = e; + while (n > 1) { + if ((n & 1) == 1) { acc = acc * base; } + n = n / 2; + base = base * base; + } + return acc * base; +} + +pub fn pow_i8(x: i8, e: u32) -> i8 { + if (e == 0) { return 1; } + var acc : i8 = 1; + var base : i8 = x; + var n : u32 = e; + while (n > 1) { + if ((n & 1) == 1) { acc = acc * base; } + n = n / 2; + base = base * base; + } + return acc * base; +} + +pub fn pow_i16(x: i16, e: u32) -> i16 { + if (e == 0) { return 1; } + var acc : i16 = 1; + var base : i16 = x; + var n : u32 = e; + while (n > 1) { + if ((n & 1) == 1) { acc = acc * base; } + n = n / 2; + base = base * base; + } + return acc * base; +} + +pub fn pow_i32(x: i32, e: u32) -> i32 { + if (e == 0) { return 1; } + var acc : i32 = 1; + var base : i32 = x; + var n : u32 = e; + while (n > 1) { + if ((n & 1) == 1) { acc = acc * base; } + n = n / 2; + base = base * base; + } + return acc * base; +} + +pub fn pow_i64(x: i64, e: u32) -> i64 { + if (e == 0) { return 1; } + var acc : i64 = 1; + var base : i64 = x; + var n : u32 = e; + while (n > 1) { + if ((n & 1) == 1) { acc = acc * base; } + n = n / 2; + base = base * base; + } + return acc * base; +} + +// ---------------------------------------------------------------- saturating arithmetic + +/// u64::saturating_add: a + b, or the largest u64 when that does not fit. hosting::panel has this fn +/// too, but a `use` of it splices 28 modules into the converted spec (#7176), so it is written here, +/// once, with the rest of the family. The unsigned types narrower than 64 bits add and multiply in +/// u64 and clamp; usize is the 64-bit host's. +pub fn saturating_add_u64(a: u64, b: u64) -> u64 { + if (b > 18446744073709551615 - a) { return 18446744073709551615; } + return a + b; +} + +pub fn saturating_sub_u64(a: u64, b: u64) -> u64 { + if (b > a) { return 0; } + return a - b; +} + +pub fn saturating_mul_u64(a: u64, b: u64) -> u64 { + if (a != 0 and b > 18446744073709551615 / a) { return 18446744073709551615; } + return a * b; +} + +pub fn saturating_add_usize(a: usize, b: usize) -> usize { + return saturating_add_u64(a as u64, b as u64) as usize; +} + +pub fn saturating_sub_usize(a: usize, b: usize) -> usize { + return saturating_sub_u64(a as u64, b as u64) as usize; +} + +pub fn saturating_mul_usize(a: usize, b: usize) -> usize { + return saturating_mul_u64(a as u64, b as u64) as usize; +} + +pub fn saturating_add_u32(a: u32, b: u32) -> u32 { + const r : u64 = (a as u64) + (b as u64); + if (r > 4294967295) { return 4294967295; } + return r as u32; +} + +pub fn saturating_sub_u32(a: u32, b: u32) -> u32 { + if (b > a) { return 0; } + return a - b; +} + +pub fn saturating_mul_u32(a: u32, b: u32) -> u32 { + const r : u64 = (a as u64) * (b as u64); + if (r > 4294967295) { return 4294967295; } + return r as u32; +} + +pub fn saturating_add_u16(a: u16, b: u16) -> u16 { + const r : u64 = (a as u64) + (b as u64); + if (r > 65535) { return 65535; } + return r as u16; +} + +pub fn saturating_sub_u16(a: u16, b: u16) -> u16 { + if (b > a) { return 0; } + return a - b; +} + +pub fn saturating_mul_u16(a: u16, b: u16) -> u16 { + const r : u64 = (a as u64) * (b as u64); + if (r > 65535) { return 65535; } + return r as u16; +} + +pub fn saturating_add_u8(a: u8, b: u8) -> u8 { + const r : u64 = (a as u64) + (b as u64); + if (r > 255) { return 255; } + return r as u8; +} + +pub fn saturating_sub_u8(a: u8, b: u8) -> u8 { + if (b > a) { return 0; } + return a - b; +} + +pub fn saturating_mul_u8(a: u8, b: u8) -> u8 { + const r : u64 = (a as u64) * (b as u64); + if (r > 255) { return 255; } + return r as u8; +} + +/// A signed i64 saturates by the direction of the overflow checked_* found: an addition overflows +/// upward when b > 0, a subtraction downward when b > 0, a product upward when the signs agree. +pub fn saturating_add_i64(a: i64, b: i64) -> i64 { + const r : ?i64 = checked_add_i64(a, b); + if (r == null) { + if (b > 0) { return I64_MAX; } + return I64_MIN; + } + return r.?; +} + +pub fn saturating_sub_i64(a: i64, b: i64) -> i64 { + const r : ?i64 = checked_sub_i64(a, b); + if (r == null) { + if (b > 0) { return I64_MIN; } + return I64_MAX; + } + return r.?; +} + +pub fn saturating_mul_i64(a: i64, b: i64) -> i64 { + const r : ?i64 = checked_mul_i64(a, b); + if (r == null) { + if ((a < 0) == (b < 0)) { return I64_MAX; } + return I64_MIN; + } + return r.?; +} + +/// The signed types narrower than 64 bits compute in i64, which holds every sum, difference and +/// product of two of them, and clamp. +pub fn saturating_add_i32(a: i32, b: i32) -> i32 { + const r : i64 = (a as i64) + (b as i64); + if (r > 2147483647) { return I32_MAX; } + if (r < -2147483648) { return I32_MIN; } + return r as i32; +} + +pub fn saturating_sub_i32(a: i32, b: i32) -> i32 { + const r : i64 = (a as i64) - (b as i64); + if (r > 2147483647) { return I32_MAX; } + if (r < -2147483648) { return I32_MIN; } + return r as i32; +} + +pub fn saturating_mul_i32(a: i32, b: i32) -> i32 { + const r : i64 = (a as i64) * (b as i64); + if (r > 2147483647) { return I32_MAX; } + if (r < -2147483648) { return I32_MIN; } + return r as i32; +} + +pub fn saturating_add_i16(a: i16, b: i16) -> i16 { + const r : i64 = (a as i64) + (b as i64); + if (r > 32767) { return 32767; } + if (r < -32768) { return -32768; } + return r as i16; +} + +pub fn saturating_sub_i16(a: i16, b: i16) -> i16 { + const r : i64 = (a as i64) - (b as i64); + if (r > 32767) { return 32767; } + if (r < -32768) { return -32768; } + return r as i16; +} + +pub fn saturating_mul_i16(a: i16, b: i16) -> i16 { + const r : i64 = (a as i64) * (b as i64); + if (r > 32767) { return 32767; } + if (r < -32768) { return -32768; } + return r as i16; +} + +pub fn saturating_add_i8(a: i8, b: i8) -> i8 { + const r : i64 = (a as i64) + (b as i64); + if (r > 127) { return 127; } + if (r < -128) { return -128; } + return r as i8; +} + +pub fn saturating_sub_i8(a: i8, b: i8) -> i8 { + const r : i64 = (a as i64) - (b as i64); + if (r > 127) { return 127; } + if (r < -128) { return -128; } + return r as i8; +} + +pub fn saturating_mul_i8(a: i8, b: i8) -> i8 { + const r : i64 = (a as i64) * (b as i64); + if (r > 127) { return 127; } + if (r < -128) { return -128; } + return r as i8; +} + +// ---------------------------------------------------------------- div_ceil + +/// u64::div_ceil: the quotient rounded up. A zero divisor traps, as Rust's panics. The narrower unsigned +/// types widen to u64 (the quotient is never above the dividend, so it narrows back); usize is the +/// 64-bit host's. The signed div_ceil is unstable in Rust and is not here. +pub fn div_ceil_u64(a: u64, b: u64) -> u64 { + const q : u64 = a / b; + if (a % b > 0) { return q + 1; } + return q; +} + +pub fn div_ceil_usize(a: usize, b: usize) -> usize { + return div_ceil_u64(a as u64, b as u64) as usize; +} + +pub fn div_ceil_u32(a: u32, b: u32) -> u32 { + return div_ceil_u64(a as u64, b as u64) as u32; +} + +pub fn div_ceil_u16(a: u16, b: u16) -> u16 { + return div_ceil_u64(a as u64, b as u64) as u16; +} + +pub fn div_ceil_u8(a: u8, b: u8) -> u8 { + return div_ceil_u64(a as u64, b as u64) as u8; +} + +// ---------------------------------------------------------------- floats + +/// f64::is_finite: neither NaN nor an infinity. x - x is 0 for every finite x and NaN for a NaN and for an +/// infinity, so the test needs no infinity constant and no bit reading. +pub fn is_finite_f64(x: f64) -> bool { + return (x - x) == 0.0; +} + +pub fn is_finite_f32(x: f32) -> bool { + return (x - x) == 0.0; +} + +/// f64::to_bits: the IEEE 754 binary64 pattern of x, every bit of a NaN's payload kept. `@bitCast` is exact +/// in the Zig and t27b backends (specs/tri/t27b/conformance/bit_cast.t27 pins it); gen-rust prints it as +/// written, which rustc does not read, so converted output that calls this fn is for those two. +pub fn to_bits_f64(x: f64) -> u64 { + const b : u64 = @bitCast(x); + return b; +} + +pub fn to_bits_f32(x: f32) -> u32 { + const b : u32 = @bitCast(x); + return b; +} + +/// f64::from_bits, the inverse of to_bits_f64: the float of a binary64 pattern. It builds the NaNs and the +/// infinities the tests below need; the table does not map a path call to it. +pub fn from_bits_f64(b: u64) -> f64 { + const x : f64 = @bitCast(b); + return x; +} + +pub fn from_bits_f32(b: u32) -> f32 { + const x : f32 = @bitCast(b); + return x; +} + +// ---------------------------------------------------------------- ASCII + +/// u8::is_ascii: the byte is below 128 (char::is_ascii is the same test on the ASCII corpus). +pub fn is_ascii_u8(b: u8) -> bool { + return b < 128; +} + +/// str::is_ascii and [u8]::is_ascii: every byte is below 128; the empty text is ASCII. +pub fn is_ascii_text(s: []const u8) -> bool { + var i : usize = 0; + while (i < s.len) { + if (s[i] >= 128) { return false; } + i += 1; + } + return true; +} + +/// u8::to_ascii_lowercase: A-Z become a-z, every other byte (control, digit, punctuation, above 127) stays. +pub fn to_ascii_lowercase_u8(b: u8) -> u8 { + if (b >= 65 and b <= 90) { return b + 32; } + return b; +} + +/// u8::to_ascii_uppercase: a-z become A-Z, every other byte stays. +pub fn to_ascii_uppercase_u8(b: u8) -> u8 { + if (b >= 97 and b <= 122) { return b - 32; } + return b; +} + +// ---------------------------------------------------------------- slice get + +/// [T]::get(i) for a scalar T: the element at i, or null past the end. Option<&T> is ?T here (a reference to a +/// scalar is the scalar); get(a..b) is not this fn, the converter leaves a range alone. The element is bound +/// before it is returned: gen-rust wraps a returned name in Some(..) but not a returned index. +pub fn get_u8(xs: []const u8, i: usize) -> ?u8 { + if (i >= xs.len) { return null; } + const v : u8 = xs[i]; + return v; +} + +pub fn get_u16(xs: []const u16, i: usize) -> ?u16 { + if (i >= xs.len) { return null; } + const v : u16 = xs[i]; + return v; +} + +pub fn get_u32(xs: []const u32, i: usize) -> ?u32 { + if (i >= xs.len) { return null; } + const v : u32 = xs[i]; + return v; +} + +pub fn get_u64(xs: []const u64, i: usize) -> ?u64 { + if (i >= xs.len) { return null; } + const v : u64 = xs[i]; + return v; +} + +pub fn get_usize(xs: []const usize, i: usize) -> ?usize { + if (i >= xs.len) { return null; } + const v : usize = xs[i]; + return v; +} + +pub fn get_i8(xs: []const i8, i: usize) -> ?i8 { + if (i >= xs.len) { return null; } + const v : i8 = xs[i]; + return v; +} + +pub fn get_i16(xs: []const i16, i: usize) -> ?i16 { + if (i >= xs.len) { return null; } + const v : i16 = xs[i]; + return v; +} + +pub fn get_i32(xs: []const i32, i: usize) -> ?i32 { + if (i >= xs.len) { return null; } + const v : i32 = xs[i]; + return v; +} + +pub fn get_i64(xs: []const i64, i: usize) -> ?i64 { + if (i >= xs.len) { return null; } + const v : i64 = xs[i]; + return v; +} + +pub fn get_f32(xs: []const f32, i: usize) -> ?f32 { + if (i >= xs.len) { return null; } + const v : f32 = xs[i]; + return v; +} + +pub fn get_f64(xs: []const f64, i: usize) -> ?f64 { + if (i >= xs.len) { return null; } + const v : f64 = xs[i]; + return v; +} + +// ---------------------------------------------------------------- slice contains + +/// [T]::contains(&x) for a scalar T: some element is `==` x, so a NaN is never contained and -0.0 is 0.0. +/// (The u8 slice is bytes_contain, above.) +pub fn contains_u16(xs: []const u16, x: u16) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +pub fn contains_u32(xs: []const u32, x: u32) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +pub fn contains_u64(xs: []const u64, x: u64) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +pub fn contains_usize(xs: []const usize, x: usize) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +pub fn contains_i8(xs: []const i8, x: i8) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +pub fn contains_i16(xs: []const i16, x: i16) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +pub fn contains_i32(xs: []const i32, x: i32) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +pub fn contains_i64(xs: []const i64, x: i64) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +pub fn contains_f32(xs: []const f32, x: f32) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +pub fn contains_f64(xs: []const f64, x: f64) -> bool { + var i : usize = 0; + while (i < xs.len) { + if (xs[i] == x) { return true; } + i += 1; + } + return false; +} + +/// str::contains with a char held in a variable (t27o holds a char as its u32 scalar value): the char's UTF-8 +/// bytes occur in s. A char literal needle never gets here, it is written as the one-byte text it is. +pub fn str_contains_char(s: []const u8, c: u32) -> bool { + var enc : [4]u8 = [0, 0, 0, 0]; + var n : usize = 1; + if (c < 128) { + enc[0] = c as u8; + } else if (c < 2048) { + enc[0] = (192 + (c >> 6)) as u8; + enc[1] = (128 + (c & 63)) as u8; + n = 2; + } else if (c < 65536) { + enc[0] = (224 + (c >> 12)) as u8; + enc[1] = (128 + ((c >> 6) & 63)) as u8; + enc[2] = (128 + (c & 63)) as u8; + n = 3; + } else { + enc[0] = (240 + (c >> 18)) as u8; + enc[1] = (128 + ((c >> 12) & 63)) as u8; + enc[2] = (128 + ((c >> 6) & 63)) as u8; + enc[3] = (128 + (c & 63)) as u8; + n = 4; + } + return find_text(s, enc[0 .. n]) != null; +} + /// Append t at w; the new write cursor. A String's push_str, lowered by t27o (#9098): the owned /// String goes through a caller's buffer, and push_str is one append onto it. pub fn append_text(out: []u8, w: usize, t: []const u8) -> usize { @@ -1283,6 +2067,3558 @@ test std_checked_arithmetic { assert(checked_mul_i64(I64_MIN, I64_MIN) == null); } +/// Bit counts: the three methods count the same pattern of an integer of each width (count_ones_*, +/// leading_zeros_*, trailing_zeros_*), every expected value printed by rustc 1.99 on the same inputs. +/// Edge values per width: 0, 1, 2, the highest bit alone, all ones, MIN / MAX, -1, an alternating pattern. +test std_bit_counts_are_rusts { + // u8 + assert(count_ones_u8(0) == 0); + assert(count_ones_u8(1) == 1); + assert(count_ones_u8(2) == 1); + assert(count_ones_u8(3) == 2); + assert(count_ones_u8(7) == 3); + assert(count_ones_u8(8) == 1); + assert(count_ones_u8(16) == 1); + assert(count_ones_u8(85) == 4); + assert(count_ones_u8(127) == 7); + assert(count_ones_u8(128) == 1); + assert(count_ones_u8(170) == 4); + assert(count_ones_u8(254) == 7); + assert(count_ones_u8(255) == 8); + assert(count_ones_u8(96) == 2); + assert(leading_zeros_u8(0) == 8); + assert(leading_zeros_u8(1) == 7); + assert(leading_zeros_u8(2) == 6); + assert(leading_zeros_u8(3) == 6); + assert(leading_zeros_u8(7) == 5); + assert(leading_zeros_u8(8) == 4); + assert(leading_zeros_u8(16) == 3); + assert(leading_zeros_u8(85) == 1); + assert(leading_zeros_u8(127) == 1); + assert(leading_zeros_u8(128) == 0); + assert(leading_zeros_u8(170) == 0); + assert(leading_zeros_u8(254) == 0); + assert(leading_zeros_u8(255) == 0); + assert(leading_zeros_u8(96) == 1); + assert(trailing_zeros_u8(0) == 8); + assert(trailing_zeros_u8(1) == 0); + assert(trailing_zeros_u8(2) == 1); + assert(trailing_zeros_u8(3) == 0); + assert(trailing_zeros_u8(7) == 0); + assert(trailing_zeros_u8(8) == 3); + assert(trailing_zeros_u8(16) == 4); + assert(trailing_zeros_u8(85) == 0); + assert(trailing_zeros_u8(127) == 0); + assert(trailing_zeros_u8(128) == 7); + assert(trailing_zeros_u8(170) == 1); + assert(trailing_zeros_u8(254) == 1); + assert(trailing_zeros_u8(255) == 0); + assert(trailing_zeros_u8(96) == 5); + // u16 + assert(count_ones_u16(0) == 0); + assert(count_ones_u16(1) == 1); + assert(count_ones_u16(2) == 1); + assert(count_ones_u16(255) == 8); + assert(count_ones_u16(256) == 1); + assert(count_ones_u16(4096) == 1); + assert(count_ones_u16(21845) == 8); + assert(count_ones_u16(32767) == 15); + assert(count_ones_u16(32768) == 1); + assert(count_ones_u16(43690) == 8); + assert(count_ones_u16(65534) == 15); + assert(count_ones_u16(65535) == 16); + assert(count_ones_u16(24576) == 2); + assert(leading_zeros_u16(0) == 16); + assert(leading_zeros_u16(1) == 15); + assert(leading_zeros_u16(2) == 14); + assert(leading_zeros_u16(255) == 8); + assert(leading_zeros_u16(256) == 7); + assert(leading_zeros_u16(4096) == 3); + assert(leading_zeros_u16(21845) == 1); + assert(leading_zeros_u16(32767) == 1); + assert(leading_zeros_u16(32768) == 0); + assert(leading_zeros_u16(43690) == 0); + assert(leading_zeros_u16(65534) == 0); + assert(leading_zeros_u16(65535) == 0); + assert(leading_zeros_u16(24576) == 1); + assert(trailing_zeros_u16(0) == 16); + assert(trailing_zeros_u16(1) == 0); + assert(trailing_zeros_u16(2) == 1); + assert(trailing_zeros_u16(255) == 0); + assert(trailing_zeros_u16(256) == 8); + assert(trailing_zeros_u16(4096) == 12); + assert(trailing_zeros_u16(21845) == 0); + assert(trailing_zeros_u16(32767) == 0); + assert(trailing_zeros_u16(32768) == 15); + assert(trailing_zeros_u16(43690) == 1); + assert(trailing_zeros_u16(65534) == 1); + assert(trailing_zeros_u16(65535) == 0); + assert(trailing_zeros_u16(24576) == 13); + // u32 + assert(count_ones_u32(0) == 0); + assert(count_ones_u32(1) == 1); + assert(count_ones_u32(2) == 1); + assert(count_ones_u32(3) == 2); + assert(count_ones_u32(65535) == 16); + assert(count_ones_u32(65536) == 1); + assert(count_ones_u32(1431655765) == 16); + assert(count_ones_u32(2147483647) == 31); + assert(count_ones_u32(2147483648) == 1); + assert(count_ones_u32(2863311530) == 16); + assert(count_ones_u32(4294967294) == 31); + assert(count_ones_u32(4294967295) == 32); + assert(count_ones_u32(16777216) == 1); + assert(count_ones_u32(3221225472) == 2); + assert(leading_zeros_u32(0) == 32); + assert(leading_zeros_u32(1) == 31); + assert(leading_zeros_u32(2) == 30); + assert(leading_zeros_u32(3) == 30); + assert(leading_zeros_u32(65535) == 16); + assert(leading_zeros_u32(65536) == 15); + assert(leading_zeros_u32(1431655765) == 1); + assert(leading_zeros_u32(2147483647) == 1); + assert(leading_zeros_u32(2147483648) == 0); + assert(leading_zeros_u32(2863311530) == 0); + assert(leading_zeros_u32(4294967294) == 0); + assert(leading_zeros_u32(4294967295) == 0); + assert(leading_zeros_u32(16777216) == 7); + assert(leading_zeros_u32(3221225472) == 0); + assert(trailing_zeros_u32(0) == 32); + assert(trailing_zeros_u32(1) == 0); + assert(trailing_zeros_u32(2) == 1); + assert(trailing_zeros_u32(3) == 0); + assert(trailing_zeros_u32(65535) == 0); + assert(trailing_zeros_u32(65536) == 16); + assert(trailing_zeros_u32(1431655765) == 0); + assert(trailing_zeros_u32(2147483647) == 0); + assert(trailing_zeros_u32(2147483648) == 31); + assert(trailing_zeros_u32(2863311530) == 1); + assert(trailing_zeros_u32(4294967294) == 1); + assert(trailing_zeros_u32(4294967295) == 0); + assert(trailing_zeros_u32(16777216) == 24); + assert(trailing_zeros_u32(3221225472) == 30); + // u64 + assert(count_ones_u64(0) == 0); + assert(count_ones_u64(1) == 1); + assert(count_ones_u64(2) == 1); + assert(count_ones_u64(4294967295) == 32); + assert(count_ones_u64(4294967296) == 1); + assert(count_ones_u64(6148914691236517205) == 32); + assert(count_ones_u64(9223372036854775807) == 63); + assert(count_ones_u64(9223372036854775808) == 1); + assert(count_ones_u64(12297829382473034410) == 32); + assert(count_ones_u64(18446744073709551614) == 63); + assert(count_ones_u64(18446744073709551615) == 64); + assert(count_ones_u64(281474976710656) == 1); + assert(count_ones_u64(72057594037927936) == 1); + assert(count_ones_u64(3) == 2); + assert(count_ones_u64(9223372036854775810) == 2); + assert(leading_zeros_u64(0) == 64); + assert(leading_zeros_u64(1) == 63); + assert(leading_zeros_u64(2) == 62); + assert(leading_zeros_u64(4294967295) == 32); + assert(leading_zeros_u64(4294967296) == 31); + assert(leading_zeros_u64(6148914691236517205) == 1); + assert(leading_zeros_u64(9223372036854775807) == 1); + assert(leading_zeros_u64(9223372036854775808) == 0); + assert(leading_zeros_u64(12297829382473034410) == 0); + assert(leading_zeros_u64(18446744073709551614) == 0); + assert(leading_zeros_u64(18446744073709551615) == 0); + assert(leading_zeros_u64(281474976710656) == 15); + assert(leading_zeros_u64(72057594037927936) == 7); + assert(leading_zeros_u64(3) == 62); + assert(leading_zeros_u64(9223372036854775810) == 0); + assert(trailing_zeros_u64(0) == 64); + assert(trailing_zeros_u64(1) == 0); + assert(trailing_zeros_u64(2) == 1); + assert(trailing_zeros_u64(4294967295) == 0); + assert(trailing_zeros_u64(4294967296) == 32); + assert(trailing_zeros_u64(6148914691236517205) == 0); + assert(trailing_zeros_u64(9223372036854775807) == 0); + assert(trailing_zeros_u64(9223372036854775808) == 63); + assert(trailing_zeros_u64(12297829382473034410) == 1); + assert(trailing_zeros_u64(18446744073709551614) == 1); + assert(trailing_zeros_u64(18446744073709551615) == 0); + assert(trailing_zeros_u64(281474976710656) == 48); + assert(trailing_zeros_u64(72057594037927936) == 56); + assert(trailing_zeros_u64(3) == 0); + assert(trailing_zeros_u64(9223372036854775810) == 1); + // usize + assert(count_ones_usize(0) == 0); + assert(count_ones_usize(1) == 1); + assert(count_ones_usize(2) == 1); + assert(count_ones_usize(4294967295) == 32); + assert(count_ones_usize(4294967296) == 1); + assert(count_ones_usize(6148914691236517205) == 32); + assert(count_ones_usize(9223372036854775807) == 63); + assert(count_ones_usize(9223372036854775808) == 1); + assert(count_ones_usize(12297829382473034410) == 32); + assert(count_ones_usize(18446744073709551614) == 63); + assert(count_ones_usize(18446744073709551615) == 64); + assert(count_ones_usize(281474976710656) == 1); + assert(count_ones_usize(72057594037927936) == 1); + assert(count_ones_usize(3) == 2); + assert(count_ones_usize(9223372036854775810) == 2); + assert(leading_zeros_usize(0) == 64); + assert(leading_zeros_usize(1) == 63); + assert(leading_zeros_usize(2) == 62); + assert(leading_zeros_usize(4294967295) == 32); + assert(leading_zeros_usize(4294967296) == 31); + assert(leading_zeros_usize(6148914691236517205) == 1); + assert(leading_zeros_usize(9223372036854775807) == 1); + assert(leading_zeros_usize(9223372036854775808) == 0); + assert(leading_zeros_usize(12297829382473034410) == 0); + assert(leading_zeros_usize(18446744073709551614) == 0); + assert(leading_zeros_usize(18446744073709551615) == 0); + assert(leading_zeros_usize(281474976710656) == 15); + assert(leading_zeros_usize(72057594037927936) == 7); + assert(leading_zeros_usize(3) == 62); + assert(leading_zeros_usize(9223372036854775810) == 0); + assert(trailing_zeros_usize(0) == 64); + assert(trailing_zeros_usize(1) == 0); + assert(trailing_zeros_usize(2) == 1); + assert(trailing_zeros_usize(4294967295) == 0); + assert(trailing_zeros_usize(4294967296) == 32); + assert(trailing_zeros_usize(6148914691236517205) == 0); + assert(trailing_zeros_usize(9223372036854775807) == 0); + assert(trailing_zeros_usize(9223372036854775808) == 63); + assert(trailing_zeros_usize(12297829382473034410) == 1); + assert(trailing_zeros_usize(18446744073709551614) == 1); + assert(trailing_zeros_usize(18446744073709551615) == 0); + assert(trailing_zeros_usize(281474976710656) == 48); + assert(trailing_zeros_usize(72057594037927936) == 56); + assert(trailing_zeros_usize(3) == 0); + assert(trailing_zeros_usize(9223372036854775810) == 1); + // i8 + assert(count_ones_i8(0) == 0); + assert(count_ones_i8(1) == 1); + assert(count_ones_i8(-1) == 8); + assert(count_ones_i8(2) == 1); + assert(count_ones_i8(-2) == 7); + assert(count_ones_i8(127) == 7); + assert(count_ones_i8(-128) == 1); + assert(count_ones_i8(-127) == 2); + assert(count_ones_i8(64) == 1); + assert(count_ones_i8(-64) == 2); + assert(count_ones_i8(85) == 4); + assert(leading_zeros_i8(0) == 8); + assert(leading_zeros_i8(1) == 7); + assert(leading_zeros_i8(-1) == 0); + assert(leading_zeros_i8(2) == 6); + assert(leading_zeros_i8(-2) == 0); + assert(leading_zeros_i8(127) == 1); + assert(leading_zeros_i8(-128) == 0); + assert(leading_zeros_i8(-127) == 0); + assert(leading_zeros_i8(64) == 1); + assert(leading_zeros_i8(-64) == 0); + assert(leading_zeros_i8(85) == 1); + assert(trailing_zeros_i8(0) == 8); + assert(trailing_zeros_i8(1) == 0); + assert(trailing_zeros_i8(-1) == 0); + assert(trailing_zeros_i8(2) == 1); + assert(trailing_zeros_i8(-2) == 1); + assert(trailing_zeros_i8(127) == 0); + assert(trailing_zeros_i8(-128) == 7); + assert(trailing_zeros_i8(-127) == 0); + assert(trailing_zeros_i8(64) == 6); + assert(trailing_zeros_i8(-64) == 6); + assert(trailing_zeros_i8(85) == 0); + // i16 + assert(count_ones_i16(0) == 0); + assert(count_ones_i16(1) == 1); + assert(count_ones_i16(-1) == 16); + assert(count_ones_i16(2) == 1); + assert(count_ones_i16(-2) == 15); + assert(count_ones_i16(32767) == 15); + assert(count_ones_i16(-32768) == 1); + assert(count_ones_i16(-32767) == 2); + assert(count_ones_i16(256) == 1); + assert(count_ones_i16(-256) == 8); + assert(count_ones_i16(21845) == 8); + assert(leading_zeros_i16(0) == 16); + assert(leading_zeros_i16(1) == 15); + assert(leading_zeros_i16(-1) == 0); + assert(leading_zeros_i16(2) == 14); + assert(leading_zeros_i16(-2) == 0); + assert(leading_zeros_i16(32767) == 1); + assert(leading_zeros_i16(-32768) == 0); + assert(leading_zeros_i16(-32767) == 0); + assert(leading_zeros_i16(256) == 7); + assert(leading_zeros_i16(-256) == 0); + assert(leading_zeros_i16(21845) == 1); + assert(trailing_zeros_i16(0) == 16); + assert(trailing_zeros_i16(1) == 0); + assert(trailing_zeros_i16(-1) == 0); + assert(trailing_zeros_i16(2) == 1); + assert(trailing_zeros_i16(-2) == 1); + assert(trailing_zeros_i16(32767) == 0); + assert(trailing_zeros_i16(-32768) == 15); + assert(trailing_zeros_i16(-32767) == 0); + assert(trailing_zeros_i16(256) == 8); + assert(trailing_zeros_i16(-256) == 8); + assert(trailing_zeros_i16(21845) == 0); + // i32 + assert(count_ones_i32(0) == 0); + assert(count_ones_i32(1) == 1); + assert(count_ones_i32(-1) == 32); + assert(count_ones_i32(2) == 1); + assert(count_ones_i32(-2) == 31); + assert(count_ones_i32(2147483647) == 31); + assert(count_ones_i32(I32_MIN) == 1); + assert(count_ones_i32(-2147483647) == 2); + assert(count_ones_i32(65536) == 1); + assert(count_ones_i32(-65536) == 16); + assert(count_ones_i32(1431655765) == 16); + assert(count_ones_i32(-1431655766) == 16); + assert(count_ones_i32(48) == 2); + assert(leading_zeros_i32(0) == 32); + assert(leading_zeros_i32(1) == 31); + assert(leading_zeros_i32(-1) == 0); + assert(leading_zeros_i32(2) == 30); + assert(leading_zeros_i32(-2) == 0); + assert(leading_zeros_i32(2147483647) == 1); + assert(leading_zeros_i32(I32_MIN) == 0); + assert(leading_zeros_i32(-2147483647) == 0); + assert(leading_zeros_i32(65536) == 15); + assert(leading_zeros_i32(-65536) == 0); + assert(leading_zeros_i32(1431655765) == 1); + assert(leading_zeros_i32(-1431655766) == 0); + assert(leading_zeros_i32(48) == 26); + assert(trailing_zeros_i32(0) == 32); + assert(trailing_zeros_i32(1) == 0); + assert(trailing_zeros_i32(-1) == 0); + assert(trailing_zeros_i32(2) == 1); + assert(trailing_zeros_i32(-2) == 1); + assert(trailing_zeros_i32(2147483647) == 0); + assert(trailing_zeros_i32(I32_MIN) == 31); + assert(trailing_zeros_i32(-2147483647) == 0); + assert(trailing_zeros_i32(65536) == 16); + assert(trailing_zeros_i32(-65536) == 16); + assert(trailing_zeros_i32(1431655765) == 0); + assert(trailing_zeros_i32(-1431655766) == 1); + assert(trailing_zeros_i32(48) == 4); + // i64 + assert(count_ones_i64(0) == 0); + assert(count_ones_i64(1) == 1); + assert(count_ones_i64(-1) == 64); + assert(count_ones_i64(2) == 1); + assert(count_ones_i64(-2) == 63); + assert(count_ones_i64(9223372036854775807) == 63); + assert(count_ones_i64(I64_MIN) == 1); + assert(count_ones_i64(-9223372036854775807) == 2); + assert(count_ones_i64(4294967296) == 1); + assert(count_ones_i64(-4294967296) == 32); + assert(count_ones_i64(6148914691236517205) == 32); + assert(count_ones_i64(-6148914691236517206) == 32); + assert(count_ones_i64(48) == 2); + assert(leading_zeros_i64(0) == 64); + assert(leading_zeros_i64(1) == 63); + assert(leading_zeros_i64(-1) == 0); + assert(leading_zeros_i64(2) == 62); + assert(leading_zeros_i64(-2) == 0); + assert(leading_zeros_i64(9223372036854775807) == 1); + assert(leading_zeros_i64(I64_MIN) == 0); + assert(leading_zeros_i64(-9223372036854775807) == 0); + assert(leading_zeros_i64(4294967296) == 31); + assert(leading_zeros_i64(-4294967296) == 0); + assert(leading_zeros_i64(6148914691236517205) == 1); + assert(leading_zeros_i64(-6148914691236517206) == 0); + assert(leading_zeros_i64(48) == 58); + assert(trailing_zeros_i64(0) == 64); + assert(trailing_zeros_i64(1) == 0); + assert(trailing_zeros_i64(-1) == 0); + assert(trailing_zeros_i64(2) == 1); + assert(trailing_zeros_i64(-2) == 1); + assert(trailing_zeros_i64(9223372036854775807) == 0); + assert(trailing_zeros_i64(I64_MIN) == 63); + assert(trailing_zeros_i64(-9223372036854775807) == 0); + assert(trailing_zeros_i64(4294967296) == 32); + assert(trailing_zeros_i64(-4294967296) == 32); + assert(trailing_zeros_i64(6148914691236517205) == 0); + assert(trailing_zeros_i64(-6148914691236517206) == 1); + assert(trailing_zeros_i64(48) == 4); +} + +/// pow of u8: every expected value was printed by rustc 1.99 running `x.pow(e)` on the same inputs; the pairs +/// that overflow are not vectors (a debug build panics on them), the ones kept are those `checked_pow` answers, +/// up to the largest result the type holds. +test std_pow_of_u8_is_rusts { + assert(pow_u8(0, 0) == 1); + assert(pow_u8(0, 1) == 0); + assert(pow_u8(0, 2) == 0); + assert(pow_u8(0, 3) == 0); + assert(pow_u8(0, 4) == 0); + assert(pow_u8(0, 5) == 0); + assert(pow_u8(0, 7) == 0); + assert(pow_u8(0, 8) == 0); + assert(pow_u8(0, 15) == 0); + assert(pow_u8(0, 16) == 0); + assert(pow_u8(0, 31) == 0); + assert(pow_u8(0, 32) == 0); + assert(pow_u8(0, 63) == 0); + assert(pow_u8(0, 64) == 0); + assert(pow_u8(1, 0) == 1); + assert(pow_u8(1, 1) == 1); + assert(pow_u8(1, 2) == 1); + assert(pow_u8(1, 3) == 1); + assert(pow_u8(1, 4) == 1); + assert(pow_u8(1, 5) == 1); + assert(pow_u8(1, 7) == 1); + assert(pow_u8(1, 8) == 1); + assert(pow_u8(1, 15) == 1); + assert(pow_u8(1, 16) == 1); + assert(pow_u8(1, 31) == 1); + assert(pow_u8(1, 32) == 1); + assert(pow_u8(1, 63) == 1); + assert(pow_u8(1, 64) == 1); + assert(pow_u8(2, 0) == 1); + assert(pow_u8(2, 1) == 2); + assert(pow_u8(2, 2) == 4); + assert(pow_u8(2, 3) == 8); + assert(pow_u8(2, 4) == 16); + assert(pow_u8(2, 5) == 32); + assert(pow_u8(2, 7) == 128); + assert(pow_u8(3, 0) == 1); + assert(pow_u8(3, 1) == 3); + assert(pow_u8(3, 2) == 9); + assert(pow_u8(3, 3) == 27); + assert(pow_u8(3, 4) == 81); + assert(pow_u8(3, 5) == 243); + assert(pow_u8(5, 0) == 1); + assert(pow_u8(5, 1) == 5); + assert(pow_u8(5, 2) == 25); + assert(pow_u8(5, 3) == 125); + assert(pow_u8(15, 0) == 1); + assert(pow_u8(15, 1) == 15); + assert(pow_u8(15, 2) == 225); + assert(pow_u8(16, 0) == 1); + assert(pow_u8(16, 1) == 16); + assert(pow_u8(127, 0) == 1); + assert(pow_u8(127, 1) == 127); + assert(pow_u8(255, 0) == 1); + assert(pow_u8(255, 1) == 255); +} + +/// pow of u16: every expected value was printed by rustc 1.99 running `x.pow(e)` on the same inputs; the pairs +/// that overflow are not vectors (a debug build panics on them), the ones kept are those `checked_pow` answers, +/// up to the largest result the type holds. +test std_pow_of_u16_is_rusts { + assert(pow_u16(0, 0) == 1); + assert(pow_u16(0, 1) == 0); + assert(pow_u16(0, 2) == 0); + assert(pow_u16(0, 3) == 0); + assert(pow_u16(0, 4) == 0); + assert(pow_u16(0, 5) == 0); + assert(pow_u16(0, 7) == 0); + assert(pow_u16(0, 8) == 0); + assert(pow_u16(0, 15) == 0); + assert(pow_u16(0, 16) == 0); + assert(pow_u16(0, 31) == 0); + assert(pow_u16(0, 32) == 0); + assert(pow_u16(0, 63) == 0); + assert(pow_u16(0, 64) == 0); + assert(pow_u16(1, 0) == 1); + assert(pow_u16(1, 1) == 1); + assert(pow_u16(1, 2) == 1); + assert(pow_u16(1, 3) == 1); + assert(pow_u16(1, 4) == 1); + assert(pow_u16(1, 5) == 1); + assert(pow_u16(1, 7) == 1); + assert(pow_u16(1, 8) == 1); + assert(pow_u16(1, 15) == 1); + assert(pow_u16(1, 16) == 1); + assert(pow_u16(1, 31) == 1); + assert(pow_u16(1, 32) == 1); + assert(pow_u16(1, 63) == 1); + assert(pow_u16(1, 64) == 1); + assert(pow_u16(2, 0) == 1); + assert(pow_u16(2, 1) == 2); + assert(pow_u16(2, 2) == 4); + assert(pow_u16(2, 3) == 8); + assert(pow_u16(2, 4) == 16); + assert(pow_u16(2, 5) == 32); + assert(pow_u16(2, 7) == 128); + assert(pow_u16(2, 8) == 256); + assert(pow_u16(2, 15) == 32768); + assert(pow_u16(3, 0) == 1); + assert(pow_u16(3, 1) == 3); + assert(pow_u16(3, 2) == 9); + assert(pow_u16(3, 3) == 27); + assert(pow_u16(3, 4) == 81); + assert(pow_u16(3, 5) == 243); + assert(pow_u16(3, 7) == 2187); + assert(pow_u16(3, 8) == 6561); + assert(pow_u16(7, 0) == 1); + assert(pow_u16(7, 1) == 7); + assert(pow_u16(7, 2) == 49); + assert(pow_u16(7, 3) == 343); + assert(pow_u16(7, 4) == 2401); + assert(pow_u16(7, 5) == 16807); + assert(pow_u16(10, 0) == 1); + assert(pow_u16(10, 1) == 10); + assert(pow_u16(10, 2) == 100); + assert(pow_u16(10, 3) == 1000); + assert(pow_u16(10, 4) == 10000); + assert(pow_u16(255, 0) == 1); + assert(pow_u16(255, 1) == 255); + assert(pow_u16(255, 2) == 65025); + assert(pow_u16(256, 0) == 1); + assert(pow_u16(256, 1) == 256); + assert(pow_u16(65535, 0) == 1); + assert(pow_u16(65535, 1) == 65535); +} + +/// pow of u32: every expected value was printed by rustc 1.99 running `x.pow(e)` on the same inputs; the pairs +/// that overflow are not vectors (a debug build panics on them), the ones kept are those `checked_pow` answers, +/// up to the largest result the type holds. +test std_pow_of_u32_is_rusts { + assert(pow_u32(0, 0) == 1); + assert(pow_u32(0, 1) == 0); + assert(pow_u32(0, 2) == 0); + assert(pow_u32(0, 3) == 0); + assert(pow_u32(0, 4) == 0); + assert(pow_u32(0, 5) == 0); + assert(pow_u32(0, 7) == 0); + assert(pow_u32(0, 8) == 0); + assert(pow_u32(0, 15) == 0); + assert(pow_u32(0, 16) == 0); + assert(pow_u32(0, 31) == 0); + assert(pow_u32(0, 32) == 0); + assert(pow_u32(0, 63) == 0); + assert(pow_u32(0, 64) == 0); + assert(pow_u32(1, 0) == 1); + assert(pow_u32(1, 1) == 1); + assert(pow_u32(1, 2) == 1); + assert(pow_u32(1, 3) == 1); + assert(pow_u32(1, 4) == 1); + assert(pow_u32(1, 5) == 1); + assert(pow_u32(1, 7) == 1); + assert(pow_u32(1, 8) == 1); + assert(pow_u32(1, 15) == 1); + assert(pow_u32(1, 16) == 1); + assert(pow_u32(1, 31) == 1); + assert(pow_u32(1, 32) == 1); + assert(pow_u32(1, 63) == 1); + assert(pow_u32(1, 64) == 1); + assert(pow_u32(2, 0) == 1); + assert(pow_u32(2, 1) == 2); + assert(pow_u32(2, 2) == 4); + assert(pow_u32(2, 3) == 8); + assert(pow_u32(2, 4) == 16); + assert(pow_u32(2, 5) == 32); + assert(pow_u32(2, 7) == 128); + assert(pow_u32(2, 8) == 256); + assert(pow_u32(2, 15) == 32768); + assert(pow_u32(2, 16) == 65536); + assert(pow_u32(2, 31) == 2147483648); + assert(pow_u32(3, 0) == 1); + assert(pow_u32(3, 1) == 3); + assert(pow_u32(3, 2) == 9); + assert(pow_u32(3, 3) == 27); + assert(pow_u32(3, 4) == 81); + assert(pow_u32(3, 5) == 243); + assert(pow_u32(3, 7) == 2187); + assert(pow_u32(3, 8) == 6561); + assert(pow_u32(3, 15) == 14348907); + assert(pow_u32(3, 16) == 43046721); + assert(pow_u32(7, 0) == 1); + assert(pow_u32(7, 1) == 7); + assert(pow_u32(7, 2) == 49); + assert(pow_u32(7, 3) == 343); + assert(pow_u32(7, 4) == 2401); + assert(pow_u32(7, 5) == 16807); + assert(pow_u32(7, 7) == 823543); + assert(pow_u32(7, 8) == 5764801); + assert(pow_u32(10, 0) == 1); + assert(pow_u32(10, 1) == 10); + assert(pow_u32(10, 2) == 100); + assert(pow_u32(10, 3) == 1000); + assert(pow_u32(10, 4) == 10000); + assert(pow_u32(10, 5) == 100000); + assert(pow_u32(10, 7) == 10000000); + assert(pow_u32(10, 8) == 100000000); + assert(pow_u32(16, 0) == 1); + assert(pow_u32(16, 1) == 16); + assert(pow_u32(16, 2) == 256); + assert(pow_u32(16, 3) == 4096); + assert(pow_u32(16, 4) == 65536); + assert(pow_u32(16, 5) == 1048576); + assert(pow_u32(16, 7) == 268435456); + assert(pow_u32(65535, 0) == 1); + assert(pow_u32(65535, 1) == 65535); + assert(pow_u32(65535, 2) == 4294836225); + assert(pow_u32(65536, 0) == 1); + assert(pow_u32(65536, 1) == 65536); + assert(pow_u32(4294967295, 0) == 1); + assert(pow_u32(4294967295, 1) == 4294967295); +} + +/// pow of u64: every expected value was printed by rustc 1.99 running `x.pow(e)` on the same inputs; the pairs +/// that overflow are not vectors (a debug build panics on them), the ones kept are those `checked_pow` answers, +/// up to the largest result the type holds. +test std_pow_of_u64_is_rusts { + assert(pow_u64(0, 0) == 1); + assert(pow_u64(0, 1) == 0); + assert(pow_u64(0, 2) == 0); + assert(pow_u64(0, 3) == 0); + assert(pow_u64(0, 4) == 0); + assert(pow_u64(0, 5) == 0); + assert(pow_u64(0, 7) == 0); + assert(pow_u64(0, 8) == 0); + assert(pow_u64(0, 15) == 0); + assert(pow_u64(0, 16) == 0); + assert(pow_u64(0, 31) == 0); + assert(pow_u64(0, 32) == 0); + assert(pow_u64(0, 63) == 0); + assert(pow_u64(0, 64) == 0); + assert(pow_u64(1, 0) == 1); + assert(pow_u64(1, 1) == 1); + assert(pow_u64(1, 2) == 1); + assert(pow_u64(1, 3) == 1); + assert(pow_u64(1, 4) == 1); + assert(pow_u64(1, 5) == 1); + assert(pow_u64(1, 7) == 1); + assert(pow_u64(1, 8) == 1); + assert(pow_u64(1, 15) == 1); + assert(pow_u64(1, 16) == 1); + assert(pow_u64(1, 31) == 1); + assert(pow_u64(1, 32) == 1); + assert(pow_u64(1, 63) == 1); + assert(pow_u64(1, 64) == 1); + assert(pow_u64(2, 0) == 1); + assert(pow_u64(2, 1) == 2); + assert(pow_u64(2, 2) == 4); + assert(pow_u64(2, 3) == 8); + assert(pow_u64(2, 4) == 16); + assert(pow_u64(2, 5) == 32); + assert(pow_u64(2, 7) == 128); + assert(pow_u64(2, 8) == 256); + assert(pow_u64(2, 15) == 32768); + assert(pow_u64(2, 16) == 65536); + assert(pow_u64(2, 31) == 2147483648); + assert(pow_u64(2, 32) == 4294967296); + assert(pow_u64(2, 63) == 9223372036854775808); + assert(pow_u64(3, 0) == 1); + assert(pow_u64(3, 1) == 3); + assert(pow_u64(3, 2) == 9); + assert(pow_u64(3, 3) == 27); + assert(pow_u64(3, 4) == 81); + assert(pow_u64(3, 5) == 243); + assert(pow_u64(3, 7) == 2187); + assert(pow_u64(3, 8) == 6561); + assert(pow_u64(3, 15) == 14348907); + assert(pow_u64(3, 16) == 43046721); + assert(pow_u64(3, 31) == 617673396283947); + assert(pow_u64(3, 32) == 1853020188851841); + assert(pow_u64(10, 0) == 1); + assert(pow_u64(10, 1) == 10); + assert(pow_u64(10, 2) == 100); + assert(pow_u64(10, 3) == 1000); + assert(pow_u64(10, 4) == 10000); + assert(pow_u64(10, 5) == 100000); + assert(pow_u64(10, 7) == 10000000); + assert(pow_u64(10, 8) == 100000000); + assert(pow_u64(10, 15) == 1000000000000000); + assert(pow_u64(10, 16) == 10000000000000000); + assert(pow_u64(16, 0) == 1); + assert(pow_u64(16, 1) == 16); + assert(pow_u64(16, 2) == 256); + assert(pow_u64(16, 3) == 4096); + assert(pow_u64(16, 4) == 65536); + assert(pow_u64(16, 5) == 1048576); + assert(pow_u64(16, 7) == 268435456); + assert(pow_u64(16, 8) == 4294967296); + assert(pow_u64(16, 15) == 1152921504606846976); + assert(pow_u64(4294967295, 0) == 1); + assert(pow_u64(4294967295, 1) == 4294967295); + assert(pow_u64(4294967295, 2) == 18446744065119617025); + assert(pow_u64(4294967296, 0) == 1); + assert(pow_u64(4294967296, 1) == 4294967296); + assert(pow_u64(18446744073709551615, 0) == 1); + assert(pow_u64(18446744073709551615, 1) == 18446744073709551615); +} + +/// pow of usize: every expected value was printed by rustc 1.99 running `x.pow(e)` on the same inputs; the pairs +/// that overflow are not vectors (a debug build panics on them), the ones kept are those `checked_pow` answers, +/// up to the largest result the type holds. +test std_pow_of_usize_is_rusts { + assert(pow_usize(0, 0) == 1); + assert(pow_usize(0, 1) == 0); + assert(pow_usize(0, 2) == 0); + assert(pow_usize(0, 3) == 0); + assert(pow_usize(0, 4) == 0); + assert(pow_usize(0, 5) == 0); + assert(pow_usize(0, 7) == 0); + assert(pow_usize(0, 8) == 0); + assert(pow_usize(0, 15) == 0); + assert(pow_usize(0, 16) == 0); + assert(pow_usize(0, 31) == 0); + assert(pow_usize(0, 32) == 0); + assert(pow_usize(0, 63) == 0); + assert(pow_usize(0, 64) == 0); + assert(pow_usize(1, 0) == 1); + assert(pow_usize(1, 1) == 1); + assert(pow_usize(1, 2) == 1); + assert(pow_usize(1, 3) == 1); + assert(pow_usize(1, 4) == 1); + assert(pow_usize(1, 5) == 1); + assert(pow_usize(1, 7) == 1); + assert(pow_usize(1, 8) == 1); + assert(pow_usize(1, 15) == 1); + assert(pow_usize(1, 16) == 1); + assert(pow_usize(1, 31) == 1); + assert(pow_usize(1, 32) == 1); + assert(pow_usize(1, 63) == 1); + assert(pow_usize(1, 64) == 1); + assert(pow_usize(2, 0) == 1); + assert(pow_usize(2, 1) == 2); + assert(pow_usize(2, 2) == 4); + assert(pow_usize(2, 3) == 8); + assert(pow_usize(2, 4) == 16); + assert(pow_usize(2, 5) == 32); + assert(pow_usize(2, 7) == 128); + assert(pow_usize(2, 8) == 256); + assert(pow_usize(2, 15) == 32768); + assert(pow_usize(2, 16) == 65536); + assert(pow_usize(2, 31) == 2147483648); + assert(pow_usize(2, 32) == 4294967296); + assert(pow_usize(2, 63) == 9223372036854775808); + assert(pow_usize(3, 0) == 1); + assert(pow_usize(3, 1) == 3); + assert(pow_usize(3, 2) == 9); + assert(pow_usize(3, 3) == 27); + assert(pow_usize(3, 4) == 81); + assert(pow_usize(3, 5) == 243); + assert(pow_usize(3, 7) == 2187); + assert(pow_usize(3, 8) == 6561); + assert(pow_usize(3, 15) == 14348907); + assert(pow_usize(3, 16) == 43046721); + assert(pow_usize(3, 31) == 617673396283947); + assert(pow_usize(3, 32) == 1853020188851841); + assert(pow_usize(10, 0) == 1); + assert(pow_usize(10, 1) == 10); + assert(pow_usize(10, 2) == 100); + assert(pow_usize(10, 3) == 1000); + assert(pow_usize(10, 4) == 10000); + assert(pow_usize(10, 5) == 100000); + assert(pow_usize(10, 7) == 10000000); + assert(pow_usize(10, 8) == 100000000); + assert(pow_usize(10, 15) == 1000000000000000); + assert(pow_usize(10, 16) == 10000000000000000); + assert(pow_usize(16, 0) == 1); + assert(pow_usize(16, 1) == 16); + assert(pow_usize(16, 2) == 256); + assert(pow_usize(16, 3) == 4096); + assert(pow_usize(16, 4) == 65536); + assert(pow_usize(16, 5) == 1048576); + assert(pow_usize(16, 7) == 268435456); + assert(pow_usize(16, 8) == 4294967296); + assert(pow_usize(16, 15) == 1152921504606846976); + assert(pow_usize(4294967295, 0) == 1); + assert(pow_usize(4294967295, 1) == 4294967295); + assert(pow_usize(4294967295, 2) == 18446744065119617025); + assert(pow_usize(4294967296, 0) == 1); + assert(pow_usize(4294967296, 1) == 4294967296); + assert(pow_usize(18446744073709551615, 0) == 1); + assert(pow_usize(18446744073709551615, 1) == 18446744073709551615); +} + +/// pow of i8: every expected value was printed by rustc 1.99 running `x.pow(e)` on the same inputs; the pairs +/// that overflow are not vectors (a debug build panics on them), the ones kept are those `checked_pow` answers, +/// up to the largest result the type holds. +test std_pow_of_i8_is_rusts { + assert(pow_i8(-128, 0) == 1); + assert(pow_i8(-128, 1) == -128); + assert(pow_i8(-3, 0) == 1); + assert(pow_i8(-3, 1) == -3); + assert(pow_i8(-3, 2) == 9); + assert(pow_i8(-3, 3) == -27); + assert(pow_i8(-3, 4) == 81); + assert(pow_i8(-2, 0) == 1); + assert(pow_i8(-2, 1) == -2); + assert(pow_i8(-2, 2) == 4); + assert(pow_i8(-2, 3) == -8); + assert(pow_i8(-2, 4) == 16); + assert(pow_i8(-2, 5) == -32); + assert(pow_i8(-2, 7) == -128); + assert(pow_i8(-1, 0) == 1); + assert(pow_i8(-1, 1) == -1); + assert(pow_i8(-1, 2) == 1); + assert(pow_i8(-1, 3) == -1); + assert(pow_i8(-1, 4) == 1); + assert(pow_i8(-1, 5) == -1); + assert(pow_i8(-1, 7) == -1); + assert(pow_i8(-1, 8) == 1); + assert(pow_i8(-1, 15) == -1); + assert(pow_i8(-1, 16) == 1); + assert(pow_i8(-1, 31) == -1); + assert(pow_i8(-1, 32) == 1); + assert(pow_i8(-1, 63) == -1); + assert(pow_i8(-1, 64) == 1); + assert(pow_i8(0, 0) == 1); + assert(pow_i8(0, 1) == 0); + assert(pow_i8(0, 2) == 0); + assert(pow_i8(0, 3) == 0); + assert(pow_i8(0, 4) == 0); + assert(pow_i8(0, 5) == 0); + assert(pow_i8(0, 7) == 0); + assert(pow_i8(0, 8) == 0); + assert(pow_i8(0, 15) == 0); + assert(pow_i8(0, 16) == 0); + assert(pow_i8(0, 31) == 0); + assert(pow_i8(0, 32) == 0); + assert(pow_i8(0, 63) == 0); + assert(pow_i8(0, 64) == 0); + assert(pow_i8(1, 0) == 1); + assert(pow_i8(1, 1) == 1); + assert(pow_i8(1, 2) == 1); + assert(pow_i8(1, 3) == 1); + assert(pow_i8(1, 4) == 1); + assert(pow_i8(1, 5) == 1); + assert(pow_i8(1, 7) == 1); + assert(pow_i8(1, 8) == 1); + assert(pow_i8(1, 15) == 1); + assert(pow_i8(1, 16) == 1); + assert(pow_i8(1, 31) == 1); + assert(pow_i8(1, 32) == 1); + assert(pow_i8(1, 63) == 1); + assert(pow_i8(1, 64) == 1); + assert(pow_i8(2, 0) == 1); + assert(pow_i8(2, 1) == 2); + assert(pow_i8(2, 2) == 4); + assert(pow_i8(2, 3) == 8); + assert(pow_i8(2, 4) == 16); + assert(pow_i8(2, 5) == 32); + assert(pow_i8(3, 0) == 1); + assert(pow_i8(3, 1) == 3); + assert(pow_i8(3, 2) == 9); + assert(pow_i8(3, 3) == 27); + assert(pow_i8(3, 4) == 81); + assert(pow_i8(5, 0) == 1); + assert(pow_i8(5, 1) == 5); + assert(pow_i8(5, 2) == 25); + assert(pow_i8(5, 3) == 125); + assert(pow_i8(11, 0) == 1); + assert(pow_i8(11, 1) == 11); + assert(pow_i8(11, 2) == 121); + assert(pow_i8(127, 0) == 1); + assert(pow_i8(127, 1) == 127); +} + +/// pow of i16: every expected value was printed by rustc 1.99 running `x.pow(e)` on the same inputs; the pairs +/// that overflow are not vectors (a debug build panics on them), the ones kept are those `checked_pow` answers, +/// up to the largest result the type holds. +test std_pow_of_i16_is_rusts { + assert(pow_i16(-32768, 0) == 1); + assert(pow_i16(-32768, 1) == -32768); + assert(pow_i16(-3, 0) == 1); + assert(pow_i16(-3, 1) == -3); + assert(pow_i16(-3, 2) == 9); + assert(pow_i16(-3, 3) == -27); + assert(pow_i16(-3, 4) == 81); + assert(pow_i16(-3, 5) == -243); + assert(pow_i16(-3, 7) == -2187); + assert(pow_i16(-3, 8) == 6561); + assert(pow_i16(-2, 0) == 1); + assert(pow_i16(-2, 1) == -2); + assert(pow_i16(-2, 2) == 4); + assert(pow_i16(-2, 3) == -8); + assert(pow_i16(-2, 4) == 16); + assert(pow_i16(-2, 5) == -32); + assert(pow_i16(-2, 7) == -128); + assert(pow_i16(-2, 8) == 256); + assert(pow_i16(-2, 15) == -32768); + assert(pow_i16(-1, 0) == 1); + assert(pow_i16(-1, 1) == -1); + assert(pow_i16(-1, 2) == 1); + assert(pow_i16(-1, 3) == -1); + assert(pow_i16(-1, 4) == 1); + assert(pow_i16(-1, 5) == -1); + assert(pow_i16(-1, 7) == -1); + assert(pow_i16(-1, 8) == 1); + assert(pow_i16(-1, 15) == -1); + assert(pow_i16(-1, 16) == 1); + assert(pow_i16(-1, 31) == -1); + assert(pow_i16(-1, 32) == 1); + assert(pow_i16(-1, 63) == -1); + assert(pow_i16(-1, 64) == 1); + assert(pow_i16(0, 0) == 1); + assert(pow_i16(0, 1) == 0); + assert(pow_i16(0, 2) == 0); + assert(pow_i16(0, 3) == 0); + assert(pow_i16(0, 4) == 0); + assert(pow_i16(0, 5) == 0); + assert(pow_i16(0, 7) == 0); + assert(pow_i16(0, 8) == 0); + assert(pow_i16(0, 15) == 0); + assert(pow_i16(0, 16) == 0); + assert(pow_i16(0, 31) == 0); + assert(pow_i16(0, 32) == 0); + assert(pow_i16(0, 63) == 0); + assert(pow_i16(0, 64) == 0); + assert(pow_i16(1, 0) == 1); + assert(pow_i16(1, 1) == 1); + assert(pow_i16(1, 2) == 1); + assert(pow_i16(1, 3) == 1); + assert(pow_i16(1, 4) == 1); + assert(pow_i16(1, 5) == 1); + assert(pow_i16(1, 7) == 1); + assert(pow_i16(1, 8) == 1); + assert(pow_i16(1, 15) == 1); + assert(pow_i16(1, 16) == 1); + assert(pow_i16(1, 31) == 1); + assert(pow_i16(1, 32) == 1); + assert(pow_i16(1, 63) == 1); + assert(pow_i16(1, 64) == 1); + assert(pow_i16(2, 0) == 1); + assert(pow_i16(2, 1) == 2); + assert(pow_i16(2, 2) == 4); + assert(pow_i16(2, 3) == 8); + assert(pow_i16(2, 4) == 16); + assert(pow_i16(2, 5) == 32); + assert(pow_i16(2, 7) == 128); + assert(pow_i16(2, 8) == 256); + assert(pow_i16(3, 0) == 1); + assert(pow_i16(3, 1) == 3); + assert(pow_i16(3, 2) == 9); + assert(pow_i16(3, 3) == 27); + assert(pow_i16(3, 4) == 81); + assert(pow_i16(3, 5) == 243); + assert(pow_i16(3, 7) == 2187); + assert(pow_i16(3, 8) == 6561); + assert(pow_i16(10, 0) == 1); + assert(pow_i16(10, 1) == 10); + assert(pow_i16(10, 2) == 100); + assert(pow_i16(10, 3) == 1000); + assert(pow_i16(10, 4) == 10000); + assert(pow_i16(181, 0) == 1); + assert(pow_i16(181, 1) == 181); + assert(pow_i16(181, 2) == 32761); + assert(pow_i16(32767, 0) == 1); + assert(pow_i16(32767, 1) == 32767); +} + +/// pow of i32: every expected value was printed by rustc 1.99 running `x.pow(e)` on the same inputs; the pairs +/// that overflow are not vectors (a debug build panics on them), the ones kept are those `checked_pow` answers, +/// up to the largest result the type holds. +test std_pow_of_i32_is_rusts { + assert(pow_i32(I32_MIN, 0) == 1); + assert(pow_i32(I32_MIN, 1) == I32_MIN); + assert(pow_i32(-46341, 0) == 1); + assert(pow_i32(-46341, 1) == -46341); + assert(pow_i32(-3, 0) == 1); + assert(pow_i32(-3, 1) == -3); + assert(pow_i32(-3, 2) == 9); + assert(pow_i32(-3, 3) == -27); + assert(pow_i32(-3, 4) == 81); + assert(pow_i32(-3, 5) == -243); + assert(pow_i32(-3, 7) == -2187); + assert(pow_i32(-3, 8) == 6561); + assert(pow_i32(-3, 15) == -14348907); + assert(pow_i32(-3, 16) == 43046721); + assert(pow_i32(-2, 0) == 1); + assert(pow_i32(-2, 1) == -2); + assert(pow_i32(-2, 2) == 4); + assert(pow_i32(-2, 3) == -8); + assert(pow_i32(-2, 4) == 16); + assert(pow_i32(-2, 5) == -32); + assert(pow_i32(-2, 7) == -128); + assert(pow_i32(-2, 8) == 256); + assert(pow_i32(-2, 15) == -32768); + assert(pow_i32(-2, 16) == 65536); + assert(pow_i32(-2, 31) == I32_MIN); + assert(pow_i32(-1, 0) == 1); + assert(pow_i32(-1, 1) == -1); + assert(pow_i32(-1, 2) == 1); + assert(pow_i32(-1, 3) == -1); + assert(pow_i32(-1, 4) == 1); + assert(pow_i32(-1, 5) == -1); + assert(pow_i32(-1, 7) == -1); + assert(pow_i32(-1, 8) == 1); + assert(pow_i32(-1, 15) == -1); + assert(pow_i32(-1, 16) == 1); + assert(pow_i32(-1, 31) == -1); + assert(pow_i32(-1, 32) == 1); + assert(pow_i32(-1, 63) == -1); + assert(pow_i32(-1, 64) == 1); + assert(pow_i32(0, 0) == 1); + assert(pow_i32(0, 1) == 0); + assert(pow_i32(0, 2) == 0); + assert(pow_i32(0, 3) == 0); + assert(pow_i32(0, 4) == 0); + assert(pow_i32(0, 5) == 0); + assert(pow_i32(0, 7) == 0); + assert(pow_i32(0, 8) == 0); + assert(pow_i32(0, 15) == 0); + assert(pow_i32(0, 16) == 0); + assert(pow_i32(0, 31) == 0); + assert(pow_i32(0, 32) == 0); + assert(pow_i32(0, 63) == 0); + assert(pow_i32(0, 64) == 0); + assert(pow_i32(1, 0) == 1); + assert(pow_i32(1, 1) == 1); + assert(pow_i32(1, 2) == 1); + assert(pow_i32(1, 3) == 1); + assert(pow_i32(1, 4) == 1); + assert(pow_i32(1, 5) == 1); + assert(pow_i32(1, 7) == 1); + assert(pow_i32(1, 8) == 1); + assert(pow_i32(1, 15) == 1); + assert(pow_i32(1, 16) == 1); + assert(pow_i32(1, 31) == 1); + assert(pow_i32(1, 32) == 1); + assert(pow_i32(1, 63) == 1); + assert(pow_i32(1, 64) == 1); + assert(pow_i32(2, 0) == 1); + assert(pow_i32(2, 1) == 2); + assert(pow_i32(2, 2) == 4); + assert(pow_i32(2, 3) == 8); + assert(pow_i32(2, 4) == 16); + assert(pow_i32(2, 5) == 32); + assert(pow_i32(2, 7) == 128); + assert(pow_i32(2, 8) == 256); + assert(pow_i32(2, 15) == 32768); + assert(pow_i32(2, 16) == 65536); + assert(pow_i32(3, 0) == 1); + assert(pow_i32(3, 1) == 3); + assert(pow_i32(3, 2) == 9); + assert(pow_i32(3, 3) == 27); + assert(pow_i32(3, 4) == 81); + assert(pow_i32(3, 5) == 243); + assert(pow_i32(3, 7) == 2187); + assert(pow_i32(3, 8) == 6561); + assert(pow_i32(3, 15) == 14348907); + assert(pow_i32(3, 16) == 43046721); + assert(pow_i32(10, 0) == 1); + assert(pow_i32(10, 1) == 10); + assert(pow_i32(10, 2) == 100); + assert(pow_i32(10, 3) == 1000); + assert(pow_i32(10, 4) == 10000); + assert(pow_i32(10, 5) == 100000); + assert(pow_i32(10, 7) == 10000000); + assert(pow_i32(10, 8) == 100000000); + assert(pow_i32(46340, 0) == 1); + assert(pow_i32(46340, 1) == 46340); + assert(pow_i32(46340, 2) == 2147395600); + assert(pow_i32(2147483647, 0) == 1); + assert(pow_i32(2147483647, 1) == 2147483647); +} + +/// pow of i64: every expected value was printed by rustc 1.99 running `x.pow(e)` on the same inputs; the pairs +/// that overflow are not vectors (a debug build panics on them), the ones kept are those `checked_pow` answers, +/// up to the largest result the type holds. +test std_pow_of_i64_is_rusts { + assert(pow_i64(I64_MIN, 0) == 1); + assert(pow_i64(I64_MIN, 1) == I64_MIN); + assert(pow_i64(-3, 0) == 1); + assert(pow_i64(-3, 1) == -3); + assert(pow_i64(-3, 2) == 9); + assert(pow_i64(-3, 3) == -27); + assert(pow_i64(-3, 4) == 81); + assert(pow_i64(-3, 5) == -243); + assert(pow_i64(-3, 7) == -2187); + assert(pow_i64(-3, 8) == 6561); + assert(pow_i64(-3, 15) == -14348907); + assert(pow_i64(-3, 16) == 43046721); + assert(pow_i64(-3, 31) == -617673396283947); + assert(pow_i64(-3, 32) == 1853020188851841); + assert(pow_i64(-2, 0) == 1); + assert(pow_i64(-2, 1) == -2); + assert(pow_i64(-2, 2) == 4); + assert(pow_i64(-2, 3) == -8); + assert(pow_i64(-2, 4) == 16); + assert(pow_i64(-2, 5) == -32); + assert(pow_i64(-2, 7) == -128); + assert(pow_i64(-2, 8) == 256); + assert(pow_i64(-2, 15) == -32768); + assert(pow_i64(-2, 16) == 65536); + assert(pow_i64(-2, 31) == -2147483648); + assert(pow_i64(-2, 32) == 4294967296); + assert(pow_i64(-2, 63) == I64_MIN); + assert(pow_i64(-1, 0) == 1); + assert(pow_i64(-1, 1) == -1); + assert(pow_i64(-1, 2) == 1); + assert(pow_i64(-1, 3) == -1); + assert(pow_i64(-1, 4) == 1); + assert(pow_i64(-1, 5) == -1); + assert(pow_i64(-1, 7) == -1); + assert(pow_i64(-1, 8) == 1); + assert(pow_i64(-1, 15) == -1); + assert(pow_i64(-1, 16) == 1); + assert(pow_i64(-1, 31) == -1); + assert(pow_i64(-1, 32) == 1); + assert(pow_i64(-1, 63) == -1); + assert(pow_i64(-1, 64) == 1); + assert(pow_i64(0, 0) == 1); + assert(pow_i64(0, 1) == 0); + assert(pow_i64(0, 2) == 0); + assert(pow_i64(0, 3) == 0); + assert(pow_i64(0, 4) == 0); + assert(pow_i64(0, 5) == 0); + assert(pow_i64(0, 7) == 0); + assert(pow_i64(0, 8) == 0); + assert(pow_i64(0, 15) == 0); + assert(pow_i64(0, 16) == 0); + assert(pow_i64(0, 31) == 0); + assert(pow_i64(0, 32) == 0); + assert(pow_i64(0, 63) == 0); + assert(pow_i64(0, 64) == 0); + assert(pow_i64(1, 0) == 1); + assert(pow_i64(1, 1) == 1); + assert(pow_i64(1, 2) == 1); + assert(pow_i64(1, 3) == 1); + assert(pow_i64(1, 4) == 1); + assert(pow_i64(1, 5) == 1); + assert(pow_i64(1, 7) == 1); + assert(pow_i64(1, 8) == 1); + assert(pow_i64(1, 15) == 1); + assert(pow_i64(1, 16) == 1); + assert(pow_i64(1, 31) == 1); + assert(pow_i64(1, 32) == 1); + assert(pow_i64(1, 63) == 1); + assert(pow_i64(1, 64) == 1); + assert(pow_i64(2, 0) == 1); + assert(pow_i64(2, 1) == 2); + assert(pow_i64(2, 2) == 4); + assert(pow_i64(2, 3) == 8); + assert(pow_i64(2, 4) == 16); + assert(pow_i64(2, 5) == 32); + assert(pow_i64(2, 7) == 128); + assert(pow_i64(2, 8) == 256); + assert(pow_i64(2, 15) == 32768); + assert(pow_i64(2, 16) == 65536); + assert(pow_i64(2, 31) == 2147483648); + assert(pow_i64(2, 32) == 4294967296); + assert(pow_i64(3, 0) == 1); + assert(pow_i64(3, 1) == 3); + assert(pow_i64(3, 2) == 9); + assert(pow_i64(3, 3) == 27); + assert(pow_i64(3, 4) == 81); + assert(pow_i64(3, 5) == 243); + assert(pow_i64(3, 7) == 2187); + assert(pow_i64(3, 8) == 6561); + assert(pow_i64(3, 15) == 14348907); + assert(pow_i64(3, 16) == 43046721); + assert(pow_i64(3, 31) == 617673396283947); + assert(pow_i64(3, 32) == 1853020188851841); + assert(pow_i64(10, 0) == 1); + assert(pow_i64(10, 1) == 10); + assert(pow_i64(10, 2) == 100); + assert(pow_i64(10, 3) == 1000); + assert(pow_i64(10, 4) == 10000); + assert(pow_i64(10, 5) == 100000); + assert(pow_i64(10, 7) == 10000000); + assert(pow_i64(10, 8) == 100000000); + assert(pow_i64(10, 15) == 1000000000000000); + assert(pow_i64(10, 16) == 10000000000000000); + assert(pow_i64(3037000499, 0) == 1); + assert(pow_i64(3037000499, 1) == 3037000499); + assert(pow_i64(3037000499, 2) == 9223372030926249001); + assert(pow_i64(9223372036854775807, 0) == 1); + assert(pow_i64(9223372036854775807, 1) == 9223372036854775807); +} + +/// saturating_add / sub / mul of u8: every expected value was printed by rustc 1.99 running the method on the same +/// inputs; the grid is the edge values taken pairwise, so the clamp-up, clamp-down and exact paths are all reached. +test std_saturating_arithmetic_of_u8_is_rusts { + assert(saturating_add_u8(0, 0) == 0); + assert(saturating_add_u8(0, 1) == 1); + assert(saturating_add_u8(0, 7) == 7); + assert(saturating_add_u8(0, 128) == 128); + assert(saturating_add_u8(0, 254) == 254); + assert(saturating_add_u8(0, 255) == 255); + assert(saturating_add_u8(1, 0) == 1); + assert(saturating_add_u8(1, 1) == 2); + assert(saturating_add_u8(1, 7) == 8); + assert(saturating_add_u8(1, 128) == 129); + assert(saturating_add_u8(1, 254) == 255); + assert(saturating_add_u8(1, 255) == 255); + assert(saturating_add_u8(7, 0) == 7); + assert(saturating_add_u8(7, 1) == 8); + assert(saturating_add_u8(7, 7) == 14); + assert(saturating_add_u8(7, 128) == 135); + assert(saturating_add_u8(7, 254) == 255); + assert(saturating_add_u8(7, 255) == 255); + assert(saturating_add_u8(128, 0) == 128); + assert(saturating_add_u8(128, 1) == 129); + assert(saturating_add_u8(128, 7) == 135); + assert(saturating_add_u8(128, 128) == 255); + assert(saturating_add_u8(128, 254) == 255); + assert(saturating_add_u8(128, 255) == 255); + assert(saturating_add_u8(254, 0) == 254); + assert(saturating_add_u8(254, 1) == 255); + assert(saturating_add_u8(254, 7) == 255); + assert(saturating_add_u8(254, 128) == 255); + assert(saturating_add_u8(254, 254) == 255); + assert(saturating_add_u8(254, 255) == 255); + assert(saturating_add_u8(255, 0) == 255); + assert(saturating_add_u8(255, 1) == 255); + assert(saturating_add_u8(255, 7) == 255); + assert(saturating_add_u8(255, 128) == 255); + assert(saturating_add_u8(255, 254) == 255); + assert(saturating_add_u8(255, 255) == 255); + assert(saturating_sub_u8(0, 0) == 0); + assert(saturating_sub_u8(0, 1) == 0); + assert(saturating_sub_u8(0, 7) == 0); + assert(saturating_sub_u8(0, 128) == 0); + assert(saturating_sub_u8(0, 254) == 0); + assert(saturating_sub_u8(0, 255) == 0); + assert(saturating_sub_u8(1, 0) == 1); + assert(saturating_sub_u8(1, 1) == 0); + assert(saturating_sub_u8(1, 7) == 0); + assert(saturating_sub_u8(1, 128) == 0); + assert(saturating_sub_u8(1, 254) == 0); + assert(saturating_sub_u8(1, 255) == 0); + assert(saturating_sub_u8(7, 0) == 7); + assert(saturating_sub_u8(7, 1) == 6); + assert(saturating_sub_u8(7, 7) == 0); + assert(saturating_sub_u8(7, 128) == 0); + assert(saturating_sub_u8(7, 254) == 0); + assert(saturating_sub_u8(7, 255) == 0); + assert(saturating_sub_u8(128, 0) == 128); + assert(saturating_sub_u8(128, 1) == 127); + assert(saturating_sub_u8(128, 7) == 121); + assert(saturating_sub_u8(128, 128) == 0); + assert(saturating_sub_u8(128, 254) == 0); + assert(saturating_sub_u8(128, 255) == 0); + assert(saturating_sub_u8(254, 0) == 254); + assert(saturating_sub_u8(254, 1) == 253); + assert(saturating_sub_u8(254, 7) == 247); + assert(saturating_sub_u8(254, 128) == 126); + assert(saturating_sub_u8(254, 254) == 0); + assert(saturating_sub_u8(254, 255) == 0); + assert(saturating_sub_u8(255, 0) == 255); + assert(saturating_sub_u8(255, 1) == 254); + assert(saturating_sub_u8(255, 7) == 248); + assert(saturating_sub_u8(255, 128) == 127); + assert(saturating_sub_u8(255, 254) == 1); + assert(saturating_sub_u8(255, 255) == 0); + assert(saturating_mul_u8(0, 0) == 0); + assert(saturating_mul_u8(0, 1) == 0); + assert(saturating_mul_u8(0, 7) == 0); + assert(saturating_mul_u8(0, 128) == 0); + assert(saturating_mul_u8(0, 254) == 0); + assert(saturating_mul_u8(0, 255) == 0); + assert(saturating_mul_u8(1, 0) == 0); + assert(saturating_mul_u8(1, 1) == 1); + assert(saturating_mul_u8(1, 7) == 7); + assert(saturating_mul_u8(1, 128) == 128); + assert(saturating_mul_u8(1, 254) == 254); + assert(saturating_mul_u8(1, 255) == 255); + assert(saturating_mul_u8(7, 0) == 0); + assert(saturating_mul_u8(7, 1) == 7); + assert(saturating_mul_u8(7, 7) == 49); + assert(saturating_mul_u8(7, 128) == 255); + assert(saturating_mul_u8(7, 254) == 255); + assert(saturating_mul_u8(7, 255) == 255); + assert(saturating_mul_u8(128, 0) == 0); + assert(saturating_mul_u8(128, 1) == 128); + assert(saturating_mul_u8(128, 7) == 255); + assert(saturating_mul_u8(128, 128) == 255); + assert(saturating_mul_u8(128, 254) == 255); + assert(saturating_mul_u8(128, 255) == 255); + assert(saturating_mul_u8(254, 0) == 0); + assert(saturating_mul_u8(254, 1) == 254); + assert(saturating_mul_u8(254, 7) == 255); + assert(saturating_mul_u8(254, 128) == 255); + assert(saturating_mul_u8(254, 254) == 255); + assert(saturating_mul_u8(254, 255) == 255); + assert(saturating_mul_u8(255, 0) == 0); + assert(saturating_mul_u8(255, 1) == 255); + assert(saturating_mul_u8(255, 7) == 255); + assert(saturating_mul_u8(255, 128) == 255); + assert(saturating_mul_u8(255, 254) == 255); + assert(saturating_mul_u8(255, 255) == 255); +} + +/// saturating_add / sub / mul of u16: every expected value was printed by rustc 1.99 running the method on the same +/// inputs; the grid is the edge values taken pairwise, so the clamp-up, clamp-down and exact paths are all reached. +test std_saturating_arithmetic_of_u16_is_rusts { + assert(saturating_add_u16(0, 0) == 0); + assert(saturating_add_u16(0, 1) == 1); + assert(saturating_add_u16(0, 7) == 7); + assert(saturating_add_u16(0, 32768) == 32768); + assert(saturating_add_u16(0, 65534) == 65534); + assert(saturating_add_u16(0, 65535) == 65535); + assert(saturating_add_u16(1, 0) == 1); + assert(saturating_add_u16(1, 1) == 2); + assert(saturating_add_u16(1, 7) == 8); + assert(saturating_add_u16(1, 32768) == 32769); + assert(saturating_add_u16(1, 65534) == 65535); + assert(saturating_add_u16(1, 65535) == 65535); + assert(saturating_add_u16(7, 0) == 7); + assert(saturating_add_u16(7, 1) == 8); + assert(saturating_add_u16(7, 7) == 14); + assert(saturating_add_u16(7, 32768) == 32775); + assert(saturating_add_u16(7, 65534) == 65535); + assert(saturating_add_u16(7, 65535) == 65535); + assert(saturating_add_u16(32768, 0) == 32768); + assert(saturating_add_u16(32768, 1) == 32769); + assert(saturating_add_u16(32768, 7) == 32775); + assert(saturating_add_u16(32768, 32768) == 65535); + assert(saturating_add_u16(32768, 65534) == 65535); + assert(saturating_add_u16(32768, 65535) == 65535); + assert(saturating_add_u16(65534, 0) == 65534); + assert(saturating_add_u16(65534, 1) == 65535); + assert(saturating_add_u16(65534, 7) == 65535); + assert(saturating_add_u16(65534, 32768) == 65535); + assert(saturating_add_u16(65534, 65534) == 65535); + assert(saturating_add_u16(65534, 65535) == 65535); + assert(saturating_add_u16(65535, 0) == 65535); + assert(saturating_add_u16(65535, 1) == 65535); + assert(saturating_add_u16(65535, 7) == 65535); + assert(saturating_add_u16(65535, 32768) == 65535); + assert(saturating_add_u16(65535, 65534) == 65535); + assert(saturating_add_u16(65535, 65535) == 65535); + assert(saturating_sub_u16(0, 0) == 0); + assert(saturating_sub_u16(0, 1) == 0); + assert(saturating_sub_u16(0, 7) == 0); + assert(saturating_sub_u16(0, 32768) == 0); + assert(saturating_sub_u16(0, 65534) == 0); + assert(saturating_sub_u16(0, 65535) == 0); + assert(saturating_sub_u16(1, 0) == 1); + assert(saturating_sub_u16(1, 1) == 0); + assert(saturating_sub_u16(1, 7) == 0); + assert(saturating_sub_u16(1, 32768) == 0); + assert(saturating_sub_u16(1, 65534) == 0); + assert(saturating_sub_u16(1, 65535) == 0); + assert(saturating_sub_u16(7, 0) == 7); + assert(saturating_sub_u16(7, 1) == 6); + assert(saturating_sub_u16(7, 7) == 0); + assert(saturating_sub_u16(7, 32768) == 0); + assert(saturating_sub_u16(7, 65534) == 0); + assert(saturating_sub_u16(7, 65535) == 0); + assert(saturating_sub_u16(32768, 0) == 32768); + assert(saturating_sub_u16(32768, 1) == 32767); + assert(saturating_sub_u16(32768, 7) == 32761); + assert(saturating_sub_u16(32768, 32768) == 0); + assert(saturating_sub_u16(32768, 65534) == 0); + assert(saturating_sub_u16(32768, 65535) == 0); + assert(saturating_sub_u16(65534, 0) == 65534); + assert(saturating_sub_u16(65534, 1) == 65533); + assert(saturating_sub_u16(65534, 7) == 65527); + assert(saturating_sub_u16(65534, 32768) == 32766); + assert(saturating_sub_u16(65534, 65534) == 0); + assert(saturating_sub_u16(65534, 65535) == 0); + assert(saturating_sub_u16(65535, 0) == 65535); + assert(saturating_sub_u16(65535, 1) == 65534); + assert(saturating_sub_u16(65535, 7) == 65528); + assert(saturating_sub_u16(65535, 32768) == 32767); + assert(saturating_sub_u16(65535, 65534) == 1); + assert(saturating_sub_u16(65535, 65535) == 0); + assert(saturating_mul_u16(0, 0) == 0); + assert(saturating_mul_u16(0, 1) == 0); + assert(saturating_mul_u16(0, 7) == 0); + assert(saturating_mul_u16(0, 32768) == 0); + assert(saturating_mul_u16(0, 65534) == 0); + assert(saturating_mul_u16(0, 65535) == 0); + assert(saturating_mul_u16(1, 0) == 0); + assert(saturating_mul_u16(1, 1) == 1); + assert(saturating_mul_u16(1, 7) == 7); + assert(saturating_mul_u16(1, 32768) == 32768); + assert(saturating_mul_u16(1, 65534) == 65534); + assert(saturating_mul_u16(1, 65535) == 65535); + assert(saturating_mul_u16(7, 0) == 0); + assert(saturating_mul_u16(7, 1) == 7); + assert(saturating_mul_u16(7, 7) == 49); + assert(saturating_mul_u16(7, 32768) == 65535); + assert(saturating_mul_u16(7, 65534) == 65535); + assert(saturating_mul_u16(7, 65535) == 65535); + assert(saturating_mul_u16(32768, 0) == 0); + assert(saturating_mul_u16(32768, 1) == 32768); + assert(saturating_mul_u16(32768, 7) == 65535); + assert(saturating_mul_u16(32768, 32768) == 65535); + assert(saturating_mul_u16(32768, 65534) == 65535); + assert(saturating_mul_u16(32768, 65535) == 65535); + assert(saturating_mul_u16(65534, 0) == 0); + assert(saturating_mul_u16(65534, 1) == 65534); + assert(saturating_mul_u16(65534, 7) == 65535); + assert(saturating_mul_u16(65534, 32768) == 65535); + assert(saturating_mul_u16(65534, 65534) == 65535); + assert(saturating_mul_u16(65534, 65535) == 65535); + assert(saturating_mul_u16(65535, 0) == 0); + assert(saturating_mul_u16(65535, 1) == 65535); + assert(saturating_mul_u16(65535, 7) == 65535); + assert(saturating_mul_u16(65535, 32768) == 65535); + assert(saturating_mul_u16(65535, 65534) == 65535); + assert(saturating_mul_u16(65535, 65535) == 65535); +} + +/// saturating_add / sub / mul of u32: every expected value was printed by rustc 1.99 running the method on the same +/// inputs; the grid is the edge values taken pairwise, so the clamp-up, clamp-down and exact paths are all reached. +test std_saturating_arithmetic_of_u32_is_rusts { + assert(saturating_add_u32(0, 0) == 0); + assert(saturating_add_u32(0, 1) == 1); + assert(saturating_add_u32(0, 7) == 7); + assert(saturating_add_u32(0, 65536) == 65536); + assert(saturating_add_u32(0, 2147483648) == 2147483648); + assert(saturating_add_u32(0, 4294967295) == 4294967295); + assert(saturating_add_u32(1, 0) == 1); + assert(saturating_add_u32(1, 1) == 2); + assert(saturating_add_u32(1, 7) == 8); + assert(saturating_add_u32(1, 65536) == 65537); + assert(saturating_add_u32(1, 2147483648) == 2147483649); + assert(saturating_add_u32(1, 4294967295) == 4294967295); + assert(saturating_add_u32(7, 0) == 7); + assert(saturating_add_u32(7, 1) == 8); + assert(saturating_add_u32(7, 7) == 14); + assert(saturating_add_u32(7, 65536) == 65543); + assert(saturating_add_u32(7, 2147483648) == 2147483655); + assert(saturating_add_u32(7, 4294967295) == 4294967295); + assert(saturating_add_u32(65536, 0) == 65536); + assert(saturating_add_u32(65536, 1) == 65537); + assert(saturating_add_u32(65536, 7) == 65543); + assert(saturating_add_u32(65536, 65536) == 131072); + assert(saturating_add_u32(65536, 2147483648) == 2147549184); + assert(saturating_add_u32(65536, 4294967295) == 4294967295); + assert(saturating_add_u32(2147483648, 0) == 2147483648); + assert(saturating_add_u32(2147483648, 1) == 2147483649); + assert(saturating_add_u32(2147483648, 7) == 2147483655); + assert(saturating_add_u32(2147483648, 65536) == 2147549184); + assert(saturating_add_u32(2147483648, 2147483648) == 4294967295); + assert(saturating_add_u32(2147483648, 4294967295) == 4294967295); + assert(saturating_add_u32(4294967295, 0) == 4294967295); + assert(saturating_add_u32(4294967295, 1) == 4294967295); + assert(saturating_add_u32(4294967295, 7) == 4294967295); + assert(saturating_add_u32(4294967295, 65536) == 4294967295); + assert(saturating_add_u32(4294967295, 2147483648) == 4294967295); + assert(saturating_add_u32(4294967295, 4294967295) == 4294967295); + assert(saturating_sub_u32(0, 0) == 0); + assert(saturating_sub_u32(0, 1) == 0); + assert(saturating_sub_u32(0, 7) == 0); + assert(saturating_sub_u32(0, 65536) == 0); + assert(saturating_sub_u32(0, 2147483648) == 0); + assert(saturating_sub_u32(0, 4294967295) == 0); + assert(saturating_sub_u32(1, 0) == 1); + assert(saturating_sub_u32(1, 1) == 0); + assert(saturating_sub_u32(1, 7) == 0); + assert(saturating_sub_u32(1, 65536) == 0); + assert(saturating_sub_u32(1, 2147483648) == 0); + assert(saturating_sub_u32(1, 4294967295) == 0); + assert(saturating_sub_u32(7, 0) == 7); + assert(saturating_sub_u32(7, 1) == 6); + assert(saturating_sub_u32(7, 7) == 0); + assert(saturating_sub_u32(7, 65536) == 0); + assert(saturating_sub_u32(7, 2147483648) == 0); + assert(saturating_sub_u32(7, 4294967295) == 0); + assert(saturating_sub_u32(65536, 0) == 65536); + assert(saturating_sub_u32(65536, 1) == 65535); + assert(saturating_sub_u32(65536, 7) == 65529); + assert(saturating_sub_u32(65536, 65536) == 0); + assert(saturating_sub_u32(65536, 2147483648) == 0); + assert(saturating_sub_u32(65536, 4294967295) == 0); + assert(saturating_sub_u32(2147483648, 0) == 2147483648); + assert(saturating_sub_u32(2147483648, 1) == 2147483647); + assert(saturating_sub_u32(2147483648, 7) == 2147483641); + assert(saturating_sub_u32(2147483648, 65536) == 2147418112); + assert(saturating_sub_u32(2147483648, 2147483648) == 0); + assert(saturating_sub_u32(2147483648, 4294967295) == 0); + assert(saturating_sub_u32(4294967295, 0) == 4294967295); + assert(saturating_sub_u32(4294967295, 1) == 4294967294); + assert(saturating_sub_u32(4294967295, 7) == 4294967288); + assert(saturating_sub_u32(4294967295, 65536) == 4294901759); + assert(saturating_sub_u32(4294967295, 2147483648) == 2147483647); + assert(saturating_sub_u32(4294967295, 4294967295) == 0); + assert(saturating_mul_u32(0, 0) == 0); + assert(saturating_mul_u32(0, 1) == 0); + assert(saturating_mul_u32(0, 7) == 0); + assert(saturating_mul_u32(0, 65536) == 0); + assert(saturating_mul_u32(0, 2147483648) == 0); + assert(saturating_mul_u32(0, 4294967295) == 0); + assert(saturating_mul_u32(1, 0) == 0); + assert(saturating_mul_u32(1, 1) == 1); + assert(saturating_mul_u32(1, 7) == 7); + assert(saturating_mul_u32(1, 65536) == 65536); + assert(saturating_mul_u32(1, 2147483648) == 2147483648); + assert(saturating_mul_u32(1, 4294967295) == 4294967295); + assert(saturating_mul_u32(7, 0) == 0); + assert(saturating_mul_u32(7, 1) == 7); + assert(saturating_mul_u32(7, 7) == 49); + assert(saturating_mul_u32(7, 65536) == 458752); + assert(saturating_mul_u32(7, 2147483648) == 4294967295); + assert(saturating_mul_u32(7, 4294967295) == 4294967295); + assert(saturating_mul_u32(65536, 0) == 0); + assert(saturating_mul_u32(65536, 1) == 65536); + assert(saturating_mul_u32(65536, 7) == 458752); + assert(saturating_mul_u32(65536, 65536) == 4294967295); + assert(saturating_mul_u32(65536, 2147483648) == 4294967295); + assert(saturating_mul_u32(65536, 4294967295) == 4294967295); + assert(saturating_mul_u32(2147483648, 0) == 0); + assert(saturating_mul_u32(2147483648, 1) == 2147483648); + assert(saturating_mul_u32(2147483648, 7) == 4294967295); + assert(saturating_mul_u32(2147483648, 65536) == 4294967295); + assert(saturating_mul_u32(2147483648, 2147483648) == 4294967295); + assert(saturating_mul_u32(2147483648, 4294967295) == 4294967295); + assert(saturating_mul_u32(4294967295, 0) == 0); + assert(saturating_mul_u32(4294967295, 1) == 4294967295); + assert(saturating_mul_u32(4294967295, 7) == 4294967295); + assert(saturating_mul_u32(4294967295, 65536) == 4294967295); + assert(saturating_mul_u32(4294967295, 2147483648) == 4294967295); + assert(saturating_mul_u32(4294967295, 4294967295) == 4294967295); +} + +/// saturating_add / sub / mul of u64: every expected value was printed by rustc 1.99 running the method on the same +/// inputs; the grid is the edge values taken pairwise, so the clamp-up, clamp-down and exact paths are all reached. +test std_saturating_arithmetic_of_u64_is_rusts { + assert(saturating_add_u64(0, 0) == 0); + assert(saturating_add_u64(0, 1) == 1); + assert(saturating_add_u64(0, 7) == 7); + assert(saturating_add_u64(0, 4294967296) == 4294967296); + assert(saturating_add_u64(0, 9223372036854775808) == 9223372036854775808); + assert(saturating_add_u64(0, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_u64(1, 0) == 1); + assert(saturating_add_u64(1, 1) == 2); + assert(saturating_add_u64(1, 7) == 8); + assert(saturating_add_u64(1, 4294967296) == 4294967297); + assert(saturating_add_u64(1, 9223372036854775808) == 9223372036854775809); + assert(saturating_add_u64(1, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_u64(7, 0) == 7); + assert(saturating_add_u64(7, 1) == 8); + assert(saturating_add_u64(7, 7) == 14); + assert(saturating_add_u64(7, 4294967296) == 4294967303); + assert(saturating_add_u64(7, 9223372036854775808) == 9223372036854775815); + assert(saturating_add_u64(7, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_u64(4294967296, 0) == 4294967296); + assert(saturating_add_u64(4294967296, 1) == 4294967297); + assert(saturating_add_u64(4294967296, 7) == 4294967303); + assert(saturating_add_u64(4294967296, 4294967296) == 8589934592); + assert(saturating_add_u64(4294967296, 9223372036854775808) == 9223372041149743104); + assert(saturating_add_u64(4294967296, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_u64(9223372036854775808, 0) == 9223372036854775808); + assert(saturating_add_u64(9223372036854775808, 1) == 9223372036854775809); + assert(saturating_add_u64(9223372036854775808, 7) == 9223372036854775815); + assert(saturating_add_u64(9223372036854775808, 4294967296) == 9223372041149743104); + assert(saturating_add_u64(9223372036854775808, 9223372036854775808) == 18446744073709551615); + assert(saturating_add_u64(9223372036854775808, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_u64(18446744073709551615, 0) == 18446744073709551615); + assert(saturating_add_u64(18446744073709551615, 1) == 18446744073709551615); + assert(saturating_add_u64(18446744073709551615, 7) == 18446744073709551615); + assert(saturating_add_u64(18446744073709551615, 4294967296) == 18446744073709551615); + assert(saturating_add_u64(18446744073709551615, 9223372036854775808) == 18446744073709551615); + assert(saturating_add_u64(18446744073709551615, 18446744073709551615) == 18446744073709551615); + assert(saturating_sub_u64(0, 0) == 0); + assert(saturating_sub_u64(0, 1) == 0); + assert(saturating_sub_u64(0, 7) == 0); + assert(saturating_sub_u64(0, 4294967296) == 0); + assert(saturating_sub_u64(0, 9223372036854775808) == 0); + assert(saturating_sub_u64(0, 18446744073709551615) == 0); + assert(saturating_sub_u64(1, 0) == 1); + assert(saturating_sub_u64(1, 1) == 0); + assert(saturating_sub_u64(1, 7) == 0); + assert(saturating_sub_u64(1, 4294967296) == 0); + assert(saturating_sub_u64(1, 9223372036854775808) == 0); + assert(saturating_sub_u64(1, 18446744073709551615) == 0); + assert(saturating_sub_u64(7, 0) == 7); + assert(saturating_sub_u64(7, 1) == 6); + assert(saturating_sub_u64(7, 7) == 0); + assert(saturating_sub_u64(7, 4294967296) == 0); + assert(saturating_sub_u64(7, 9223372036854775808) == 0); + assert(saturating_sub_u64(7, 18446744073709551615) == 0); + assert(saturating_sub_u64(4294967296, 0) == 4294967296); + assert(saturating_sub_u64(4294967296, 1) == 4294967295); + assert(saturating_sub_u64(4294967296, 7) == 4294967289); + assert(saturating_sub_u64(4294967296, 4294967296) == 0); + assert(saturating_sub_u64(4294967296, 9223372036854775808) == 0); + assert(saturating_sub_u64(4294967296, 18446744073709551615) == 0); + assert(saturating_sub_u64(9223372036854775808, 0) == 9223372036854775808); + assert(saturating_sub_u64(9223372036854775808, 1) == 9223372036854775807); + assert(saturating_sub_u64(9223372036854775808, 7) == 9223372036854775801); + assert(saturating_sub_u64(9223372036854775808, 4294967296) == 9223372032559808512); + assert(saturating_sub_u64(9223372036854775808, 9223372036854775808) == 0); + assert(saturating_sub_u64(9223372036854775808, 18446744073709551615) == 0); + assert(saturating_sub_u64(18446744073709551615, 0) == 18446744073709551615); + assert(saturating_sub_u64(18446744073709551615, 1) == 18446744073709551614); + assert(saturating_sub_u64(18446744073709551615, 7) == 18446744073709551608); + assert(saturating_sub_u64(18446744073709551615, 4294967296) == 18446744069414584319); + assert(saturating_sub_u64(18446744073709551615, 9223372036854775808) == 9223372036854775807); + assert(saturating_sub_u64(18446744073709551615, 18446744073709551615) == 0); + assert(saturating_mul_u64(0, 0) == 0); + assert(saturating_mul_u64(0, 1) == 0); + assert(saturating_mul_u64(0, 7) == 0); + assert(saturating_mul_u64(0, 4294967296) == 0); + assert(saturating_mul_u64(0, 9223372036854775808) == 0); + assert(saturating_mul_u64(0, 18446744073709551615) == 0); + assert(saturating_mul_u64(1, 0) == 0); + assert(saturating_mul_u64(1, 1) == 1); + assert(saturating_mul_u64(1, 7) == 7); + assert(saturating_mul_u64(1, 4294967296) == 4294967296); + assert(saturating_mul_u64(1, 9223372036854775808) == 9223372036854775808); + assert(saturating_mul_u64(1, 18446744073709551615) == 18446744073709551615); + assert(saturating_mul_u64(7, 0) == 0); + assert(saturating_mul_u64(7, 1) == 7); + assert(saturating_mul_u64(7, 7) == 49); + assert(saturating_mul_u64(7, 4294967296) == 30064771072); + assert(saturating_mul_u64(7, 9223372036854775808) == 18446744073709551615); + assert(saturating_mul_u64(7, 18446744073709551615) == 18446744073709551615); + assert(saturating_mul_u64(4294967296, 0) == 0); + assert(saturating_mul_u64(4294967296, 1) == 4294967296); + assert(saturating_mul_u64(4294967296, 7) == 30064771072); + assert(saturating_mul_u64(4294967296, 4294967296) == 18446744073709551615); + assert(saturating_mul_u64(4294967296, 9223372036854775808) == 18446744073709551615); + assert(saturating_mul_u64(4294967296, 18446744073709551615) == 18446744073709551615); + assert(saturating_mul_u64(9223372036854775808, 0) == 0); + assert(saturating_mul_u64(9223372036854775808, 1) == 9223372036854775808); + assert(saturating_mul_u64(9223372036854775808, 7) == 18446744073709551615); + assert(saturating_mul_u64(9223372036854775808, 4294967296) == 18446744073709551615); + assert(saturating_mul_u64(9223372036854775808, 9223372036854775808) == 18446744073709551615); + assert(saturating_mul_u64(9223372036854775808, 18446744073709551615) == 18446744073709551615); + assert(saturating_mul_u64(18446744073709551615, 0) == 0); + assert(saturating_mul_u64(18446744073709551615, 1) == 18446744073709551615); + assert(saturating_mul_u64(18446744073709551615, 7) == 18446744073709551615); + assert(saturating_mul_u64(18446744073709551615, 4294967296) == 18446744073709551615); + assert(saturating_mul_u64(18446744073709551615, 9223372036854775808) == 18446744073709551615); + assert(saturating_mul_u64(18446744073709551615, 18446744073709551615) == 18446744073709551615); +} + +/// saturating_add / sub / mul of usize: every expected value was printed by rustc 1.99 running the method on the same +/// inputs; the grid is the edge values taken pairwise, so the clamp-up, clamp-down and exact paths are all reached. +test std_saturating_arithmetic_of_usize_is_rusts { + assert(saturating_add_usize(0, 0) == 0); + assert(saturating_add_usize(0, 1) == 1); + assert(saturating_add_usize(0, 7) == 7); + assert(saturating_add_usize(0, 4294967296) == 4294967296); + assert(saturating_add_usize(0, 9223372036854775808) == 9223372036854775808); + assert(saturating_add_usize(0, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_usize(1, 0) == 1); + assert(saturating_add_usize(1, 1) == 2); + assert(saturating_add_usize(1, 7) == 8); + assert(saturating_add_usize(1, 4294967296) == 4294967297); + assert(saturating_add_usize(1, 9223372036854775808) == 9223372036854775809); + assert(saturating_add_usize(1, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_usize(7, 0) == 7); + assert(saturating_add_usize(7, 1) == 8); + assert(saturating_add_usize(7, 7) == 14); + assert(saturating_add_usize(7, 4294967296) == 4294967303); + assert(saturating_add_usize(7, 9223372036854775808) == 9223372036854775815); + assert(saturating_add_usize(7, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_usize(4294967296, 0) == 4294967296); + assert(saturating_add_usize(4294967296, 1) == 4294967297); + assert(saturating_add_usize(4294967296, 7) == 4294967303); + assert(saturating_add_usize(4294967296, 4294967296) == 8589934592); + assert(saturating_add_usize(4294967296, 9223372036854775808) == 9223372041149743104); + assert(saturating_add_usize(4294967296, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_usize(9223372036854775808, 0) == 9223372036854775808); + assert(saturating_add_usize(9223372036854775808, 1) == 9223372036854775809); + assert(saturating_add_usize(9223372036854775808, 7) == 9223372036854775815); + assert(saturating_add_usize(9223372036854775808, 4294967296) == 9223372041149743104); + assert(saturating_add_usize(9223372036854775808, 9223372036854775808) == 18446744073709551615); + assert(saturating_add_usize(9223372036854775808, 18446744073709551615) == 18446744073709551615); + assert(saturating_add_usize(18446744073709551615, 0) == 18446744073709551615); + assert(saturating_add_usize(18446744073709551615, 1) == 18446744073709551615); + assert(saturating_add_usize(18446744073709551615, 7) == 18446744073709551615); + assert(saturating_add_usize(18446744073709551615, 4294967296) == 18446744073709551615); + assert(saturating_add_usize(18446744073709551615, 9223372036854775808) == 18446744073709551615); + assert(saturating_add_usize(18446744073709551615, 18446744073709551615) == 18446744073709551615); + assert(saturating_sub_usize(0, 0) == 0); + assert(saturating_sub_usize(0, 1) == 0); + assert(saturating_sub_usize(0, 7) == 0); + assert(saturating_sub_usize(0, 4294967296) == 0); + assert(saturating_sub_usize(0, 9223372036854775808) == 0); + assert(saturating_sub_usize(0, 18446744073709551615) == 0); + assert(saturating_sub_usize(1, 0) == 1); + assert(saturating_sub_usize(1, 1) == 0); + assert(saturating_sub_usize(1, 7) == 0); + assert(saturating_sub_usize(1, 4294967296) == 0); + assert(saturating_sub_usize(1, 9223372036854775808) == 0); + assert(saturating_sub_usize(1, 18446744073709551615) == 0); + assert(saturating_sub_usize(7, 0) == 7); + assert(saturating_sub_usize(7, 1) == 6); + assert(saturating_sub_usize(7, 7) == 0); + assert(saturating_sub_usize(7, 4294967296) == 0); + assert(saturating_sub_usize(7, 9223372036854775808) == 0); + assert(saturating_sub_usize(7, 18446744073709551615) == 0); + assert(saturating_sub_usize(4294967296, 0) == 4294967296); + assert(saturating_sub_usize(4294967296, 1) == 4294967295); + assert(saturating_sub_usize(4294967296, 7) == 4294967289); + assert(saturating_sub_usize(4294967296, 4294967296) == 0); + assert(saturating_sub_usize(4294967296, 9223372036854775808) == 0); + assert(saturating_sub_usize(4294967296, 18446744073709551615) == 0); + assert(saturating_sub_usize(9223372036854775808, 0) == 9223372036854775808); + assert(saturating_sub_usize(9223372036854775808, 1) == 9223372036854775807); + assert(saturating_sub_usize(9223372036854775808, 7) == 9223372036854775801); + assert(saturating_sub_usize(9223372036854775808, 4294967296) == 9223372032559808512); + assert(saturating_sub_usize(9223372036854775808, 9223372036854775808) == 0); + assert(saturating_sub_usize(9223372036854775808, 18446744073709551615) == 0); + assert(saturating_sub_usize(18446744073709551615, 0) == 18446744073709551615); + assert(saturating_sub_usize(18446744073709551615, 1) == 18446744073709551614); + assert(saturating_sub_usize(18446744073709551615, 7) == 18446744073709551608); + assert(saturating_sub_usize(18446744073709551615, 4294967296) == 18446744069414584319); + assert(saturating_sub_usize(18446744073709551615, 9223372036854775808) == 9223372036854775807); + assert(saturating_sub_usize(18446744073709551615, 18446744073709551615) == 0); + assert(saturating_mul_usize(0, 0) == 0); + assert(saturating_mul_usize(0, 1) == 0); + assert(saturating_mul_usize(0, 7) == 0); + assert(saturating_mul_usize(0, 4294967296) == 0); + assert(saturating_mul_usize(0, 9223372036854775808) == 0); + assert(saturating_mul_usize(0, 18446744073709551615) == 0); + assert(saturating_mul_usize(1, 0) == 0); + assert(saturating_mul_usize(1, 1) == 1); + assert(saturating_mul_usize(1, 7) == 7); + assert(saturating_mul_usize(1, 4294967296) == 4294967296); + assert(saturating_mul_usize(1, 9223372036854775808) == 9223372036854775808); + assert(saturating_mul_usize(1, 18446744073709551615) == 18446744073709551615); + assert(saturating_mul_usize(7, 0) == 0); + assert(saturating_mul_usize(7, 1) == 7); + assert(saturating_mul_usize(7, 7) == 49); + assert(saturating_mul_usize(7, 4294967296) == 30064771072); + assert(saturating_mul_usize(7, 9223372036854775808) == 18446744073709551615); + assert(saturating_mul_usize(7, 18446744073709551615) == 18446744073709551615); + assert(saturating_mul_usize(4294967296, 0) == 0); + assert(saturating_mul_usize(4294967296, 1) == 4294967296); + assert(saturating_mul_usize(4294967296, 7) == 30064771072); + assert(saturating_mul_usize(4294967296, 4294967296) == 18446744073709551615); + assert(saturating_mul_usize(4294967296, 9223372036854775808) == 18446744073709551615); + assert(saturating_mul_usize(4294967296, 18446744073709551615) == 18446744073709551615); + assert(saturating_mul_usize(9223372036854775808, 0) == 0); + assert(saturating_mul_usize(9223372036854775808, 1) == 9223372036854775808); + assert(saturating_mul_usize(9223372036854775808, 7) == 18446744073709551615); + assert(saturating_mul_usize(9223372036854775808, 4294967296) == 18446744073709551615); + assert(saturating_mul_usize(9223372036854775808, 9223372036854775808) == 18446744073709551615); + assert(saturating_mul_usize(9223372036854775808, 18446744073709551615) == 18446744073709551615); + assert(saturating_mul_usize(18446744073709551615, 0) == 0); + assert(saturating_mul_usize(18446744073709551615, 1) == 18446744073709551615); + assert(saturating_mul_usize(18446744073709551615, 7) == 18446744073709551615); + assert(saturating_mul_usize(18446744073709551615, 4294967296) == 18446744073709551615); + assert(saturating_mul_usize(18446744073709551615, 9223372036854775808) == 18446744073709551615); + assert(saturating_mul_usize(18446744073709551615, 18446744073709551615) == 18446744073709551615); +} + +/// saturating_add / sub / mul of i8: every expected value was printed by rustc 1.99 running the method on the same +/// inputs; the grid is the edge values taken pairwise, so the clamp-up, clamp-down and exact paths are all reached. +test std_saturating_arithmetic_of_i8_is_rusts { + assert(saturating_add_i8(-128, -128) == -128); + assert(saturating_add_i8(-128, -7) == -128); + assert(saturating_add_i8(-128, -1) == -128); + assert(saturating_add_i8(-128, 0) == -128); + assert(saturating_add_i8(-128, 1) == -127); + assert(saturating_add_i8(-128, 7) == -121); + assert(saturating_add_i8(-128, 127) == -1); + assert(saturating_add_i8(-7, -128) == -128); + assert(saturating_add_i8(-7, -7) == -14); + assert(saturating_add_i8(-7, -1) == -8); + assert(saturating_add_i8(-7, 0) == -7); + assert(saturating_add_i8(-7, 1) == -6); + assert(saturating_add_i8(-7, 7) == 0); + assert(saturating_add_i8(-7, 127) == 120); + assert(saturating_add_i8(-1, -128) == -128); + assert(saturating_add_i8(-1, -7) == -8); + assert(saturating_add_i8(-1, -1) == -2); + assert(saturating_add_i8(-1, 0) == -1); + assert(saturating_add_i8(-1, 1) == 0); + assert(saturating_add_i8(-1, 7) == 6); + assert(saturating_add_i8(-1, 127) == 126); + assert(saturating_add_i8(0, -128) == -128); + assert(saturating_add_i8(0, -7) == -7); + assert(saturating_add_i8(0, -1) == -1); + assert(saturating_add_i8(0, 0) == 0); + assert(saturating_add_i8(0, 1) == 1); + assert(saturating_add_i8(0, 7) == 7); + assert(saturating_add_i8(0, 127) == 127); + assert(saturating_add_i8(1, -128) == -127); + assert(saturating_add_i8(1, -7) == -6); + assert(saturating_add_i8(1, -1) == 0); + assert(saturating_add_i8(1, 0) == 1); + assert(saturating_add_i8(1, 1) == 2); + assert(saturating_add_i8(1, 7) == 8); + assert(saturating_add_i8(1, 127) == 127); + assert(saturating_add_i8(7, -128) == -121); + assert(saturating_add_i8(7, -7) == 0); + assert(saturating_add_i8(7, -1) == 6); + assert(saturating_add_i8(7, 0) == 7); + assert(saturating_add_i8(7, 1) == 8); + assert(saturating_add_i8(7, 7) == 14); + assert(saturating_add_i8(7, 127) == 127); + assert(saturating_add_i8(127, -128) == -1); + assert(saturating_add_i8(127, -7) == 120); + assert(saturating_add_i8(127, -1) == 126); + assert(saturating_add_i8(127, 0) == 127); + assert(saturating_add_i8(127, 1) == 127); + assert(saturating_add_i8(127, 7) == 127); + assert(saturating_add_i8(127, 127) == 127); + assert(saturating_sub_i8(-128, -128) == 0); + assert(saturating_sub_i8(-128, -7) == -121); + assert(saturating_sub_i8(-128, -1) == -127); + assert(saturating_sub_i8(-128, 0) == -128); + assert(saturating_sub_i8(-128, 1) == -128); + assert(saturating_sub_i8(-128, 7) == -128); + assert(saturating_sub_i8(-128, 127) == -128); + assert(saturating_sub_i8(-7, -128) == 121); + assert(saturating_sub_i8(-7, -7) == 0); + assert(saturating_sub_i8(-7, -1) == -6); + assert(saturating_sub_i8(-7, 0) == -7); + assert(saturating_sub_i8(-7, 1) == -8); + assert(saturating_sub_i8(-7, 7) == -14); + assert(saturating_sub_i8(-7, 127) == -128); + assert(saturating_sub_i8(-1, -128) == 127); + assert(saturating_sub_i8(-1, -7) == 6); + assert(saturating_sub_i8(-1, -1) == 0); + assert(saturating_sub_i8(-1, 0) == -1); + assert(saturating_sub_i8(-1, 1) == -2); + assert(saturating_sub_i8(-1, 7) == -8); + assert(saturating_sub_i8(-1, 127) == -128); + assert(saturating_sub_i8(0, -128) == 127); + assert(saturating_sub_i8(0, -7) == 7); + assert(saturating_sub_i8(0, -1) == 1); + assert(saturating_sub_i8(0, 0) == 0); + assert(saturating_sub_i8(0, 1) == -1); + assert(saturating_sub_i8(0, 7) == -7); + assert(saturating_sub_i8(0, 127) == -127); + assert(saturating_sub_i8(1, -128) == 127); + assert(saturating_sub_i8(1, -7) == 8); + assert(saturating_sub_i8(1, -1) == 2); + assert(saturating_sub_i8(1, 0) == 1); + assert(saturating_sub_i8(1, 1) == 0); + assert(saturating_sub_i8(1, 7) == -6); + assert(saturating_sub_i8(1, 127) == -126); + assert(saturating_sub_i8(7, -128) == 127); + assert(saturating_sub_i8(7, -7) == 14); + assert(saturating_sub_i8(7, -1) == 8); + assert(saturating_sub_i8(7, 0) == 7); + assert(saturating_sub_i8(7, 1) == 6); + assert(saturating_sub_i8(7, 7) == 0); + assert(saturating_sub_i8(7, 127) == -120); + assert(saturating_sub_i8(127, -128) == 127); + assert(saturating_sub_i8(127, -7) == 127); + assert(saturating_sub_i8(127, -1) == 127); + assert(saturating_sub_i8(127, 0) == 127); + assert(saturating_sub_i8(127, 1) == 126); + assert(saturating_sub_i8(127, 7) == 120); + assert(saturating_sub_i8(127, 127) == 0); + assert(saturating_mul_i8(-128, -128) == 127); + assert(saturating_mul_i8(-128, -7) == 127); + assert(saturating_mul_i8(-128, -1) == 127); + assert(saturating_mul_i8(-128, 0) == 0); + assert(saturating_mul_i8(-128, 1) == -128); + assert(saturating_mul_i8(-128, 7) == -128); + assert(saturating_mul_i8(-128, 127) == -128); + assert(saturating_mul_i8(-7, -128) == 127); + assert(saturating_mul_i8(-7, -7) == 49); + assert(saturating_mul_i8(-7, -1) == 7); + assert(saturating_mul_i8(-7, 0) == 0); + assert(saturating_mul_i8(-7, 1) == -7); + assert(saturating_mul_i8(-7, 7) == -49); + assert(saturating_mul_i8(-7, 127) == -128); + assert(saturating_mul_i8(-1, -128) == 127); + assert(saturating_mul_i8(-1, -7) == 7); + assert(saturating_mul_i8(-1, -1) == 1); + assert(saturating_mul_i8(-1, 0) == 0); + assert(saturating_mul_i8(-1, 1) == -1); + assert(saturating_mul_i8(-1, 7) == -7); + assert(saturating_mul_i8(-1, 127) == -127); + assert(saturating_mul_i8(0, -128) == 0); + assert(saturating_mul_i8(0, -7) == 0); + assert(saturating_mul_i8(0, -1) == 0); + assert(saturating_mul_i8(0, 0) == 0); + assert(saturating_mul_i8(0, 1) == 0); + assert(saturating_mul_i8(0, 7) == 0); + assert(saturating_mul_i8(0, 127) == 0); + assert(saturating_mul_i8(1, -128) == -128); + assert(saturating_mul_i8(1, -7) == -7); + assert(saturating_mul_i8(1, -1) == -1); + assert(saturating_mul_i8(1, 0) == 0); + assert(saturating_mul_i8(1, 1) == 1); + assert(saturating_mul_i8(1, 7) == 7); + assert(saturating_mul_i8(1, 127) == 127); + assert(saturating_mul_i8(7, -128) == -128); + assert(saturating_mul_i8(7, -7) == -49); + assert(saturating_mul_i8(7, -1) == -7); + assert(saturating_mul_i8(7, 0) == 0); + assert(saturating_mul_i8(7, 1) == 7); + assert(saturating_mul_i8(7, 7) == 49); + assert(saturating_mul_i8(7, 127) == 127); + assert(saturating_mul_i8(127, -128) == -128); + assert(saturating_mul_i8(127, -7) == -128); + assert(saturating_mul_i8(127, -1) == -127); + assert(saturating_mul_i8(127, 0) == 0); + assert(saturating_mul_i8(127, 1) == 127); + assert(saturating_mul_i8(127, 7) == 127); + assert(saturating_mul_i8(127, 127) == 127); +} + +/// saturating_add / sub / mul of i16: every expected value was printed by rustc 1.99 running the method on the same +/// inputs; the grid is the edge values taken pairwise, so the clamp-up, clamp-down and exact paths are all reached. +test std_saturating_arithmetic_of_i16_is_rusts { + assert(saturating_add_i16(-32768, -32768) == -32768); + assert(saturating_add_i16(-32768, -7) == -32768); + assert(saturating_add_i16(-32768, -1) == -32768); + assert(saturating_add_i16(-32768, 0) == -32768); + assert(saturating_add_i16(-32768, 1) == -32767); + assert(saturating_add_i16(-32768, 7) == -32761); + assert(saturating_add_i16(-32768, 32767) == -1); + assert(saturating_add_i16(-7, -32768) == -32768); + assert(saturating_add_i16(-7, -7) == -14); + assert(saturating_add_i16(-7, -1) == -8); + assert(saturating_add_i16(-7, 0) == -7); + assert(saturating_add_i16(-7, 1) == -6); + assert(saturating_add_i16(-7, 7) == 0); + assert(saturating_add_i16(-7, 32767) == 32760); + assert(saturating_add_i16(-1, -32768) == -32768); + assert(saturating_add_i16(-1, -7) == -8); + assert(saturating_add_i16(-1, -1) == -2); + assert(saturating_add_i16(-1, 0) == -1); + assert(saturating_add_i16(-1, 1) == 0); + assert(saturating_add_i16(-1, 7) == 6); + assert(saturating_add_i16(-1, 32767) == 32766); + assert(saturating_add_i16(0, -32768) == -32768); + assert(saturating_add_i16(0, -7) == -7); + assert(saturating_add_i16(0, -1) == -1); + assert(saturating_add_i16(0, 0) == 0); + assert(saturating_add_i16(0, 1) == 1); + assert(saturating_add_i16(0, 7) == 7); + assert(saturating_add_i16(0, 32767) == 32767); + assert(saturating_add_i16(1, -32768) == -32767); + assert(saturating_add_i16(1, -7) == -6); + assert(saturating_add_i16(1, -1) == 0); + assert(saturating_add_i16(1, 0) == 1); + assert(saturating_add_i16(1, 1) == 2); + assert(saturating_add_i16(1, 7) == 8); + assert(saturating_add_i16(1, 32767) == 32767); + assert(saturating_add_i16(7, -32768) == -32761); + assert(saturating_add_i16(7, -7) == 0); + assert(saturating_add_i16(7, -1) == 6); + assert(saturating_add_i16(7, 0) == 7); + assert(saturating_add_i16(7, 1) == 8); + assert(saturating_add_i16(7, 7) == 14); + assert(saturating_add_i16(7, 32767) == 32767); + assert(saturating_add_i16(32767, -32768) == -1); + assert(saturating_add_i16(32767, -7) == 32760); + assert(saturating_add_i16(32767, -1) == 32766); + assert(saturating_add_i16(32767, 0) == 32767); + assert(saturating_add_i16(32767, 1) == 32767); + assert(saturating_add_i16(32767, 7) == 32767); + assert(saturating_add_i16(32767, 32767) == 32767); + assert(saturating_sub_i16(-32768, -32768) == 0); + assert(saturating_sub_i16(-32768, -7) == -32761); + assert(saturating_sub_i16(-32768, -1) == -32767); + assert(saturating_sub_i16(-32768, 0) == -32768); + assert(saturating_sub_i16(-32768, 1) == -32768); + assert(saturating_sub_i16(-32768, 7) == -32768); + assert(saturating_sub_i16(-32768, 32767) == -32768); + assert(saturating_sub_i16(-7, -32768) == 32761); + assert(saturating_sub_i16(-7, -7) == 0); + assert(saturating_sub_i16(-7, -1) == -6); + assert(saturating_sub_i16(-7, 0) == -7); + assert(saturating_sub_i16(-7, 1) == -8); + assert(saturating_sub_i16(-7, 7) == -14); + assert(saturating_sub_i16(-7, 32767) == -32768); + assert(saturating_sub_i16(-1, -32768) == 32767); + assert(saturating_sub_i16(-1, -7) == 6); + assert(saturating_sub_i16(-1, -1) == 0); + assert(saturating_sub_i16(-1, 0) == -1); + assert(saturating_sub_i16(-1, 1) == -2); + assert(saturating_sub_i16(-1, 7) == -8); + assert(saturating_sub_i16(-1, 32767) == -32768); + assert(saturating_sub_i16(0, -32768) == 32767); + assert(saturating_sub_i16(0, -7) == 7); + assert(saturating_sub_i16(0, -1) == 1); + assert(saturating_sub_i16(0, 0) == 0); + assert(saturating_sub_i16(0, 1) == -1); + assert(saturating_sub_i16(0, 7) == -7); + assert(saturating_sub_i16(0, 32767) == -32767); + assert(saturating_sub_i16(1, -32768) == 32767); + assert(saturating_sub_i16(1, -7) == 8); + assert(saturating_sub_i16(1, -1) == 2); + assert(saturating_sub_i16(1, 0) == 1); + assert(saturating_sub_i16(1, 1) == 0); + assert(saturating_sub_i16(1, 7) == -6); + assert(saturating_sub_i16(1, 32767) == -32766); + assert(saturating_sub_i16(7, -32768) == 32767); + assert(saturating_sub_i16(7, -7) == 14); + assert(saturating_sub_i16(7, -1) == 8); + assert(saturating_sub_i16(7, 0) == 7); + assert(saturating_sub_i16(7, 1) == 6); + assert(saturating_sub_i16(7, 7) == 0); + assert(saturating_sub_i16(7, 32767) == -32760); + assert(saturating_sub_i16(32767, -32768) == 32767); + assert(saturating_sub_i16(32767, -7) == 32767); + assert(saturating_sub_i16(32767, -1) == 32767); + assert(saturating_sub_i16(32767, 0) == 32767); + assert(saturating_sub_i16(32767, 1) == 32766); + assert(saturating_sub_i16(32767, 7) == 32760); + assert(saturating_sub_i16(32767, 32767) == 0); + assert(saturating_mul_i16(-32768, -32768) == 32767); + assert(saturating_mul_i16(-32768, -7) == 32767); + assert(saturating_mul_i16(-32768, -1) == 32767); + assert(saturating_mul_i16(-32768, 0) == 0); + assert(saturating_mul_i16(-32768, 1) == -32768); + assert(saturating_mul_i16(-32768, 7) == -32768); + assert(saturating_mul_i16(-32768, 32767) == -32768); + assert(saturating_mul_i16(-7, -32768) == 32767); + assert(saturating_mul_i16(-7, -7) == 49); + assert(saturating_mul_i16(-7, -1) == 7); + assert(saturating_mul_i16(-7, 0) == 0); + assert(saturating_mul_i16(-7, 1) == -7); + assert(saturating_mul_i16(-7, 7) == -49); + assert(saturating_mul_i16(-7, 32767) == -32768); + assert(saturating_mul_i16(-1, -32768) == 32767); + assert(saturating_mul_i16(-1, -7) == 7); + assert(saturating_mul_i16(-1, -1) == 1); + assert(saturating_mul_i16(-1, 0) == 0); + assert(saturating_mul_i16(-1, 1) == -1); + assert(saturating_mul_i16(-1, 7) == -7); + assert(saturating_mul_i16(-1, 32767) == -32767); + assert(saturating_mul_i16(0, -32768) == 0); + assert(saturating_mul_i16(0, -7) == 0); + assert(saturating_mul_i16(0, -1) == 0); + assert(saturating_mul_i16(0, 0) == 0); + assert(saturating_mul_i16(0, 1) == 0); + assert(saturating_mul_i16(0, 7) == 0); + assert(saturating_mul_i16(0, 32767) == 0); + assert(saturating_mul_i16(1, -32768) == -32768); + assert(saturating_mul_i16(1, -7) == -7); + assert(saturating_mul_i16(1, -1) == -1); + assert(saturating_mul_i16(1, 0) == 0); + assert(saturating_mul_i16(1, 1) == 1); + assert(saturating_mul_i16(1, 7) == 7); + assert(saturating_mul_i16(1, 32767) == 32767); + assert(saturating_mul_i16(7, -32768) == -32768); + assert(saturating_mul_i16(7, -7) == -49); + assert(saturating_mul_i16(7, -1) == -7); + assert(saturating_mul_i16(7, 0) == 0); + assert(saturating_mul_i16(7, 1) == 7); + assert(saturating_mul_i16(7, 7) == 49); + assert(saturating_mul_i16(7, 32767) == 32767); + assert(saturating_mul_i16(32767, -32768) == -32768); + assert(saturating_mul_i16(32767, -7) == -32768); + assert(saturating_mul_i16(32767, -1) == -32767); + assert(saturating_mul_i16(32767, 0) == 0); + assert(saturating_mul_i16(32767, 1) == 32767); + assert(saturating_mul_i16(32767, 7) == 32767); + assert(saturating_mul_i16(32767, 32767) == 32767); +} + +/// saturating_add / sub / mul of i32: every expected value was printed by rustc 1.99 running the method on the same +/// inputs; the grid is the edge values taken pairwise, so the clamp-up, clamp-down and exact paths are all reached. +test std_saturating_arithmetic_of_i32_is_rusts { + assert(saturating_add_i32(I32_MIN, I32_MIN) == I32_MIN); + assert(saturating_add_i32(I32_MIN, -7) == I32_MIN); + assert(saturating_add_i32(I32_MIN, -1) == I32_MIN); + assert(saturating_add_i32(I32_MIN, 0) == I32_MIN); + assert(saturating_add_i32(I32_MIN, 1) == -2147483647); + assert(saturating_add_i32(I32_MIN, 7) == -2147483641); + assert(saturating_add_i32(I32_MIN, I32_MAX) == -1); + assert(saturating_add_i32(-7, I32_MIN) == I32_MIN); + assert(saturating_add_i32(-7, -7) == -14); + assert(saturating_add_i32(-7, -1) == -8); + assert(saturating_add_i32(-7, 0) == -7); + assert(saturating_add_i32(-7, 1) == -6); + assert(saturating_add_i32(-7, 7) == 0); + assert(saturating_add_i32(-7, I32_MAX) == 2147483640); + assert(saturating_add_i32(-1, I32_MIN) == I32_MIN); + assert(saturating_add_i32(-1, -7) == -8); + assert(saturating_add_i32(-1, -1) == -2); + assert(saturating_add_i32(-1, 0) == -1); + assert(saturating_add_i32(-1, 1) == 0); + assert(saturating_add_i32(-1, 7) == 6); + assert(saturating_add_i32(-1, I32_MAX) == 2147483646); + assert(saturating_add_i32(0, I32_MIN) == I32_MIN); + assert(saturating_add_i32(0, -7) == -7); + assert(saturating_add_i32(0, -1) == -1); + assert(saturating_add_i32(0, 0) == 0); + assert(saturating_add_i32(0, 1) == 1); + assert(saturating_add_i32(0, 7) == 7); + assert(saturating_add_i32(0, I32_MAX) == I32_MAX); + assert(saturating_add_i32(1, I32_MIN) == -2147483647); + assert(saturating_add_i32(1, -7) == -6); + assert(saturating_add_i32(1, -1) == 0); + assert(saturating_add_i32(1, 0) == 1); + assert(saturating_add_i32(1, 1) == 2); + assert(saturating_add_i32(1, 7) == 8); + assert(saturating_add_i32(1, I32_MAX) == I32_MAX); + assert(saturating_add_i32(7, I32_MIN) == -2147483641); + assert(saturating_add_i32(7, -7) == 0); + assert(saturating_add_i32(7, -1) == 6); + assert(saturating_add_i32(7, 0) == 7); + assert(saturating_add_i32(7, 1) == 8); + assert(saturating_add_i32(7, 7) == 14); + assert(saturating_add_i32(7, I32_MAX) == I32_MAX); + assert(saturating_add_i32(I32_MAX, I32_MIN) == -1); + assert(saturating_add_i32(I32_MAX, -7) == 2147483640); + assert(saturating_add_i32(I32_MAX, -1) == 2147483646); + assert(saturating_add_i32(I32_MAX, 0) == I32_MAX); + assert(saturating_add_i32(I32_MAX, 1) == I32_MAX); + assert(saturating_add_i32(I32_MAX, 7) == I32_MAX); + assert(saturating_add_i32(I32_MAX, I32_MAX) == I32_MAX); + assert(saturating_sub_i32(I32_MIN, I32_MIN) == 0); + assert(saturating_sub_i32(I32_MIN, -7) == -2147483641); + assert(saturating_sub_i32(I32_MIN, -1) == -2147483647); + assert(saturating_sub_i32(I32_MIN, 0) == I32_MIN); + assert(saturating_sub_i32(I32_MIN, 1) == I32_MIN); + assert(saturating_sub_i32(I32_MIN, 7) == I32_MIN); + assert(saturating_sub_i32(I32_MIN, I32_MAX) == I32_MIN); + assert(saturating_sub_i32(-7, I32_MIN) == 2147483641); + assert(saturating_sub_i32(-7, -7) == 0); + assert(saturating_sub_i32(-7, -1) == -6); + assert(saturating_sub_i32(-7, 0) == -7); + assert(saturating_sub_i32(-7, 1) == -8); + assert(saturating_sub_i32(-7, 7) == -14); + assert(saturating_sub_i32(-7, I32_MAX) == I32_MIN); + assert(saturating_sub_i32(-1, I32_MIN) == I32_MAX); + assert(saturating_sub_i32(-1, -7) == 6); + assert(saturating_sub_i32(-1, -1) == 0); + assert(saturating_sub_i32(-1, 0) == -1); + assert(saturating_sub_i32(-1, 1) == -2); + assert(saturating_sub_i32(-1, 7) == -8); + assert(saturating_sub_i32(-1, I32_MAX) == I32_MIN); + assert(saturating_sub_i32(0, I32_MIN) == I32_MAX); + assert(saturating_sub_i32(0, -7) == 7); + assert(saturating_sub_i32(0, -1) == 1); + assert(saturating_sub_i32(0, 0) == 0); + assert(saturating_sub_i32(0, 1) == -1); + assert(saturating_sub_i32(0, 7) == -7); + assert(saturating_sub_i32(0, I32_MAX) == -2147483647); + assert(saturating_sub_i32(1, I32_MIN) == I32_MAX); + assert(saturating_sub_i32(1, -7) == 8); + assert(saturating_sub_i32(1, -1) == 2); + assert(saturating_sub_i32(1, 0) == 1); + assert(saturating_sub_i32(1, 1) == 0); + assert(saturating_sub_i32(1, 7) == -6); + assert(saturating_sub_i32(1, I32_MAX) == -2147483646); + assert(saturating_sub_i32(7, I32_MIN) == I32_MAX); + assert(saturating_sub_i32(7, -7) == 14); + assert(saturating_sub_i32(7, -1) == 8); + assert(saturating_sub_i32(7, 0) == 7); + assert(saturating_sub_i32(7, 1) == 6); + assert(saturating_sub_i32(7, 7) == 0); + assert(saturating_sub_i32(7, I32_MAX) == -2147483640); + assert(saturating_sub_i32(I32_MAX, I32_MIN) == I32_MAX); + assert(saturating_sub_i32(I32_MAX, -7) == I32_MAX); + assert(saturating_sub_i32(I32_MAX, -1) == I32_MAX); + assert(saturating_sub_i32(I32_MAX, 0) == I32_MAX); + assert(saturating_sub_i32(I32_MAX, 1) == 2147483646); + assert(saturating_sub_i32(I32_MAX, 7) == 2147483640); + assert(saturating_sub_i32(I32_MAX, I32_MAX) == 0); + assert(saturating_mul_i32(I32_MIN, I32_MIN) == I32_MAX); + assert(saturating_mul_i32(I32_MIN, -7) == I32_MAX); + assert(saturating_mul_i32(I32_MIN, -1) == I32_MAX); + assert(saturating_mul_i32(I32_MIN, 0) == 0); + assert(saturating_mul_i32(I32_MIN, 1) == I32_MIN); + assert(saturating_mul_i32(I32_MIN, 7) == I32_MIN); + assert(saturating_mul_i32(I32_MIN, I32_MAX) == I32_MIN); + assert(saturating_mul_i32(-7, I32_MIN) == I32_MAX); + assert(saturating_mul_i32(-7, -7) == 49); + assert(saturating_mul_i32(-7, -1) == 7); + assert(saturating_mul_i32(-7, 0) == 0); + assert(saturating_mul_i32(-7, 1) == -7); + assert(saturating_mul_i32(-7, 7) == -49); + assert(saturating_mul_i32(-7, I32_MAX) == I32_MIN); + assert(saturating_mul_i32(-1, I32_MIN) == I32_MAX); + assert(saturating_mul_i32(-1, -7) == 7); + assert(saturating_mul_i32(-1, -1) == 1); + assert(saturating_mul_i32(-1, 0) == 0); + assert(saturating_mul_i32(-1, 1) == -1); + assert(saturating_mul_i32(-1, 7) == -7); + assert(saturating_mul_i32(-1, I32_MAX) == -2147483647); + assert(saturating_mul_i32(0, I32_MIN) == 0); + assert(saturating_mul_i32(0, -7) == 0); + assert(saturating_mul_i32(0, -1) == 0); + assert(saturating_mul_i32(0, 0) == 0); + assert(saturating_mul_i32(0, 1) == 0); + assert(saturating_mul_i32(0, 7) == 0); + assert(saturating_mul_i32(0, I32_MAX) == 0); + assert(saturating_mul_i32(1, I32_MIN) == I32_MIN); + assert(saturating_mul_i32(1, -7) == -7); + assert(saturating_mul_i32(1, -1) == -1); + assert(saturating_mul_i32(1, 0) == 0); + assert(saturating_mul_i32(1, 1) == 1); + assert(saturating_mul_i32(1, 7) == 7); + assert(saturating_mul_i32(1, I32_MAX) == I32_MAX); + assert(saturating_mul_i32(7, I32_MIN) == I32_MIN); + assert(saturating_mul_i32(7, -7) == -49); + assert(saturating_mul_i32(7, -1) == -7); + assert(saturating_mul_i32(7, 0) == 0); + assert(saturating_mul_i32(7, 1) == 7); + assert(saturating_mul_i32(7, 7) == 49); + assert(saturating_mul_i32(7, I32_MAX) == I32_MAX); + assert(saturating_mul_i32(I32_MAX, I32_MIN) == I32_MIN); + assert(saturating_mul_i32(I32_MAX, -7) == I32_MIN); + assert(saturating_mul_i32(I32_MAX, -1) == -2147483647); + assert(saturating_mul_i32(I32_MAX, 0) == 0); + assert(saturating_mul_i32(I32_MAX, 1) == I32_MAX); + assert(saturating_mul_i32(I32_MAX, 7) == I32_MAX); + assert(saturating_mul_i32(I32_MAX, I32_MAX) == I32_MAX); +} + +/// saturating_add / sub / mul of i64: every expected value was printed by rustc 1.99 running the method on the same +/// inputs; the grid is the edge values taken pairwise, so the clamp-up, clamp-down and exact paths are all reached. +test std_saturating_arithmetic_of_i64_is_rusts { + assert(saturating_add_i64(I64_MIN, I64_MIN) == I64_MIN); + assert(saturating_add_i64(I64_MIN, -7) == I64_MIN); + assert(saturating_add_i64(I64_MIN, -1) == I64_MIN); + assert(saturating_add_i64(I64_MIN, 0) == I64_MIN); + assert(saturating_add_i64(I64_MIN, 1) == -9223372036854775807); + assert(saturating_add_i64(I64_MIN, 7) == -9223372036854775801); + assert(saturating_add_i64(I64_MIN, I64_MAX) == -1); + assert(saturating_add_i64(-7, I64_MIN) == I64_MIN); + assert(saturating_add_i64(-7, -7) == -14); + assert(saturating_add_i64(-7, -1) == -8); + assert(saturating_add_i64(-7, 0) == -7); + assert(saturating_add_i64(-7, 1) == -6); + assert(saturating_add_i64(-7, 7) == 0); + assert(saturating_add_i64(-7, I64_MAX) == 9223372036854775800); + assert(saturating_add_i64(-1, I64_MIN) == I64_MIN); + assert(saturating_add_i64(-1, -7) == -8); + assert(saturating_add_i64(-1, -1) == -2); + assert(saturating_add_i64(-1, 0) == -1); + assert(saturating_add_i64(-1, 1) == 0); + assert(saturating_add_i64(-1, 7) == 6); + assert(saturating_add_i64(-1, I64_MAX) == 9223372036854775806); + assert(saturating_add_i64(0, I64_MIN) == I64_MIN); + assert(saturating_add_i64(0, -7) == -7); + assert(saturating_add_i64(0, -1) == -1); + assert(saturating_add_i64(0, 0) == 0); + assert(saturating_add_i64(0, 1) == 1); + assert(saturating_add_i64(0, 7) == 7); + assert(saturating_add_i64(0, I64_MAX) == I64_MAX); + assert(saturating_add_i64(1, I64_MIN) == -9223372036854775807); + assert(saturating_add_i64(1, -7) == -6); + assert(saturating_add_i64(1, -1) == 0); + assert(saturating_add_i64(1, 0) == 1); + assert(saturating_add_i64(1, 1) == 2); + assert(saturating_add_i64(1, 7) == 8); + assert(saturating_add_i64(1, I64_MAX) == I64_MAX); + assert(saturating_add_i64(7, I64_MIN) == -9223372036854775801); + assert(saturating_add_i64(7, -7) == 0); + assert(saturating_add_i64(7, -1) == 6); + assert(saturating_add_i64(7, 0) == 7); + assert(saturating_add_i64(7, 1) == 8); + assert(saturating_add_i64(7, 7) == 14); + assert(saturating_add_i64(7, I64_MAX) == I64_MAX); + assert(saturating_add_i64(I64_MAX, I64_MIN) == -1); + assert(saturating_add_i64(I64_MAX, -7) == 9223372036854775800); + assert(saturating_add_i64(I64_MAX, -1) == 9223372036854775806); + assert(saturating_add_i64(I64_MAX, 0) == I64_MAX); + assert(saturating_add_i64(I64_MAX, 1) == I64_MAX); + assert(saturating_add_i64(I64_MAX, 7) == I64_MAX); + assert(saturating_add_i64(I64_MAX, I64_MAX) == I64_MAX); + assert(saturating_sub_i64(I64_MIN, I64_MIN) == 0); + assert(saturating_sub_i64(I64_MIN, -7) == -9223372036854775801); + assert(saturating_sub_i64(I64_MIN, -1) == -9223372036854775807); + assert(saturating_sub_i64(I64_MIN, 0) == I64_MIN); + assert(saturating_sub_i64(I64_MIN, 1) == I64_MIN); + assert(saturating_sub_i64(I64_MIN, 7) == I64_MIN); + assert(saturating_sub_i64(I64_MIN, I64_MAX) == I64_MIN); + assert(saturating_sub_i64(-7, I64_MIN) == 9223372036854775801); + assert(saturating_sub_i64(-7, -7) == 0); + assert(saturating_sub_i64(-7, -1) == -6); + assert(saturating_sub_i64(-7, 0) == -7); + assert(saturating_sub_i64(-7, 1) == -8); + assert(saturating_sub_i64(-7, 7) == -14); + assert(saturating_sub_i64(-7, I64_MAX) == I64_MIN); + assert(saturating_sub_i64(-1, I64_MIN) == I64_MAX); + assert(saturating_sub_i64(-1, -7) == 6); + assert(saturating_sub_i64(-1, -1) == 0); + assert(saturating_sub_i64(-1, 0) == -1); + assert(saturating_sub_i64(-1, 1) == -2); + assert(saturating_sub_i64(-1, 7) == -8); + assert(saturating_sub_i64(-1, I64_MAX) == I64_MIN); + assert(saturating_sub_i64(0, I64_MIN) == I64_MAX); + assert(saturating_sub_i64(0, -7) == 7); + assert(saturating_sub_i64(0, -1) == 1); + assert(saturating_sub_i64(0, 0) == 0); + assert(saturating_sub_i64(0, 1) == -1); + assert(saturating_sub_i64(0, 7) == -7); + assert(saturating_sub_i64(0, I64_MAX) == -9223372036854775807); + assert(saturating_sub_i64(1, I64_MIN) == I64_MAX); + assert(saturating_sub_i64(1, -7) == 8); + assert(saturating_sub_i64(1, -1) == 2); + assert(saturating_sub_i64(1, 0) == 1); + assert(saturating_sub_i64(1, 1) == 0); + assert(saturating_sub_i64(1, 7) == -6); + assert(saturating_sub_i64(1, I64_MAX) == -9223372036854775806); + assert(saturating_sub_i64(7, I64_MIN) == I64_MAX); + assert(saturating_sub_i64(7, -7) == 14); + assert(saturating_sub_i64(7, -1) == 8); + assert(saturating_sub_i64(7, 0) == 7); + assert(saturating_sub_i64(7, 1) == 6); + assert(saturating_sub_i64(7, 7) == 0); + assert(saturating_sub_i64(7, I64_MAX) == -9223372036854775800); + assert(saturating_sub_i64(I64_MAX, I64_MIN) == I64_MAX); + assert(saturating_sub_i64(I64_MAX, -7) == I64_MAX); + assert(saturating_sub_i64(I64_MAX, -1) == I64_MAX); + assert(saturating_sub_i64(I64_MAX, 0) == I64_MAX); + assert(saturating_sub_i64(I64_MAX, 1) == 9223372036854775806); + assert(saturating_sub_i64(I64_MAX, 7) == 9223372036854775800); + assert(saturating_sub_i64(I64_MAX, I64_MAX) == 0); + assert(saturating_mul_i64(I64_MIN, I64_MIN) == I64_MAX); + assert(saturating_mul_i64(I64_MIN, -7) == I64_MAX); + assert(saturating_mul_i64(I64_MIN, -1) == I64_MAX); + assert(saturating_mul_i64(I64_MIN, 0) == 0); + assert(saturating_mul_i64(I64_MIN, 1) == I64_MIN); + assert(saturating_mul_i64(I64_MIN, 7) == I64_MIN); + assert(saturating_mul_i64(I64_MIN, I64_MAX) == I64_MIN); + assert(saturating_mul_i64(-7, I64_MIN) == I64_MAX); + assert(saturating_mul_i64(-7, -7) == 49); + assert(saturating_mul_i64(-7, -1) == 7); + assert(saturating_mul_i64(-7, 0) == 0); + assert(saturating_mul_i64(-7, 1) == -7); + assert(saturating_mul_i64(-7, 7) == -49); + assert(saturating_mul_i64(-7, I64_MAX) == I64_MIN); + assert(saturating_mul_i64(-1, I64_MIN) == I64_MAX); + assert(saturating_mul_i64(-1, -7) == 7); + assert(saturating_mul_i64(-1, -1) == 1); + assert(saturating_mul_i64(-1, 0) == 0); + assert(saturating_mul_i64(-1, 1) == -1); + assert(saturating_mul_i64(-1, 7) == -7); + assert(saturating_mul_i64(-1, I64_MAX) == -9223372036854775807); + assert(saturating_mul_i64(0, I64_MIN) == 0); + assert(saturating_mul_i64(0, -7) == 0); + assert(saturating_mul_i64(0, -1) == 0); + assert(saturating_mul_i64(0, 0) == 0); + assert(saturating_mul_i64(0, 1) == 0); + assert(saturating_mul_i64(0, 7) == 0); + assert(saturating_mul_i64(0, I64_MAX) == 0); + assert(saturating_mul_i64(1, I64_MIN) == I64_MIN); + assert(saturating_mul_i64(1, -7) == -7); + assert(saturating_mul_i64(1, -1) == -1); + assert(saturating_mul_i64(1, 0) == 0); + assert(saturating_mul_i64(1, 1) == 1); + assert(saturating_mul_i64(1, 7) == 7); + assert(saturating_mul_i64(1, I64_MAX) == I64_MAX); + assert(saturating_mul_i64(7, I64_MIN) == I64_MIN); + assert(saturating_mul_i64(7, -7) == -49); + assert(saturating_mul_i64(7, -1) == -7); + assert(saturating_mul_i64(7, 0) == 0); + assert(saturating_mul_i64(7, 1) == 7); + assert(saturating_mul_i64(7, 7) == 49); + assert(saturating_mul_i64(7, I64_MAX) == I64_MAX); + assert(saturating_mul_i64(I64_MAX, I64_MIN) == I64_MIN); + assert(saturating_mul_i64(I64_MAX, -7) == I64_MIN); + assert(saturating_mul_i64(I64_MAX, -1) == -9223372036854775807); + assert(saturating_mul_i64(I64_MAX, 0) == 0); + assert(saturating_mul_i64(I64_MAX, 1) == I64_MAX); + assert(saturating_mul_i64(I64_MAX, 7) == I64_MAX); + assert(saturating_mul_i64(I64_MAX, I64_MAX) == I64_MAX); +} + +/// div_ceil of u8: every expected value was printed by rustc 1.99 running `a.div_ceil(b)` on the same inputs; +/// the pairs are the edge values taken pairwise, divisor 0 left out (it panics). +test std_div_ceil_of_u8_is_rusts { + assert(div_ceil_u8(0, 1) == 0); + assert(div_ceil_u8(0, 2) == 0); + assert(div_ceil_u8(0, 3) == 0); + assert(div_ceil_u8(0, 7) == 0); + assert(div_ceil_u8(0, 100) == 0); + assert(div_ceil_u8(0, 127) == 0); + assert(div_ceil_u8(0, 128) == 0); + assert(div_ceil_u8(0, 254) == 0); + assert(div_ceil_u8(0, 255) == 0); + assert(div_ceil_u8(1, 1) == 1); + assert(div_ceil_u8(1, 2) == 1); + assert(div_ceil_u8(1, 3) == 1); + assert(div_ceil_u8(1, 7) == 1); + assert(div_ceil_u8(1, 100) == 1); + assert(div_ceil_u8(1, 127) == 1); + assert(div_ceil_u8(1, 128) == 1); + assert(div_ceil_u8(1, 254) == 1); + assert(div_ceil_u8(1, 255) == 1); + assert(div_ceil_u8(2, 1) == 2); + assert(div_ceil_u8(2, 2) == 1); + assert(div_ceil_u8(2, 3) == 1); + assert(div_ceil_u8(2, 7) == 1); + assert(div_ceil_u8(2, 100) == 1); + assert(div_ceil_u8(2, 127) == 1); + assert(div_ceil_u8(2, 128) == 1); + assert(div_ceil_u8(2, 254) == 1); + assert(div_ceil_u8(2, 255) == 1); + assert(div_ceil_u8(3, 1) == 3); + assert(div_ceil_u8(3, 2) == 2); + assert(div_ceil_u8(3, 3) == 1); + assert(div_ceil_u8(3, 7) == 1); + assert(div_ceil_u8(3, 100) == 1); + assert(div_ceil_u8(3, 127) == 1); + assert(div_ceil_u8(3, 128) == 1); + assert(div_ceil_u8(3, 254) == 1); + assert(div_ceil_u8(3, 255) == 1); + assert(div_ceil_u8(7, 1) == 7); + assert(div_ceil_u8(7, 2) == 4); + assert(div_ceil_u8(7, 3) == 3); + assert(div_ceil_u8(7, 7) == 1); + assert(div_ceil_u8(7, 100) == 1); + assert(div_ceil_u8(7, 127) == 1); + assert(div_ceil_u8(7, 128) == 1); + assert(div_ceil_u8(7, 254) == 1); + assert(div_ceil_u8(7, 255) == 1); + assert(div_ceil_u8(100, 1) == 100); + assert(div_ceil_u8(100, 2) == 50); + assert(div_ceil_u8(100, 3) == 34); + assert(div_ceil_u8(100, 7) == 15); + assert(div_ceil_u8(100, 100) == 1); + assert(div_ceil_u8(100, 127) == 1); + assert(div_ceil_u8(100, 128) == 1); + assert(div_ceil_u8(100, 254) == 1); + assert(div_ceil_u8(100, 255) == 1); + assert(div_ceil_u8(127, 1) == 127); + assert(div_ceil_u8(127, 2) == 64); + assert(div_ceil_u8(127, 3) == 43); + assert(div_ceil_u8(127, 7) == 19); + assert(div_ceil_u8(127, 100) == 2); + assert(div_ceil_u8(127, 127) == 1); + assert(div_ceil_u8(127, 128) == 1); + assert(div_ceil_u8(127, 254) == 1); + assert(div_ceil_u8(127, 255) == 1); + assert(div_ceil_u8(128, 1) == 128); + assert(div_ceil_u8(128, 2) == 64); + assert(div_ceil_u8(128, 3) == 43); + assert(div_ceil_u8(128, 7) == 19); + assert(div_ceil_u8(128, 100) == 2); + assert(div_ceil_u8(128, 127) == 2); + assert(div_ceil_u8(128, 128) == 1); + assert(div_ceil_u8(128, 254) == 1); + assert(div_ceil_u8(128, 255) == 1); + assert(div_ceil_u8(254, 1) == 254); + assert(div_ceil_u8(254, 2) == 127); + assert(div_ceil_u8(254, 3) == 85); + assert(div_ceil_u8(254, 7) == 37); + assert(div_ceil_u8(254, 100) == 3); + assert(div_ceil_u8(254, 127) == 2); + assert(div_ceil_u8(254, 128) == 2); + assert(div_ceil_u8(254, 254) == 1); + assert(div_ceil_u8(254, 255) == 1); + assert(div_ceil_u8(255, 1) == 255); + assert(div_ceil_u8(255, 2) == 128); + assert(div_ceil_u8(255, 3) == 85); + assert(div_ceil_u8(255, 7) == 37); + assert(div_ceil_u8(255, 100) == 3); + assert(div_ceil_u8(255, 127) == 3); + assert(div_ceil_u8(255, 128) == 2); + assert(div_ceil_u8(255, 254) == 2); + assert(div_ceil_u8(255, 255) == 1); +} + +/// div_ceil of u16: every expected value was printed by rustc 1.99 running `a.div_ceil(b)` on the same inputs; +/// the pairs are the edge values taken pairwise, divisor 0 left out (it panics). +test std_div_ceil_of_u16_is_rusts { + assert(div_ceil_u16(0, 1) == 0); + assert(div_ceil_u16(0, 2) == 0); + assert(div_ceil_u16(0, 3) == 0); + assert(div_ceil_u16(0, 7) == 0); + assert(div_ceil_u16(0, 255) == 0); + assert(div_ceil_u16(0, 256) == 0); + assert(div_ceil_u16(0, 32767) == 0); + assert(div_ceil_u16(0, 32768) == 0); + assert(div_ceil_u16(0, 65535) == 0); + assert(div_ceil_u16(1, 1) == 1); + assert(div_ceil_u16(1, 2) == 1); + assert(div_ceil_u16(1, 3) == 1); + assert(div_ceil_u16(1, 7) == 1); + assert(div_ceil_u16(1, 255) == 1); + assert(div_ceil_u16(1, 256) == 1); + assert(div_ceil_u16(1, 32767) == 1); + assert(div_ceil_u16(1, 32768) == 1); + assert(div_ceil_u16(1, 65535) == 1); + assert(div_ceil_u16(2, 1) == 2); + assert(div_ceil_u16(2, 2) == 1); + assert(div_ceil_u16(2, 3) == 1); + assert(div_ceil_u16(2, 7) == 1); + assert(div_ceil_u16(2, 255) == 1); + assert(div_ceil_u16(2, 256) == 1); + assert(div_ceil_u16(2, 32767) == 1); + assert(div_ceil_u16(2, 32768) == 1); + assert(div_ceil_u16(2, 65535) == 1); + assert(div_ceil_u16(3, 1) == 3); + assert(div_ceil_u16(3, 2) == 2); + assert(div_ceil_u16(3, 3) == 1); + assert(div_ceil_u16(3, 7) == 1); + assert(div_ceil_u16(3, 255) == 1); + assert(div_ceil_u16(3, 256) == 1); + assert(div_ceil_u16(3, 32767) == 1); + assert(div_ceil_u16(3, 32768) == 1); + assert(div_ceil_u16(3, 65535) == 1); + assert(div_ceil_u16(7, 1) == 7); + assert(div_ceil_u16(7, 2) == 4); + assert(div_ceil_u16(7, 3) == 3); + assert(div_ceil_u16(7, 7) == 1); + assert(div_ceil_u16(7, 255) == 1); + assert(div_ceil_u16(7, 256) == 1); + assert(div_ceil_u16(7, 32767) == 1); + assert(div_ceil_u16(7, 32768) == 1); + assert(div_ceil_u16(7, 65535) == 1); + assert(div_ceil_u16(255, 1) == 255); + assert(div_ceil_u16(255, 2) == 128); + assert(div_ceil_u16(255, 3) == 85); + assert(div_ceil_u16(255, 7) == 37); + assert(div_ceil_u16(255, 255) == 1); + assert(div_ceil_u16(255, 256) == 1); + assert(div_ceil_u16(255, 32767) == 1); + assert(div_ceil_u16(255, 32768) == 1); + assert(div_ceil_u16(255, 65535) == 1); + assert(div_ceil_u16(256, 1) == 256); + assert(div_ceil_u16(256, 2) == 128); + assert(div_ceil_u16(256, 3) == 86); + assert(div_ceil_u16(256, 7) == 37); + assert(div_ceil_u16(256, 255) == 2); + assert(div_ceil_u16(256, 256) == 1); + assert(div_ceil_u16(256, 32767) == 1); + assert(div_ceil_u16(256, 32768) == 1); + assert(div_ceil_u16(256, 65535) == 1); + assert(div_ceil_u16(32767, 1) == 32767); + assert(div_ceil_u16(32767, 2) == 16384); + assert(div_ceil_u16(32767, 3) == 10923); + assert(div_ceil_u16(32767, 7) == 4681); + assert(div_ceil_u16(32767, 255) == 129); + assert(div_ceil_u16(32767, 256) == 128); + assert(div_ceil_u16(32767, 32767) == 1); + assert(div_ceil_u16(32767, 32768) == 1); + assert(div_ceil_u16(32767, 65535) == 1); + assert(div_ceil_u16(32768, 1) == 32768); + assert(div_ceil_u16(32768, 2) == 16384); + assert(div_ceil_u16(32768, 3) == 10923); + assert(div_ceil_u16(32768, 7) == 4682); + assert(div_ceil_u16(32768, 255) == 129); + assert(div_ceil_u16(32768, 256) == 128); + assert(div_ceil_u16(32768, 32767) == 2); + assert(div_ceil_u16(32768, 32768) == 1); + assert(div_ceil_u16(32768, 65535) == 1); + assert(div_ceil_u16(65535, 1) == 65535); + assert(div_ceil_u16(65535, 2) == 32768); + assert(div_ceil_u16(65535, 3) == 21845); + assert(div_ceil_u16(65535, 7) == 9363); + assert(div_ceil_u16(65535, 255) == 257); + assert(div_ceil_u16(65535, 256) == 256); + assert(div_ceil_u16(65535, 32767) == 3); + assert(div_ceil_u16(65535, 32768) == 2); + assert(div_ceil_u16(65535, 65535) == 1); +} + +/// div_ceil of u32: every expected value was printed by rustc 1.99 running `a.div_ceil(b)` on the same inputs; +/// the pairs are the edge values taken pairwise, divisor 0 left out (it panics). +test std_div_ceil_of_u32_is_rusts { + assert(div_ceil_u32(0, 1) == 0); + assert(div_ceil_u32(0, 2) == 0); + assert(div_ceil_u32(0, 3) == 0); + assert(div_ceil_u32(0, 7) == 0); + assert(div_ceil_u32(0, 65535) == 0); + assert(div_ceil_u32(0, 65536) == 0); + assert(div_ceil_u32(0, 2147483647) == 0); + assert(div_ceil_u32(0, 2147483648) == 0); + assert(div_ceil_u32(0, 4294967295) == 0); + assert(div_ceil_u32(1, 1) == 1); + assert(div_ceil_u32(1, 2) == 1); + assert(div_ceil_u32(1, 3) == 1); + assert(div_ceil_u32(1, 7) == 1); + assert(div_ceil_u32(1, 65535) == 1); + assert(div_ceil_u32(1, 65536) == 1); + assert(div_ceil_u32(1, 2147483647) == 1); + assert(div_ceil_u32(1, 2147483648) == 1); + assert(div_ceil_u32(1, 4294967295) == 1); + assert(div_ceil_u32(2, 1) == 2); + assert(div_ceil_u32(2, 2) == 1); + assert(div_ceil_u32(2, 3) == 1); + assert(div_ceil_u32(2, 7) == 1); + assert(div_ceil_u32(2, 65535) == 1); + assert(div_ceil_u32(2, 65536) == 1); + assert(div_ceil_u32(2, 2147483647) == 1); + assert(div_ceil_u32(2, 2147483648) == 1); + assert(div_ceil_u32(2, 4294967295) == 1); + assert(div_ceil_u32(3, 1) == 3); + assert(div_ceil_u32(3, 2) == 2); + assert(div_ceil_u32(3, 3) == 1); + assert(div_ceil_u32(3, 7) == 1); + assert(div_ceil_u32(3, 65535) == 1); + assert(div_ceil_u32(3, 65536) == 1); + assert(div_ceil_u32(3, 2147483647) == 1); + assert(div_ceil_u32(3, 2147483648) == 1); + assert(div_ceil_u32(3, 4294967295) == 1); + assert(div_ceil_u32(7, 1) == 7); + assert(div_ceil_u32(7, 2) == 4); + assert(div_ceil_u32(7, 3) == 3); + assert(div_ceil_u32(7, 7) == 1); + assert(div_ceil_u32(7, 65535) == 1); + assert(div_ceil_u32(7, 65536) == 1); + assert(div_ceil_u32(7, 2147483647) == 1); + assert(div_ceil_u32(7, 2147483648) == 1); + assert(div_ceil_u32(7, 4294967295) == 1); + assert(div_ceil_u32(65535, 1) == 65535); + assert(div_ceil_u32(65535, 2) == 32768); + assert(div_ceil_u32(65535, 3) == 21845); + assert(div_ceil_u32(65535, 7) == 9363); + assert(div_ceil_u32(65535, 65535) == 1); + assert(div_ceil_u32(65535, 65536) == 1); + assert(div_ceil_u32(65535, 2147483647) == 1); + assert(div_ceil_u32(65535, 2147483648) == 1); + assert(div_ceil_u32(65535, 4294967295) == 1); + assert(div_ceil_u32(65536, 1) == 65536); + assert(div_ceil_u32(65536, 2) == 32768); + assert(div_ceil_u32(65536, 3) == 21846); + assert(div_ceil_u32(65536, 7) == 9363); + assert(div_ceil_u32(65536, 65535) == 2); + assert(div_ceil_u32(65536, 65536) == 1); + assert(div_ceil_u32(65536, 2147483647) == 1); + assert(div_ceil_u32(65536, 2147483648) == 1); + assert(div_ceil_u32(65536, 4294967295) == 1); + assert(div_ceil_u32(2147483647, 1) == 2147483647); + assert(div_ceil_u32(2147483647, 2) == 1073741824); + assert(div_ceil_u32(2147483647, 3) == 715827883); + assert(div_ceil_u32(2147483647, 7) == 306783379); + assert(div_ceil_u32(2147483647, 65535) == 32769); + assert(div_ceil_u32(2147483647, 65536) == 32768); + assert(div_ceil_u32(2147483647, 2147483647) == 1); + assert(div_ceil_u32(2147483647, 2147483648) == 1); + assert(div_ceil_u32(2147483647, 4294967295) == 1); + assert(div_ceil_u32(2147483648, 1) == 2147483648); + assert(div_ceil_u32(2147483648, 2) == 1073741824); + assert(div_ceil_u32(2147483648, 3) == 715827883); + assert(div_ceil_u32(2147483648, 7) == 306783379); + assert(div_ceil_u32(2147483648, 65535) == 32769); + assert(div_ceil_u32(2147483648, 65536) == 32768); + assert(div_ceil_u32(2147483648, 2147483647) == 2); + assert(div_ceil_u32(2147483648, 2147483648) == 1); + assert(div_ceil_u32(2147483648, 4294967295) == 1); + assert(div_ceil_u32(4294967295, 1) == 4294967295); + assert(div_ceil_u32(4294967295, 2) == 2147483648); + assert(div_ceil_u32(4294967295, 3) == 1431655765); + assert(div_ceil_u32(4294967295, 7) == 613566757); + assert(div_ceil_u32(4294967295, 65535) == 65537); + assert(div_ceil_u32(4294967295, 65536) == 65536); + assert(div_ceil_u32(4294967295, 2147483647) == 3); + assert(div_ceil_u32(4294967295, 2147483648) == 2); + assert(div_ceil_u32(4294967295, 4294967295) == 1); +} + +/// div_ceil of u64: every expected value was printed by rustc 1.99 running `a.div_ceil(b)` on the same inputs; +/// the pairs are the edge values taken pairwise, divisor 0 left out (it panics). +test std_div_ceil_of_u64_is_rusts { + assert(div_ceil_u64(0, 1) == 0); + assert(div_ceil_u64(0, 2) == 0); + assert(div_ceil_u64(0, 3) == 0); + assert(div_ceil_u64(0, 7) == 0); + assert(div_ceil_u64(0, 4294967295) == 0); + assert(div_ceil_u64(0, 4294967296) == 0); + assert(div_ceil_u64(0, 9223372036854775807) == 0); + assert(div_ceil_u64(0, 9223372036854775808) == 0); + assert(div_ceil_u64(0, 18446744073709551615) == 0); + assert(div_ceil_u64(1, 1) == 1); + assert(div_ceil_u64(1, 2) == 1); + assert(div_ceil_u64(1, 3) == 1); + assert(div_ceil_u64(1, 7) == 1); + assert(div_ceil_u64(1, 4294967295) == 1); + assert(div_ceil_u64(1, 4294967296) == 1); + assert(div_ceil_u64(1, 9223372036854775807) == 1); + assert(div_ceil_u64(1, 9223372036854775808) == 1); + assert(div_ceil_u64(1, 18446744073709551615) == 1); + assert(div_ceil_u64(2, 1) == 2); + assert(div_ceil_u64(2, 2) == 1); + assert(div_ceil_u64(2, 3) == 1); + assert(div_ceil_u64(2, 7) == 1); + assert(div_ceil_u64(2, 4294967295) == 1); + assert(div_ceil_u64(2, 4294967296) == 1); + assert(div_ceil_u64(2, 9223372036854775807) == 1); + assert(div_ceil_u64(2, 9223372036854775808) == 1); + assert(div_ceil_u64(2, 18446744073709551615) == 1); + assert(div_ceil_u64(3, 1) == 3); + assert(div_ceil_u64(3, 2) == 2); + assert(div_ceil_u64(3, 3) == 1); + assert(div_ceil_u64(3, 7) == 1); + assert(div_ceil_u64(3, 4294967295) == 1); + assert(div_ceil_u64(3, 4294967296) == 1); + assert(div_ceil_u64(3, 9223372036854775807) == 1); + assert(div_ceil_u64(3, 9223372036854775808) == 1); + assert(div_ceil_u64(3, 18446744073709551615) == 1); + assert(div_ceil_u64(7, 1) == 7); + assert(div_ceil_u64(7, 2) == 4); + assert(div_ceil_u64(7, 3) == 3); + assert(div_ceil_u64(7, 7) == 1); + assert(div_ceil_u64(7, 4294967295) == 1); + assert(div_ceil_u64(7, 4294967296) == 1); + assert(div_ceil_u64(7, 9223372036854775807) == 1); + assert(div_ceil_u64(7, 9223372036854775808) == 1); + assert(div_ceil_u64(7, 18446744073709551615) == 1); + assert(div_ceil_u64(4294967295, 1) == 4294967295); + assert(div_ceil_u64(4294967295, 2) == 2147483648); + assert(div_ceil_u64(4294967295, 3) == 1431655765); + assert(div_ceil_u64(4294967295, 7) == 613566757); + assert(div_ceil_u64(4294967295, 4294967295) == 1); + assert(div_ceil_u64(4294967295, 4294967296) == 1); + assert(div_ceil_u64(4294967295, 9223372036854775807) == 1); + assert(div_ceil_u64(4294967295, 9223372036854775808) == 1); + assert(div_ceil_u64(4294967295, 18446744073709551615) == 1); + assert(div_ceil_u64(4294967296, 1) == 4294967296); + assert(div_ceil_u64(4294967296, 2) == 2147483648); + assert(div_ceil_u64(4294967296, 3) == 1431655766); + assert(div_ceil_u64(4294967296, 7) == 613566757); + assert(div_ceil_u64(4294967296, 4294967295) == 2); + assert(div_ceil_u64(4294967296, 4294967296) == 1); + assert(div_ceil_u64(4294967296, 9223372036854775807) == 1); + assert(div_ceil_u64(4294967296, 9223372036854775808) == 1); + assert(div_ceil_u64(4294967296, 18446744073709551615) == 1); + assert(div_ceil_u64(9223372036854775807, 1) == 9223372036854775807); + assert(div_ceil_u64(9223372036854775807, 2) == 4611686018427387904); + assert(div_ceil_u64(9223372036854775807, 3) == 3074457345618258603); + assert(div_ceil_u64(9223372036854775807, 7) == 1317624576693539401); + assert(div_ceil_u64(9223372036854775807, 4294967295) == 2147483649); + assert(div_ceil_u64(9223372036854775807, 4294967296) == 2147483648); + assert(div_ceil_u64(9223372036854775807, 9223372036854775807) == 1); + assert(div_ceil_u64(9223372036854775807, 9223372036854775808) == 1); + assert(div_ceil_u64(9223372036854775807, 18446744073709551615) == 1); + assert(div_ceil_u64(9223372036854775808, 1) == 9223372036854775808); + assert(div_ceil_u64(9223372036854775808, 2) == 4611686018427387904); + assert(div_ceil_u64(9223372036854775808, 3) == 3074457345618258603); + assert(div_ceil_u64(9223372036854775808, 7) == 1317624576693539402); + assert(div_ceil_u64(9223372036854775808, 4294967295) == 2147483649); + assert(div_ceil_u64(9223372036854775808, 4294967296) == 2147483648); + assert(div_ceil_u64(9223372036854775808, 9223372036854775807) == 2); + assert(div_ceil_u64(9223372036854775808, 9223372036854775808) == 1); + assert(div_ceil_u64(9223372036854775808, 18446744073709551615) == 1); + assert(div_ceil_u64(18446744073709551615, 1) == 18446744073709551615); + assert(div_ceil_u64(18446744073709551615, 2) == 9223372036854775808); + assert(div_ceil_u64(18446744073709551615, 3) == 6148914691236517205); + assert(div_ceil_u64(18446744073709551615, 7) == 2635249153387078803); + assert(div_ceil_u64(18446744073709551615, 4294967295) == 4294967297); + assert(div_ceil_u64(18446744073709551615, 4294967296) == 4294967296); + assert(div_ceil_u64(18446744073709551615, 9223372036854775807) == 3); + assert(div_ceil_u64(18446744073709551615, 9223372036854775808) == 2); + assert(div_ceil_u64(18446744073709551615, 18446744073709551615) == 1); +} + +/// div_ceil of usize: every expected value was printed by rustc 1.99 running `a.div_ceil(b)` on the same inputs; +/// the pairs are the edge values taken pairwise, divisor 0 left out (it panics). +test std_div_ceil_of_usize_is_rusts { + assert(div_ceil_usize(0, 1) == 0); + assert(div_ceil_usize(0, 2) == 0); + assert(div_ceil_usize(0, 3) == 0); + assert(div_ceil_usize(0, 7) == 0); + assert(div_ceil_usize(0, 4294967295) == 0); + assert(div_ceil_usize(0, 4294967296) == 0); + assert(div_ceil_usize(0, 9223372036854775807) == 0); + assert(div_ceil_usize(0, 9223372036854775808) == 0); + assert(div_ceil_usize(0, 18446744073709551615) == 0); + assert(div_ceil_usize(1, 1) == 1); + assert(div_ceil_usize(1, 2) == 1); + assert(div_ceil_usize(1, 3) == 1); + assert(div_ceil_usize(1, 7) == 1); + assert(div_ceil_usize(1, 4294967295) == 1); + assert(div_ceil_usize(1, 4294967296) == 1); + assert(div_ceil_usize(1, 9223372036854775807) == 1); + assert(div_ceil_usize(1, 9223372036854775808) == 1); + assert(div_ceil_usize(1, 18446744073709551615) == 1); + assert(div_ceil_usize(2, 1) == 2); + assert(div_ceil_usize(2, 2) == 1); + assert(div_ceil_usize(2, 3) == 1); + assert(div_ceil_usize(2, 7) == 1); + assert(div_ceil_usize(2, 4294967295) == 1); + assert(div_ceil_usize(2, 4294967296) == 1); + assert(div_ceil_usize(2, 9223372036854775807) == 1); + assert(div_ceil_usize(2, 9223372036854775808) == 1); + assert(div_ceil_usize(2, 18446744073709551615) == 1); + assert(div_ceil_usize(3, 1) == 3); + assert(div_ceil_usize(3, 2) == 2); + assert(div_ceil_usize(3, 3) == 1); + assert(div_ceil_usize(3, 7) == 1); + assert(div_ceil_usize(3, 4294967295) == 1); + assert(div_ceil_usize(3, 4294967296) == 1); + assert(div_ceil_usize(3, 9223372036854775807) == 1); + assert(div_ceil_usize(3, 9223372036854775808) == 1); + assert(div_ceil_usize(3, 18446744073709551615) == 1); + assert(div_ceil_usize(7, 1) == 7); + assert(div_ceil_usize(7, 2) == 4); + assert(div_ceil_usize(7, 3) == 3); + assert(div_ceil_usize(7, 7) == 1); + assert(div_ceil_usize(7, 4294967295) == 1); + assert(div_ceil_usize(7, 4294967296) == 1); + assert(div_ceil_usize(7, 9223372036854775807) == 1); + assert(div_ceil_usize(7, 9223372036854775808) == 1); + assert(div_ceil_usize(7, 18446744073709551615) == 1); + assert(div_ceil_usize(4294967295, 1) == 4294967295); + assert(div_ceil_usize(4294967295, 2) == 2147483648); + assert(div_ceil_usize(4294967295, 3) == 1431655765); + assert(div_ceil_usize(4294967295, 7) == 613566757); + assert(div_ceil_usize(4294967295, 4294967295) == 1); + assert(div_ceil_usize(4294967295, 4294967296) == 1); + assert(div_ceil_usize(4294967295, 9223372036854775807) == 1); + assert(div_ceil_usize(4294967295, 9223372036854775808) == 1); + assert(div_ceil_usize(4294967295, 18446744073709551615) == 1); + assert(div_ceil_usize(4294967296, 1) == 4294967296); + assert(div_ceil_usize(4294967296, 2) == 2147483648); + assert(div_ceil_usize(4294967296, 3) == 1431655766); + assert(div_ceil_usize(4294967296, 7) == 613566757); + assert(div_ceil_usize(4294967296, 4294967295) == 2); + assert(div_ceil_usize(4294967296, 4294967296) == 1); + assert(div_ceil_usize(4294967296, 9223372036854775807) == 1); + assert(div_ceil_usize(4294967296, 9223372036854775808) == 1); + assert(div_ceil_usize(4294967296, 18446744073709551615) == 1); + assert(div_ceil_usize(9223372036854775807, 1) == 9223372036854775807); + assert(div_ceil_usize(9223372036854775807, 2) == 4611686018427387904); + assert(div_ceil_usize(9223372036854775807, 3) == 3074457345618258603); + assert(div_ceil_usize(9223372036854775807, 7) == 1317624576693539401); + assert(div_ceil_usize(9223372036854775807, 4294967295) == 2147483649); + assert(div_ceil_usize(9223372036854775807, 4294967296) == 2147483648); + assert(div_ceil_usize(9223372036854775807, 9223372036854775807) == 1); + assert(div_ceil_usize(9223372036854775807, 9223372036854775808) == 1); + assert(div_ceil_usize(9223372036854775807, 18446744073709551615) == 1); + assert(div_ceil_usize(9223372036854775808, 1) == 9223372036854775808); + assert(div_ceil_usize(9223372036854775808, 2) == 4611686018427387904); + assert(div_ceil_usize(9223372036854775808, 3) == 3074457345618258603); + assert(div_ceil_usize(9223372036854775808, 7) == 1317624576693539402); + assert(div_ceil_usize(9223372036854775808, 4294967295) == 2147483649); + assert(div_ceil_usize(9223372036854775808, 4294967296) == 2147483648); + assert(div_ceil_usize(9223372036854775808, 9223372036854775807) == 2); + assert(div_ceil_usize(9223372036854775808, 9223372036854775808) == 1); + assert(div_ceil_usize(9223372036854775808, 18446744073709551615) == 1); + assert(div_ceil_usize(18446744073709551615, 1) == 18446744073709551615); + assert(div_ceil_usize(18446744073709551615, 2) == 9223372036854775808); + assert(div_ceil_usize(18446744073709551615, 3) == 6148914691236517205); + assert(div_ceil_usize(18446744073709551615, 7) == 2635249153387078803); + assert(div_ceil_usize(18446744073709551615, 4294967295) == 4294967297); + assert(div_ceil_usize(18446744073709551615, 4294967296) == 4294967296); + assert(div_ceil_usize(18446744073709551615, 9223372036854775807) == 3); + assert(div_ceil_usize(18446744073709551615, 9223372036854775808) == 2); + assert(div_ceil_usize(18446744073709551615, 18446744073709551615) == 1); +} + +/// f64 sqrt, is_finite and to_bits: every expected value was printed by rustc 1.99 running the method on the same bit +/// pattern (0, -0, +-1, halves, MAX, MIN_POSITIVE, a subnormal, both infinities, quiet and signalling NaNs). A NaN result is +/// tested as NaN (x != x): its sign and payload are the CPU's, not Rust's. Inputs enter through from_bits_f64. +test std_f64_sqrt_is_finite_and_to_bits_are_rusts { + assert(to_bits_f64(from_bits_f64(0x0000000000000000)) == 0x0000000000000000); + assert(to_bits_f64(0.0) == 0x0000000000000000); + assert(is_finite_f64(from_bits_f64(0x0000000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x0000000000000000))) == 0x0000000000000000); + assert(to_bits_f64(from_bits_f64(0x8000000000000000)) == 0x8000000000000000); + assert(to_bits_f64(-0.0) == 0x8000000000000000); + assert(is_finite_f64(from_bits_f64(0x8000000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x8000000000000000))) == 0x8000000000000000); + assert(to_bits_f64(from_bits_f64(0x3FF0000000000000)) == 0x3FF0000000000000); + assert(to_bits_f64(1.0) == 0x3FF0000000000000); + assert(is_finite_f64(from_bits_f64(0x3FF0000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x3FF0000000000000))) == 0x3FF0000000000000); + assert(to_bits_f64(from_bits_f64(0xBFF0000000000000)) == 0xBFF0000000000000); + assert(to_bits_f64(-1.0) == 0xBFF0000000000000); + assert(is_finite_f64(from_bits_f64(0xBFF0000000000000)) == true); + assert(@sqrt(from_bits_f64(0xBFF0000000000000)) != @sqrt(from_bits_f64(0xBFF0000000000000))); + assert(to_bits_f64(from_bits_f64(0x3FE0000000000000)) == 0x3FE0000000000000); + assert(to_bits_f64(0.5) == 0x3FE0000000000000); + assert(is_finite_f64(from_bits_f64(0x3FE0000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x3FE0000000000000))) == 0x3FE6A09E667F3BCD); + assert(to_bits_f64(from_bits_f64(0x4000000000000000)) == 0x4000000000000000); + assert(to_bits_f64(2.0) == 0x4000000000000000); + assert(is_finite_f64(from_bits_f64(0x4000000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x4000000000000000))) == 0x3FF6A09E667F3BCD); + assert(to_bits_f64(from_bits_f64(0x3FF8000000000000)) == 0x3FF8000000000000); + assert(to_bits_f64(1.5) == 0x3FF8000000000000); + assert(is_finite_f64(from_bits_f64(0x3FF8000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x3FF8000000000000))) == 0x3FF3988E1409212E); + assert(to_bits_f64(from_bits_f64(0x4059100000000000)) == 0x4059100000000000); + assert(to_bits_f64(100.25) == 0x4059100000000000); + assert(is_finite_f64(from_bits_f64(0x4059100000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x4059100000000000))) == 0x4024066560954A8F); + assert(to_bits_f64(from_bits_f64(0x4010000000000000)) == 0x4010000000000000); + assert(to_bits_f64(4.0) == 0x4010000000000000); + assert(is_finite_f64(from_bits_f64(0x4010000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x4010000000000000))) == 0x4000000000000000); + assert(to_bits_f64(from_bits_f64(0x3FD0000000000000)) == 0x3FD0000000000000); + assert(to_bits_f64(0.25) == 0x3FD0000000000000); + assert(is_finite_f64(from_bits_f64(0x3FD0000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x3FD0000000000000))) == 0x3FE0000000000000); + assert(to_bits_f64(from_bits_f64(0x4014000000000000)) == 0x4014000000000000); + assert(to_bits_f64(5.0) == 0x4014000000000000); + assert(is_finite_f64(from_bits_f64(0x4014000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x4014000000000000))) == 0x4001E3779B97F4A8); + assert(to_bits_f64(from_bits_f64(0x400921FB54442D18)) == 0x400921FB54442D18); + assert(to_bits_f64(3.141592653589793) == 0x400921FB54442D18); + assert(is_finite_f64(from_bits_f64(0x400921FB54442D18)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x400921FB54442D18))) == 0x3FFC5BF891B4EF6A); + assert(to_bits_f64(from_bits_f64(0x7FEFFFFFFFFFFFFF)) == 0x7FEFFFFFFFFFFFFF); + assert(is_finite_f64(from_bits_f64(0x7FEFFFFFFFFFFFFF)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x7FEFFFFFFFFFFFFF))) == 0x5FEFFFFFFFFFFFFF); + assert(to_bits_f64(from_bits_f64(0xFFEFFFFFFFFFFFFF)) == 0xFFEFFFFFFFFFFFFF); + assert(is_finite_f64(from_bits_f64(0xFFEFFFFFFFFFFFFF)) == true); + assert(@sqrt(from_bits_f64(0xFFEFFFFFFFFFFFFF)) != @sqrt(from_bits_f64(0xFFEFFFFFFFFFFFFF))); + assert(to_bits_f64(from_bits_f64(0x0010000000000000)) == 0x0010000000000000); + assert(is_finite_f64(from_bits_f64(0x0010000000000000)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x0010000000000000))) == 0x2000000000000000); + assert(to_bits_f64(from_bits_f64(0x0000000000000001)) == 0x0000000000000001); + assert(is_finite_f64(from_bits_f64(0x0000000000000001)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x0000000000000001))) == 0x1E60000000000000); + assert(to_bits_f64(from_bits_f64(0x000FFFFFFFFFFFFF)) == 0x000FFFFFFFFFFFFF); + assert(is_finite_f64(from_bits_f64(0x000FFFFFFFFFFFFF)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x000FFFFFFFFFFFFF))) == 0x1FFFFFFFFFFFFFFF); + assert(to_bits_f64(from_bits_f64(0x7FF0000000000000)) == 0x7FF0000000000000); + assert(is_finite_f64(from_bits_f64(0x7FF0000000000000)) == false); + assert(to_bits_f64(@sqrt(from_bits_f64(0x7FF0000000000000))) == 0x7FF0000000000000); + assert(to_bits_f64(from_bits_f64(0xFFF0000000000000)) == 0xFFF0000000000000); + assert(is_finite_f64(from_bits_f64(0xFFF0000000000000)) == false); + assert(@sqrt(from_bits_f64(0xFFF0000000000000)) != @sqrt(from_bits_f64(0xFFF0000000000000))); + assert(to_bits_f64(from_bits_f64(0x7FF8000000000000)) == 0x7FF8000000000000); + assert(is_finite_f64(from_bits_f64(0x7FF8000000000000)) == false); + assert(@sqrt(from_bits_f64(0x7FF8000000000000)) != @sqrt(from_bits_f64(0x7FF8000000000000))); + assert(to_bits_f64(from_bits_f64(0xFFF8000000000000)) == 0xFFF8000000000000); + assert(is_finite_f64(from_bits_f64(0xFFF8000000000000)) == false); + assert(@sqrt(from_bits_f64(0xFFF8000000000000)) != @sqrt(from_bits_f64(0xFFF8000000000000))); + assert(to_bits_f64(from_bits_f64(0x7FF0000000000001)) == 0x7FF0000000000001); + assert(is_finite_f64(from_bits_f64(0x7FF0000000000001)) == false); + assert(@sqrt(from_bits_f64(0x7FF0000000000001)) != @sqrt(from_bits_f64(0x7FF0000000000001))); + assert(to_bits_f64(from_bits_f64(0x7E37E43C8800759C)) == 0x7E37E43C8800759C); + assert(is_finite_f64(from_bits_f64(0x7E37E43C8800759C)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x7E37E43C8800759C))) == 0x5F138D352E5096AF); + assert(to_bits_f64(from_bits_f64(0x1A56E1FC2F8F359C)) == 0x1A56E1FC2F8F359C); + assert(is_finite_f64(from_bits_f64(0x1A56E1FC2F8F359C)) == true); + assert(to_bits_f64(@sqrt(from_bits_f64(0x1A56E1FC2F8F359C))) == 0x2D232265FE206D57); +} + +/// f32 sqrt, is_finite and to_bits, as above for binary32 (from_bits_f32 builds the input). +test std_f32_sqrt_is_finite_and_to_bits_are_rusts { + assert(to_bits_f32(from_bits_f32(0x00000000)) == 0x00000000); + assert(to_bits_f32(0.0) == 0x00000000); + assert(is_finite_f32(from_bits_f32(0x00000000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x00000000))) == 0x00000000); + assert(to_bits_f32(from_bits_f32(0x80000000)) == 0x80000000); + assert(to_bits_f32(-0.0) == 0x80000000); + assert(is_finite_f32(from_bits_f32(0x80000000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x80000000))) == 0x80000000); + assert(to_bits_f32(from_bits_f32(0x3F800000)) == 0x3F800000); + assert(to_bits_f32(1.0) == 0x3F800000); + assert(is_finite_f32(from_bits_f32(0x3F800000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x3F800000))) == 0x3F800000); + assert(to_bits_f32(from_bits_f32(0xBF800000)) == 0xBF800000); + assert(to_bits_f32(-1.0) == 0xBF800000); + assert(is_finite_f32(from_bits_f32(0xBF800000)) == true); + assert(@sqrt(from_bits_f32(0xBF800000)) != @sqrt(from_bits_f32(0xBF800000))); + assert(to_bits_f32(from_bits_f32(0x3F000000)) == 0x3F000000); + assert(to_bits_f32(0.5) == 0x3F000000); + assert(is_finite_f32(from_bits_f32(0x3F000000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x3F000000))) == 0x3F3504F3); + assert(to_bits_f32(from_bits_f32(0x40000000)) == 0x40000000); + assert(to_bits_f32(2.0) == 0x40000000); + assert(is_finite_f32(from_bits_f32(0x40000000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x40000000))) == 0x3FB504F3); + assert(to_bits_f32(from_bits_f32(0x3FC00000)) == 0x3FC00000); + assert(to_bits_f32(1.5) == 0x3FC00000); + assert(is_finite_f32(from_bits_f32(0x3FC00000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x3FC00000))) == 0x3F9CC471); + assert(to_bits_f32(from_bits_f32(0x42C80000)) == 0x42C80000); + assert(to_bits_f32(100.0) == 0x42C80000); + assert(is_finite_f32(from_bits_f32(0x42C80000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x42C80000))) == 0x41200000); + assert(to_bits_f32(from_bits_f32(0x40800000)) == 0x40800000); + assert(to_bits_f32(4.0) == 0x40800000); + assert(is_finite_f32(from_bits_f32(0x40800000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x40800000))) == 0x40000000); + assert(to_bits_f32(from_bits_f32(0x3E800000)) == 0x3E800000); + assert(to_bits_f32(0.25) == 0x3E800000); + assert(is_finite_f32(from_bits_f32(0x3E800000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x3E800000))) == 0x3F000000); + assert(to_bits_f32(from_bits_f32(0x40A00000)) == 0x40A00000); + assert(to_bits_f32(5.0) == 0x40A00000); + assert(is_finite_f32(from_bits_f32(0x40A00000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x40A00000))) == 0x400F1BBD); + assert(to_bits_f32(from_bits_f32(0x40490FDB)) == 0x40490FDB); + assert(is_finite_f32(from_bits_f32(0x40490FDB)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x40490FDB))) == 0x3FE2DFC5); + assert(to_bits_f32(from_bits_f32(0x7F7FFFFF)) == 0x7F7FFFFF); + assert(is_finite_f32(from_bits_f32(0x7F7FFFFF)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x7F7FFFFF))) == 0x5F7FFFFF); + assert(to_bits_f32(from_bits_f32(0xFF7FFFFF)) == 0xFF7FFFFF); + assert(is_finite_f32(from_bits_f32(0xFF7FFFFF)) == true); + assert(@sqrt(from_bits_f32(0xFF7FFFFF)) != @sqrt(from_bits_f32(0xFF7FFFFF))); + assert(to_bits_f32(from_bits_f32(0x00800000)) == 0x00800000); + assert(is_finite_f32(from_bits_f32(0x00800000)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x00800000))) == 0x20000000); + assert(to_bits_f32(from_bits_f32(0x00000001)) == 0x00000001); + assert(is_finite_f32(from_bits_f32(0x00000001)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x00000001))) == 0x1A3504F3); + assert(to_bits_f32(from_bits_f32(0x007FFFFF)) == 0x007FFFFF); + assert(is_finite_f32(from_bits_f32(0x007FFFFF)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x007FFFFF))) == 0x1FFFFFFF); + assert(to_bits_f32(from_bits_f32(0x7F800000)) == 0x7F800000); + assert(is_finite_f32(from_bits_f32(0x7F800000)) == false); + assert(to_bits_f32(@sqrt(from_bits_f32(0x7F800000))) == 0x7F800000); + assert(to_bits_f32(from_bits_f32(0xFF800000)) == 0xFF800000); + assert(is_finite_f32(from_bits_f32(0xFF800000)) == false); + assert(@sqrt(from_bits_f32(0xFF800000)) != @sqrt(from_bits_f32(0xFF800000))); + assert(to_bits_f32(from_bits_f32(0x7FC00000)) == 0x7FC00000); + assert(is_finite_f32(from_bits_f32(0x7FC00000)) == false); + assert(@sqrt(from_bits_f32(0x7FC00000)) != @sqrt(from_bits_f32(0x7FC00000))); + assert(to_bits_f32(from_bits_f32(0xFFC00000)) == 0xFFC00000); + assert(is_finite_f32(from_bits_f32(0xFFC00000)) == false); + assert(@sqrt(from_bits_f32(0xFFC00000)) != @sqrt(from_bits_f32(0xFFC00000))); + assert(to_bits_f32(from_bits_f32(0x7F800001)) == 0x7F800001); + assert(is_finite_f32(from_bits_f32(0x7F800001)) == false); + assert(@sqrt(from_bits_f32(0x7F800001)) != @sqrt(from_bits_f32(0x7F800001))); + assert(to_bits_f32(from_bits_f32(0x7149F2CA)) == 0x7149F2CA); + assert(is_finite_f32(from_bits_f32(0x7149F2CA)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x7149F2CA))) == 0x58635FA9); + assert(to_bits_f32(from_bits_f32(0x0DA24260)) == 0x0DA24260); + assert(is_finite_f32(from_bits_f32(0x0DA24260)) == true); + assert(to_bits_f32(@sqrt(from_bits_f32(0x0DA24260))) == 0x26901D7D); +} + +/// ASCII methods: every expected value was printed by rustc 1.99 running the method on the same input. The bytes are the +/// edges of the letter ranges (63, 64, 65, 90, 91, 96, 97, 122, 123), a digit, control, DEL (127) and the first and last byte +/// above 127; then all 256 bytes at once through a checksum (the sum of (b + 1) * f(b), as u64), which rustc printed too. +test std_ascii_methods_are_rusts { + assert(is_ascii_u8(0) == true); + assert(to_ascii_lowercase_u8(0) == 0); + assert(to_ascii_uppercase_u8(0) == 0); + assert(is_ascii_u8(9) == true); + assert(to_ascii_lowercase_u8(9) == 9); + assert(to_ascii_uppercase_u8(9) == 9); + assert(is_ascii_u8(32) == true); + assert(to_ascii_lowercase_u8(32) == 32); + assert(to_ascii_uppercase_u8(32) == 32); + assert(is_ascii_u8(47) == true); + assert(to_ascii_lowercase_u8(47) == 47); + assert(to_ascii_uppercase_u8(47) == 47); + assert(is_ascii_u8(48) == true); + assert(to_ascii_lowercase_u8(48) == 48); + assert(to_ascii_uppercase_u8(48) == 48); + assert(is_ascii_u8(57) == true); + assert(to_ascii_lowercase_u8(57) == 57); + assert(to_ascii_uppercase_u8(57) == 57); + assert(is_ascii_u8(63) == true); + assert(to_ascii_lowercase_u8(63) == 63); + assert(to_ascii_uppercase_u8(63) == 63); + assert(is_ascii_u8(64) == true); + assert(to_ascii_lowercase_u8(64) == 64); + assert(to_ascii_uppercase_u8(64) == 64); + assert(is_ascii_u8(65) == true); + assert(to_ascii_lowercase_u8(65) == 97); + assert(to_ascii_uppercase_u8(65) == 65); + assert(is_ascii_u8(90) == true); + assert(to_ascii_lowercase_u8(90) == 122); + assert(to_ascii_uppercase_u8(90) == 90); + assert(is_ascii_u8(91) == true); + assert(to_ascii_lowercase_u8(91) == 91); + assert(to_ascii_uppercase_u8(91) == 91); + assert(is_ascii_u8(96) == true); + assert(to_ascii_lowercase_u8(96) == 96); + assert(to_ascii_uppercase_u8(96) == 96); + assert(is_ascii_u8(97) == true); + assert(to_ascii_lowercase_u8(97) == 97); + assert(to_ascii_uppercase_u8(97) == 65); + assert(is_ascii_u8(122) == true); + assert(to_ascii_lowercase_u8(122) == 122); + assert(to_ascii_uppercase_u8(122) == 90); + assert(is_ascii_u8(123) == true); + assert(to_ascii_lowercase_u8(123) == 123); + assert(to_ascii_uppercase_u8(123) == 123); + assert(is_ascii_u8(127) == true); + assert(to_ascii_lowercase_u8(127) == 127); + assert(to_ascii_uppercase_u8(127) == 127); + assert(is_ascii_u8(128) == false); + assert(to_ascii_lowercase_u8(128) == 128); + assert(to_ascii_uppercase_u8(128) == 128); + assert(is_ascii_u8(255) == false); + assert(to_ascii_lowercase_u8(255) == 255); + assert(to_ascii_uppercase_u8(255) == 255); + var s_is : u64 = 0; + var s_lo : u64 = 0; + var s_up : u64 = 0; + var n_ascii : u64 = 0; + var b : u16 = 0; + while (b < 256) { + const x : u8 = b as u8; + if (is_ascii_u8(x)) { s_is = s_is + ((b as u64) + 1); n_ascii = n_ascii + 1; } + s_lo = s_lo + ((b as u64) + 1) * (to_ascii_lowercase_u8(x) as u64); + s_up = s_up + ((b as u64) + 1) * (to_ascii_uppercase_u8(x) as u64); + b = b + 1; + } + assert(n_ascii == 128); + assert(s_is == 8256); + assert(s_lo == 5657632); + assert(s_up == 5500384); + assert(is_ascii_text("") == true); + assert(is_ascii_text("a") == true); + assert(is_ascii_text("Hello, world 0123456789 ~") == true); + const t1 : [4]u8 = [104, 105, 127, 10]; + assert(is_ascii_text(t1[0 .. 4]) == true); + const t2 : [3]u8 = [104, 128, 105]; + assert(is_ascii_text(t2[0 .. 3]) == false); + const t3 : [3]u8 = [104, 105, 255]; + assert(is_ascii_text(t3[0 .. 3]) == false); + const t4 : [1]u8 = [128]; + assert(is_ascii_text(t4[0 .. 1]) == false); + assert(is_ascii_text(t2[0 .. 1]) == true); + assert(is_ascii_text(t2[0 .. 0]) == true); +} + +/// [u8]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_u8_is_rusts { + const a : [5]u8 = [0, 1, 127, 128, 255]; + assert(get_u8(a[0 .. 5], 0).? == 0); + assert(get_u8(a[0 .. 5], 1).? == 1); + assert(get_u8(a[0 .. 5], 2).? == 127); + assert(get_u8(a[0 .. 5], 4).? == 255); + assert(get_u8(a[0 .. 5], 5) == null); + assert(get_u8(a[0 .. 5], 6) == null); + assert(get_u8(a[0 .. 5], 1000) == null); + assert(get_u8(a[0 .. 5], 18446744073709551615) == null); + assert(get_u8(a[0 .. 0], 0) == null); +} + +/// [u16]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_u16_is_rusts { + const a : [4]u16 = [0, 1, 32768, 65535]; + assert(get_u16(a[0 .. 4], 0).? == 0); + assert(get_u16(a[0 .. 4], 1).? == 1); + assert(get_u16(a[0 .. 4], 2).? == 32768); + assert(get_u16(a[0 .. 4], 3).? == 65535); + assert(get_u16(a[0 .. 4], 4) == null); + assert(get_u16(a[0 .. 4], 5) == null); + assert(get_u16(a[0 .. 4], 1000) == null); + assert(get_u16(a[0 .. 4], 18446744073709551615) == null); + assert(get_u16(a[0 .. 0], 0) == null); +} + +/// [u32]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_u32_is_rusts { + const a : [4]u32 = [0, 1, 2147483648, 4294967295]; + assert(get_u32(a[0 .. 4], 0).? == 0); + assert(get_u32(a[0 .. 4], 1).? == 1); + assert(get_u32(a[0 .. 4], 2).? == 2147483648); + assert(get_u32(a[0 .. 4], 3).? == 4294967295); + assert(get_u32(a[0 .. 4], 4) == null); + assert(get_u32(a[0 .. 4], 5) == null); + assert(get_u32(a[0 .. 4], 1000) == null); + assert(get_u32(a[0 .. 4], 18446744073709551615) == null); + assert(get_u32(a[0 .. 0], 0) == null); +} + +/// [u64]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_u64_is_rusts { + const a : [4]u64 = [0, 1, 9223372036854775808, 18446744073709551615]; + assert(get_u64(a[0 .. 4], 0).? == 0); + assert(get_u64(a[0 .. 4], 1).? == 1); + assert(get_u64(a[0 .. 4], 2).? == 9223372036854775808); + assert(get_u64(a[0 .. 4], 3).? == 18446744073709551615); + assert(get_u64(a[0 .. 4], 4) == null); + assert(get_u64(a[0 .. 4], 5) == null); + assert(get_u64(a[0 .. 4], 1000) == null); + assert(get_u64(a[0 .. 4], 18446744073709551615) == null); + assert(get_u64(a[0 .. 0], 0) == null); +} + +/// [usize]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_usize_is_rusts { + const a : [4]usize = [0, 1, 9223372036854775808, 18446744073709551615]; + assert(get_usize(a[0 .. 4], 0).? == 0); + assert(get_usize(a[0 .. 4], 1).? == 1); + assert(get_usize(a[0 .. 4], 2).? == 9223372036854775808); + assert(get_usize(a[0 .. 4], 3).? == 18446744073709551615); + assert(get_usize(a[0 .. 4], 4) == null); + assert(get_usize(a[0 .. 4], 5) == null); + assert(get_usize(a[0 .. 4], 1000) == null); + assert(get_usize(a[0 .. 4], 18446744073709551615) == null); + assert(get_usize(a[0 .. 0], 0) == null); +} + +/// [i8]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_i8_is_rusts { + const a : [5]i8 = [-128, -1, 0, 1, 127]; + assert(get_i8(a[0 .. 5], 0).? == -128); + assert(get_i8(a[0 .. 5], 1).? == -1); + assert(get_i8(a[0 .. 5], 2).? == 0); + assert(get_i8(a[0 .. 5], 4).? == 127); + assert(get_i8(a[0 .. 5], 5) == null); + assert(get_i8(a[0 .. 5], 6) == null); + assert(get_i8(a[0 .. 5], 1000) == null); + assert(get_i8(a[0 .. 5], 18446744073709551615) == null); + assert(get_i8(a[0 .. 0], 0) == null); +} + +/// [i16]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_i16_is_rusts { + const a : [5]i16 = [-32768, -1, 0, 1, 32767]; + assert(get_i16(a[0 .. 5], 0).? == -32768); + assert(get_i16(a[0 .. 5], 1).? == -1); + assert(get_i16(a[0 .. 5], 2).? == 0); + assert(get_i16(a[0 .. 5], 4).? == 32767); + assert(get_i16(a[0 .. 5], 5) == null); + assert(get_i16(a[0 .. 5], 6) == null); + assert(get_i16(a[0 .. 5], 1000) == null); + assert(get_i16(a[0 .. 5], 18446744073709551615) == null); + assert(get_i16(a[0 .. 0], 0) == null); +} + +/// [i32]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_i32_is_rusts { + const a : [5]i32 = [I32_MIN, -1, 0, 1, 2147483647]; + assert(get_i32(a[0 .. 5], 0).? == I32_MIN); + assert(get_i32(a[0 .. 5], 1).? == -1); + assert(get_i32(a[0 .. 5], 2).? == 0); + assert(get_i32(a[0 .. 5], 4).? == 2147483647); + assert(get_i32(a[0 .. 5], 5) == null); + assert(get_i32(a[0 .. 5], 6) == null); + assert(get_i32(a[0 .. 5], 1000) == null); + assert(get_i32(a[0 .. 5], 18446744073709551615) == null); + assert(get_i32(a[0 .. 0], 0) == null); +} + +/// [i64]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_i64_is_rusts { + const a : [5]i64 = [I64_MIN, -1, 0, 1, 9223372036854775807]; + assert(get_i64(a[0 .. 5], 0).? == I64_MIN); + assert(get_i64(a[0 .. 5], 1).? == -1); + assert(get_i64(a[0 .. 5], 2).? == 0); + assert(get_i64(a[0 .. 5], 4).? == 9223372036854775807); + assert(get_i64(a[0 .. 5], 5) == null); + assert(get_i64(a[0 .. 5], 6) == null); + assert(get_i64(a[0 .. 5], 1000) == null); + assert(get_i64(a[0 .. 5], 18446744073709551615) == null); + assert(get_i64(a[0 .. 0], 0) == null); +} + +/// [f32]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_f32_is_rusts { + const a : [5]f32 = [0.0, -0.0, 1.5, -2.25, 100.0]; + assert(get_f32(a[0 .. 5], 0).? == 0.0); + assert(get_f32(a[0 .. 5], 1).? == -0.0); + assert(get_f32(a[0 .. 5], 2).? == 1.5); + assert(get_f32(a[0 .. 5], 4).? == 100.0); + assert(get_f32(a[0 .. 5], 5) == null); + assert(get_f32(a[0 .. 5], 6) == null); + assert(get_f32(a[0 .. 5], 1000) == null); + assert(get_f32(a[0 .. 5], 18446744073709551615) == null); + assert(get_f32(a[0 .. 0], 0) == null); +} + +/// [f64]::get(i): every expected value was printed by rustc 1.99 running `a.get(i)` on the same array, for an index in range, at the +/// last element, one past it, far past it and usize::MAX; an empty slice answers None for 0. +test std_get_of_f64_is_rusts { + const a : [5]f64 = [0.0, -0.0, 1.5, -2.25, 100.0]; + assert(get_f64(a[0 .. 5], 0).? == 0.0); + assert(get_f64(a[0 .. 5], 1).? == -0.0); + assert(get_f64(a[0 .. 5], 2).? == 1.5); + assert(get_f64(a[0 .. 5], 4).? == 100.0); + assert(get_f64(a[0 .. 5], 5) == null); + assert(get_f64(a[0 .. 5], 6) == null); + assert(get_f64(a[0 .. 5], 1000) == null); + assert(get_f64(a[0 .. 5], 18446744073709551615) == null); + assert(get_f64(a[0 .. 0], 0) == null); +} + +/// [u16]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_u16_is_rusts { + const a : [4]u16 = [7, 0, 65535, 300]; + assert(contains_u16(a[0 .. 4], 7) == true); + assert(contains_u16(a[0 .. 4], 0) == true); + assert(contains_u16(a[0 .. 4], 65535) == true); + assert(contains_u16(a[0 .. 4], 300) == true); + assert(contains_u16(a[0 .. 4], 1) == false); + assert(contains_u16(a[0 .. 4], 299) == false); + assert(contains_u16(a[0 .. 4], 301) == false); + assert(contains_u16(a[0 .. 4], 32768) == false); + assert(contains_u16(a[0 .. 0], 7) == false); +} + +/// [u32]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_u32_is_rusts { + const a : [4]u32 = [7, 0, 4294967295, 65536]; + assert(contains_u32(a[0 .. 4], 7) == true); + assert(contains_u32(a[0 .. 4], 0) == true); + assert(contains_u32(a[0 .. 4], 4294967295) == true); + assert(contains_u32(a[0 .. 4], 65536) == true); + assert(contains_u32(a[0 .. 4], 1) == false); + assert(contains_u32(a[0 .. 4], 65535) == false); + assert(contains_u32(a[0 .. 4], 65537) == false); + assert(contains_u32(a[0 .. 4], 2147483648) == false); + assert(contains_u32(a[0 .. 0], 7) == false); +} + +/// [u64]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_u64_is_rusts { + const a : [4]u64 = [7, 0, 18446744073709551615, 4294967296]; + assert(contains_u64(a[0 .. 4], 7) == true); + assert(contains_u64(a[0 .. 4], 0) == true); + assert(contains_u64(a[0 .. 4], 18446744073709551615) == true); + assert(contains_u64(a[0 .. 4], 4294967296) == true); + assert(contains_u64(a[0 .. 4], 1) == false); + assert(contains_u64(a[0 .. 4], 4294967295) == false); + assert(contains_u64(a[0 .. 4], 4294967297) == false); + assert(contains_u64(a[0 .. 4], 9223372036854775808) == false); + assert(contains_u64(a[0 .. 0], 7) == false); +} + +/// [usize]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_usize_is_rusts { + const a : [4]usize = [7, 0, 18446744073709551615, 4294967296]; + assert(contains_usize(a[0 .. 4], 7) == true); + assert(contains_usize(a[0 .. 4], 0) == true); + assert(contains_usize(a[0 .. 4], 18446744073709551615) == true); + assert(contains_usize(a[0 .. 4], 4294967296) == true); + assert(contains_usize(a[0 .. 4], 1) == false); + assert(contains_usize(a[0 .. 4], 4294967295) == false); + assert(contains_usize(a[0 .. 4], 4294967297) == false); + assert(contains_usize(a[0 .. 4], 9223372036854775808) == false); + assert(contains_usize(a[0 .. 0], 7) == false); +} + +/// [i8]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_i8_is_rusts { + const a : [4]i8 = [7, -128, 127, -1]; + assert(contains_i8(a[0 .. 4], 7) == true); + assert(contains_i8(a[0 .. 4], -128) == true); + assert(contains_i8(a[0 .. 4], 127) == true); + assert(contains_i8(a[0 .. 4], -1) == true); + assert(contains_i8(a[0 .. 4], 0) == false); + assert(contains_i8(a[0 .. 4], 1) == false); + assert(contains_i8(a[0 .. 4], -127) == false); + assert(contains_i8(a[0 .. 4], 126) == false); + assert(contains_i8(a[0 .. 0], 7) == false); +} + +/// [i16]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_i16_is_rusts { + const a : [4]i16 = [7, -32768, 32767, -1]; + assert(contains_i16(a[0 .. 4], 7) == true); + assert(contains_i16(a[0 .. 4], -32768) == true); + assert(contains_i16(a[0 .. 4], 32767) == true); + assert(contains_i16(a[0 .. 4], -1) == true); + assert(contains_i16(a[0 .. 4], 0) == false); + assert(contains_i16(a[0 .. 4], 1) == false); + assert(contains_i16(a[0 .. 4], -32767) == false); + assert(contains_i16(a[0 .. 4], 32766) == false); + assert(contains_i16(a[0 .. 0], 7) == false); +} + +/// [i32]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_i32_is_rusts { + const a : [4]i32 = [7, I32_MIN, 2147483647, -1]; + assert(contains_i32(a[0 .. 4], 7) == true); + assert(contains_i32(a[0 .. 4], I32_MIN) == true); + assert(contains_i32(a[0 .. 4], 2147483647) == true); + assert(contains_i32(a[0 .. 4], -1) == true); + assert(contains_i32(a[0 .. 4], 0) == false); + assert(contains_i32(a[0 .. 4], 1) == false); + assert(contains_i32(a[0 .. 4], -2147483647) == false); + assert(contains_i32(a[0 .. 4], 2147483646) == false); + assert(contains_i32(a[0 .. 0], 7) == false); +} + +/// [i64]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_i64_is_rusts { + const a : [4]i64 = [7, I64_MIN, 9223372036854775807, -1]; + assert(contains_i64(a[0 .. 4], 7) == true); + assert(contains_i64(a[0 .. 4], I64_MIN) == true); + assert(contains_i64(a[0 .. 4], 9223372036854775807) == true); + assert(contains_i64(a[0 .. 4], -1) == true); + assert(contains_i64(a[0 .. 4], 0) == false); + assert(contains_i64(a[0 .. 4], 1) == false); + assert(contains_i64(a[0 .. 4], -9223372036854775807) == false); + assert(contains_i64(a[0 .. 4], 9223372036854775806) == false); + assert(contains_i64(a[0 .. 0], 7) == false); +} + +/// [f32]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_f32_is_rusts { + const a : [4]f32 = [1.5, 0.0, -2.25, 100.0]; + assert(contains_f32(a[0 .. 4], 1.5) == true); + assert(contains_f32(a[0 .. 4], 0.0) == true); + assert(contains_f32(a[0 .. 4], -0.0) == true); + assert(contains_f32(a[0 .. 4], -2.25) == true); + assert(contains_f32(a[0 .. 4], 100.0) == true); + assert(contains_f32(a[0 .. 4], 1.25) == false); + assert(contains_f32(a[0 .. 4], 3.5) == false); + assert(contains_f32(a[0 .. 0], 1.5) == false); + const nan : f32 = from_bits_f32(0x7FC00000); + const b : [2]f32 = [1.5, nan]; + assert(contains_f32(b[0 .. 2], nan) == false); + assert(contains_f32(a[0 .. 4], nan) == false); +} + +/// [f64]::contains(&x): every expected value was printed by rustc 1.99 running `a.contains(&x)` on the same array, for a +/// member (first, middle, last), a non-member and the neighbours of the edge values; the empty slice contains nothing. +test std_contains_of_f64_is_rusts { + const a : [4]f64 = [1.5, 0.0, -2.25, 100.0]; + assert(contains_f64(a[0 .. 4], 1.5) == true); + assert(contains_f64(a[0 .. 4], 0.0) == true); + assert(contains_f64(a[0 .. 4], -0.0) == true); + assert(contains_f64(a[0 .. 4], -2.25) == true); + assert(contains_f64(a[0 .. 4], 100.0) == true); + assert(contains_f64(a[0 .. 4], 1.25) == false); + assert(contains_f64(a[0 .. 4], 3.5) == false); + assert(contains_f64(a[0 .. 0], 1.5) == false); + const nan : f64 = from_bits_f64(0x7FF8000000000000); + const b : [2]f64 = [1.5, nan]; + assert(contains_f64(b[0 .. 2], nan) == false); + assert(contains_f64(a[0 .. 4], nan) == false); +} + +/// str::contains(char) of a char in a variable: every expected value was printed by rustc 1.99 running `t.contains(c)`; the +/// texts hold one-, two-, three- and four-byte chars and enter as byte arrays (t27 source is ASCII), the chars as scalar values. +test std_contains_of_a_char_is_rusts { + const t1 : [3]u8 = [97, 98, 99]; + const t2 : [11]u8 = [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]; + const t3 : [13]u8 = [104, 195, 169, 108, 108, 111, 32, 119, 195, 182, 114, 108, 100]; + const t4 : [11]u8 = [112, 114, 105, 99, 101, 58, 32, 53, 226, 130, 172]; + const t5 : [13]u8 = [115, 109, 105, 108, 101, 32, 240, 159, 152, 128, 32, 111, 107]; + const t6 : [1]u8 = [127]; + const t7 : [8]u8 = [116, 97, 98, 9, 104, 101, 114, 101]; + assert(str_contains_char(t1[0 .. 0], 97) == false); + assert(str_contains_char(t1[0 .. 0], 122) == false); + assert(str_contains_char(t1[0 .. 0], 32) == false); + assert(str_contains_char(t1[0 .. 0], 9) == false); + assert(str_contains_char(t1[0 .. 0], 127) == false); + assert(str_contains_char(t1[0 .. 0], 233) == false); + assert(str_contains_char(t1[0 .. 0], 223) == false); + assert(str_contains_char(t1[0 .. 0], 8364) == false); + assert(str_contains_char(t1[0 .. 0], 128512) == false); + assert(str_contains_char(t1[0 .. 0], 1114111) == false); + assert(str_contains_char(t1[0 .. 0], 0) == false); + assert(str_contains_char(t1[0 .. 3], 97) == true); + assert(str_contains_char(t1[0 .. 3], 122) == false); + assert(str_contains_char(t1[0 .. 3], 32) == false); + assert(str_contains_char(t1[0 .. 3], 9) == false); + assert(str_contains_char(t1[0 .. 3], 127) == false); + assert(str_contains_char(t1[0 .. 3], 233) == false); + assert(str_contains_char(t1[0 .. 3], 223) == false); + assert(str_contains_char(t1[0 .. 3], 8364) == false); + assert(str_contains_char(t1[0 .. 3], 128512) == false); + assert(str_contains_char(t1[0 .. 3], 1114111) == false); + assert(str_contains_char(t1[0 .. 3], 0) == false); + assert(str_contains_char(t2[0 .. 11], 97) == false); + assert(str_contains_char(t2[0 .. 11], 122) == false); + assert(str_contains_char(t2[0 .. 11], 32) == true); + assert(str_contains_char(t2[0 .. 11], 9) == false); + assert(str_contains_char(t2[0 .. 11], 127) == false); + assert(str_contains_char(t2[0 .. 11], 233) == false); + assert(str_contains_char(t2[0 .. 11], 223) == false); + assert(str_contains_char(t2[0 .. 11], 8364) == false); + assert(str_contains_char(t2[0 .. 11], 128512) == false); + assert(str_contains_char(t2[0 .. 11], 1114111) == false); + assert(str_contains_char(t2[0 .. 11], 0) == false); + assert(str_contains_char(t3[0 .. 13], 97) == false); + assert(str_contains_char(t3[0 .. 13], 122) == false); + assert(str_contains_char(t3[0 .. 13], 32) == true); + assert(str_contains_char(t3[0 .. 13], 9) == false); + assert(str_contains_char(t3[0 .. 13], 127) == false); + assert(str_contains_char(t3[0 .. 13], 233) == true); + assert(str_contains_char(t3[0 .. 13], 223) == false); + assert(str_contains_char(t3[0 .. 13], 8364) == false); + assert(str_contains_char(t3[0 .. 13], 128512) == false); + assert(str_contains_char(t3[0 .. 13], 1114111) == false); + assert(str_contains_char(t3[0 .. 13], 0) == false); + assert(str_contains_char(t4[0 .. 11], 97) == false); + assert(str_contains_char(t4[0 .. 11], 122) == false); + assert(str_contains_char(t4[0 .. 11], 32) == true); + assert(str_contains_char(t4[0 .. 11], 9) == false); + assert(str_contains_char(t4[0 .. 11], 127) == false); + assert(str_contains_char(t4[0 .. 11], 233) == false); + assert(str_contains_char(t4[0 .. 11], 223) == false); + assert(str_contains_char(t4[0 .. 11], 8364) == true); + assert(str_contains_char(t4[0 .. 11], 128512) == false); + assert(str_contains_char(t4[0 .. 11], 1114111) == false); + assert(str_contains_char(t4[0 .. 11], 0) == false); + assert(str_contains_char(t5[0 .. 13], 97) == false); + assert(str_contains_char(t5[0 .. 13], 122) == false); + assert(str_contains_char(t5[0 .. 13], 32) == true); + assert(str_contains_char(t5[0 .. 13], 9) == false); + assert(str_contains_char(t5[0 .. 13], 127) == false); + assert(str_contains_char(t5[0 .. 13], 233) == false); + assert(str_contains_char(t5[0 .. 13], 223) == false); + assert(str_contains_char(t5[0 .. 13], 8364) == false); + assert(str_contains_char(t5[0 .. 13], 128512) == true); + assert(str_contains_char(t5[0 .. 13], 1114111) == false); + assert(str_contains_char(t5[0 .. 13], 0) == false); + assert(str_contains_char(t6[0 .. 1], 97) == false); + assert(str_contains_char(t6[0 .. 1], 122) == false); + assert(str_contains_char(t6[0 .. 1], 32) == false); + assert(str_contains_char(t6[0 .. 1], 9) == false); + assert(str_contains_char(t6[0 .. 1], 127) == true); + assert(str_contains_char(t6[0 .. 1], 233) == false); + assert(str_contains_char(t6[0 .. 1], 223) == false); + assert(str_contains_char(t6[0 .. 1], 8364) == false); + assert(str_contains_char(t6[0 .. 1], 128512) == false); + assert(str_contains_char(t6[0 .. 1], 1114111) == false); + assert(str_contains_char(t6[0 .. 1], 0) == false); + assert(str_contains_char(t7[0 .. 8], 97) == true); + assert(str_contains_char(t7[0 .. 8], 122) == false); + assert(str_contains_char(t7[0 .. 8], 32) == false); + assert(str_contains_char(t7[0 .. 8], 9) == true); + assert(str_contains_char(t7[0 .. 8], 127) == false); + assert(str_contains_char(t7[0 .. 8], 233) == false); + assert(str_contains_char(t7[0 .. 8], 223) == false); + assert(str_contains_char(t7[0 .. 8], 8364) == false); + assert(str_contains_char(t7[0 .. 8], 128512) == false); + assert(str_contains_char(t7[0 .. 8], 1114111) == false); + assert(str_contains_char(t7[0 .. 8], 0) == false); +} + +/// Option::unwrap_or and Result::unwrap_or in the converter's inline form `if (r != null) { r.? } else { d }` (t27 has no `orelse`), +/// over the receivers the table makes (parse, find, strip_prefix): every expected value was printed by rustc 1.99 running +/// the Rust call on the same text and default. The receiver is written twice by the form, so it is a pure helper; the form stands alone as a value (a let here). +test std_unwrap_or_is_rusts { + const r1 : u8 = if (parse_u8("255") != null) { parse_u8("255").? } else { 7 }; + assert(r1 == 255); + const r2 : u8 = if (parse_u8("256") != null) { parse_u8("256").? } else { 7 }; + assert(r2 == 7); + const r3 : u8 = if (parse_u8("") != null) { parse_u8("").? } else { 9 }; + assert(r3 == 9); + const r4 : u16 = if (parse_u16("65535") != null) { parse_u16("65535").? } else { 1 }; + assert(r4 == 65535); + const r5 : u16 = if (parse_u16("-1") != null) { parse_u16("-1").? } else { 65535 }; + assert(r5 == 65535); + const r6 : u32 = if (parse_u32("4294967295") != null) { parse_u32("4294967295").? } else { 0 }; + assert(r6 == 4294967295); + const r7 : u32 = if (parse_u32("4294967296") != null) { parse_u32("4294967296").? } else { 5 }; + assert(r7 == 5); + const r8 : u64 = if (parse_u64("18446744073709551615") != null) { parse_u64("18446744073709551615").? } else { 0 }; + assert(r8 == 18446744073709551615); + const r9 : u64 = if (parse_u64("18446744073709551616") != null) { parse_u64("18446744073709551616").? } else { 18446744073709551615 }; + assert(r9 == 18446744073709551615); + const r10 : usize = if (parse_usize("42") != null) { parse_usize("42").? } else { 0 }; + assert(r10 == 42); + const r11 : usize = if (parse_usize("4x") != null) { parse_usize("4x").? } else { 3 }; + assert(r11 == 3); + const r12 : i8 = if (parse_i8("-128") != null) { parse_i8("-128").? } else { 127 }; + assert(r12 == -128); + const r13 : i8 = if (parse_i8("-129") != null) { parse_i8("-129").? } else { 5 }; + assert(r13 == 5); + const r14 : i16 = if (parse_i16("+7") != null) { parse_i16("+7").? } else { 0 }; + assert(r14 == 7); + const r15 : i32 = if (parse_i32("-2147483648") != null) { parse_i32("-2147483648").? } else { 2147483647 }; + assert(r15 == I32_MIN); + const r16 : i32 = if (parse_i32("2147483648") != null) { parse_i32("2147483648").? } else { I32_MIN }; + assert(r16 == I32_MIN); + const r17 : i64 = if (parse_i64("-9223372036854775808") != null) { parse_i64("-9223372036854775808").? } else { 5 }; + assert(r17 == I64_MIN); + const r18 : i64 = if (parse_i64("x") != null) { parse_i64("x").? } else { I64_MIN }; + assert(r18 == I64_MIN); + const f0 : usize = if (find_byte("abc", 98) != null) { find_byte("abc", 98).? } else { 99 }; + assert(f0 == 1); + const f1 : usize = if (find_byte("abc", 122) != null) { find_byte("abc", 122).? } else { 99 }; + assert(f1 == 99); + const f2 : usize = if (find_text("hello", "ll") != null) { find_text("hello", "ll").? } else { 0 }; + assert(f2 == 2); + const f3 : usize = if (find_text("hello", "lx") != null) { find_text("hello", "lx").? } else { 0 }; + assert(f3 == 0); + const t0 : []const u8 = if (strip_prefix_text("pub fn", "pub ") != null) { strip_prefix_text("pub fn", "pub ").? } else { "pub fn" }; + assert(type_text::same(t0, "fn")); + const t1 : []const u8 = if (strip_prefix_text("fn", "pub ") != null) { strip_prefix_text("fn", "pub ").? } else { "fn" }; + assert(type_text::same(t1, "fn")); + const t2 : []const u8 = if (strip_prefix_text("", "pub ") != null) { strip_prefix_text("", "pub ").? } else { "" }; + assert(type_text::same(t2, "")); + const t3 : []const u8 = if (strip_prefix_text("pub ", "pub ") != null) { strip_prefix_text("pub ", "pub ").? } else { "pub " }; + assert(type_text::same(t3, "")); + const t4 : []const u8 = if (strip_prefix_text("x", "") != null) { strip_prefix_text("x", "").? } else { "x" }; + assert(type_text::same(t4, "x")); + const t5 : []const u8 = if (strip_prefix_byte("-5", 45) != null) { strip_prefix_byte("-5", 45).? } else { "-5" }; + assert(type_text::same(t5, "5")); + const t6 : []const u8 = if (strip_prefix_byte("5", 45) != null) { strip_prefix_byte("5", 45).? } else { "5" }; + assert(type_text::same(t6, "5")); + const t7 : []const u8 = if (strip_prefix_byte("--", 45) != null) { strip_prefix_byte("--", 45).? } else { "--" }; + assert(type_text::same(t7, "-")); +} + /// The appends are Rust's own String writes: every expected value below was printed by /// `format!`/`push` under rustc on the lab, not derived. test std_appends_are_rusts_string_writes {