use crate::any::{Dynamic, Variant}; use crate::def_package; use crate::module::{FuncReturn, Module}; use crate::parser::INT; use crate::stdlib::{ any::TypeId, boxed::Box, ops::{Add, Range}, }; // Register range function fn reg_range(lib: &mut Module) where Range: Iterator, { lib.set_iter(TypeId::of::>(), |source| { Box::new(source.cast::>().map(|x| x.into_dynamic())) as Box> }); } fn get_range(from: T, to: T) -> FuncReturn> { Ok(from..to) } // Register range function with step #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] struct StepRange(T, T, T) where for<'a> &'a T: Add<&'a T, Output = T>, T: Variant + Clone + PartialOrd; impl Iterator for StepRange where for<'a> &'a T: Add<&'a T, Output = T>, T: Variant + Clone + PartialOrd, { type Item = T; fn next(&mut self) -> Option { if self.0 < self.1 { let v = self.0.clone(); self.0 = &v + &self.2; Some(v) } else { None } } } fn reg_step(lib: &mut Module) where for<'a> &'a T: Add<&'a T, Output = T>, T: Variant + Clone + PartialOrd, StepRange: Iterator, { lib.set_iter(TypeId::of::>(), |source| { Box::new(source.cast::>().map(|x| x.into_dynamic())) as Box> }); } fn get_step_range(from: T, to: T, step: T) -> FuncReturn> where for<'a> &'a T: Add<&'a T, Output = T>, T: Variant + Clone + PartialOrd, { Ok(StepRange::(from, to, step)) } def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, { reg_range::(lib); lib.set_fn_2("range", get_range::); if cfg!(not(feature = "only_i32")) && cfg!(not(feature = "only_i64")) { macro_rules! reg_range { ($lib:expr, $x:expr, $( $y:ty ),*) => ( $( reg_range::<$y>($lib); $lib.set_fn_2($x, get_range::<$y>); )* ) } reg_range!(lib, "range", i8, u8, i16, u16, i32, i64, u32, u64); if cfg!(not(target_arch = "wasm32")) { reg_range!(lib, "range", i128, u128); } } reg_step::(lib); lib.set_fn_3("range", get_step_range::); if cfg!(not(feature = "only_i32")) && cfg!(not(feature = "only_i64")) { macro_rules! reg_step { ($lib:expr, $x:expr, $( $y:ty ),*) => ( $( reg_step::<$y>($lib); $lib.set_fn_3($x, get_step_range::<$y>); )* ) } reg_step!(lib, "range", i8, u8, i16, u16, i32, i64, u32, u64); if cfg!(not(target_arch = "wasm32")) { reg_step!(lib, "range", i128, u128); } } });