#![allow(clippy::inline_always)]
#![allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_sign_loss)]
use crate::nat_int::{
LEAN_MAX_SMALL_INT, LEAN_MAX_SMALL_NAT, LEAN_MIN_SMALL_INT, lean_big_int_to_int, lean_big_int64_to_int,
lean_big_size_t_to_int, lean_big_uint64_to_nat, lean_big_usize_to_nat, lean_uint8_of_big_nat,
};
use crate::object::{lean_box, lean_is_scalar, lean_unbox};
use crate::types::{b_lean_obj_arg, lean_obj_res};
#[inline(always)]
pub unsafe fn lean_usize_to_nat(n: usize) -> lean_obj_res {
unsafe {
if n <= LEAN_MAX_SMALL_NAT {
lean_box(n)
} else {
lean_big_usize_to_nat(n)
}
}
}
#[inline(always)]
pub unsafe fn lean_unsigned_to_nat(n: u32) -> lean_obj_res {
unsafe { lean_usize_to_nat(n as usize) }
}
#[inline(always)]
pub unsafe fn lean_uint64_to_nat(n: u64) -> lean_obj_res {
unsafe {
if (n as usize as u64) == n && (n as usize) <= LEAN_MAX_SMALL_NAT {
lean_box(n as usize)
} else {
lean_big_uint64_to_nat(n)
}
}
}
#[inline(always)]
pub unsafe fn lean_uint8_of_nat(a: b_lean_obj_arg) -> u8 {
unsafe {
if lean_is_scalar(a) {
lean_unbox(a) as u8
} else {
lean_uint8_of_big_nat(a)
}
}
}
#[inline(always)]
pub unsafe fn lean_uint8_to_nat(a: u8) -> lean_obj_res {
unsafe { lean_usize_to_nat(a as usize) }
}
#[inline(always)]
pub unsafe fn lean_uint16_to_nat(a: u16) -> lean_obj_res {
unsafe { lean_usize_to_nat(a as usize) }
}
#[inline(always)]
pub unsafe fn lean_uint32_to_nat(a: u32) -> lean_obj_res {
unsafe { lean_usize_to_nat(a as usize) }
}
#[inline(always)]
pub unsafe fn lean_int_to_int(n: i32) -> lean_obj_res {
let fits =
core::mem::size_of::<*mut ()>() == 8 || (LEAN_MIN_SMALL_INT..=LEAN_MAX_SMALL_INT).contains(&i64::from(n));
unsafe {
if fits {
lean_box((n as u32) as usize)
} else {
lean_big_int_to_int(n)
}
}
}
#[inline(always)]
pub unsafe fn lean_int64_to_int(n: i64) -> lean_obj_res {
unsafe {
if (LEAN_MIN_SMALL_INT..=LEAN_MAX_SMALL_INT).contains(&n) {
lean_box((n as i32 as u32) as usize)
} else {
lean_big_int64_to_int(n)
}
}
}
#[inline(always)]
pub unsafe fn lean_nat_to_int(a: lean_obj_res) -> lean_obj_res {
unsafe {
if !lean_is_scalar(a) {
return a;
}
let v = lean_unbox(a);
if i64::try_from(v).is_ok_and(|n| n <= LEAN_MAX_SMALL_INT) {
a
} else {
lean_big_size_t_to_int(v)
}
}
}
#[inline(always)]
pub unsafe fn lean_scalar_to_int64(a: b_lean_obj_arg) -> i64 {
unsafe {
if core::mem::size_of::<*mut ()>() == 8 {
i64::from((lean_unbox(a) as u32) as i32)
} else {
((a as usize) as isize >> 1) as i64
}
}
}
#[inline(always)]
pub unsafe fn lean_scalar_to_int(a: b_lean_obj_arg) -> i32 {
unsafe { lean_scalar_to_int64(a) as i32 }
}