pub fn map_indexed<T, U>(
        &'a self,
        list: &'a ReadSignal<Vec<T>>,
        map_fn: impl for<'child_lifetime> Fn(
                BoundedScopeRef<'child_lifetime, 'a>,
                T,
            ) -> U
            + 'a,
    ) -> &'a ReadSignal<Vec<U>>
    where
        T: PartialEq + Clone,
        U: Clone + 'a,
    {
        let map_fn = Rc::new(map_fn);

        // Previous state used for diffing.
        let mut items = Rc::new(Vec::new());
        let mut mapped = Vec::new();
        let mut disposers: Vec<ScopeDisposer<'a>> = Vec::new();

        let signal = self.create_signal(Vec::new());

        // Diff and update signal each time list is updated.
        self.create_effect(move || {
            let new_items = list.get();

            if new_items.is_empty() {
                // Fast path for removing all items.
                for dis in mem::take(&mut disposers) {
                    unsafe {
                        dis.dispose();
                    }
                }
                items = Rc::new(Vec::new());
                mapped = Vec::new();
            } else {
                // Pre-allocate space needed
                if new_items.len() > items.len() {
                    let new_count = new_items.len() - items.len();
                    mapped.reserve(new_count);
                    disposers.reserve(new_count);
                }

                for (i, new_item) in new_items.iter().enumerate() {
                    let new_item = new_item.clone();
                    let item = items.get(i);
                    // We lift the equality out of the else if branch to satisfy
                    // borrow checker.
                    let eqs = item != Some(&new_item);

                    let mut tmp = MaybeUninit::<U>::zeroed();
                    let ptr = &mut tmp as *mut MaybeUninit<U>;
                    if item.is_none() || eqs {
                        let new_disposer = self.create_child_scope({
                            let map_fn = Rc::clone(&map_fn);
                            move |ctx| unsafe {
                                // SAFETY: callback is called immediately in
                                // self.create_child_scope.
                                // ptr is still accessible after
                                // self.create_child_scope and
                                // therefore lives long enough.

                                // SAFETY: f takes the same parameter as the
                                // argument to
                                // self.create_child_scope(_).
                                (*ptr).write(map_fn(
                                    mem::transmute(ctx),
                                    new_item,
                                ));
                            }
                        });
                        if item.is_none() {
                            // SAFETY: tmp is written in self.create_child_scope
                            mapped.push(unsafe { tmp.assume_init() });
                            disposers.push(new_disposer);
                        } else if eqs {
                            // SAFETY: tmp is written in self.create_child_scope
                            mapped[i] = unsafe { tmp.assume_init() };
                            let prev =
                                mem::replace(&mut disposers[i], new_disposer);
                            unsafe {
                                prev.dispose();
                            }
                        }
                    }
                }

                if new_items.len() < items.len() {
                    for _i in new_items.len()..items.len() {
                        unsafe {
                            disposers.pop().unwrap().dispose();
                        }
                    }
                }

                // In case the new set is shorter than the old, set the length
                // of the mapped array.
                mapped.truncate(new_items.len());

                // save a copy of the mapped items for the next update.
                items = Rc::clone(&new_items);
                debug_assert!([items.len(), mapped.len(), disposers.len()]
                    .iter()
                    .all(|l| *l == new_items.len()));
            }

            // Update signal to trigger updates.
            signal.set(mapped.clone());
        });

        signal
    }
/// Function that maps a `Vec` to another `Vec` via a map function. The
/// mapped `Vec` is lazy computed, meaning that it's value will only be
/// updated when requested. Modifications to the input `Vec` are diffed
/// by index to prevent recomputing values that have not changed.
///
/// Generally, it is preferred to use [`map_keyed`](Self::map_keyed) instead
/// when a key function is available.
///
/// This function is the underlying utility behind `Indexed`.
///
/// # Params
/// * `list` - The list to be mapped. The list must be a [`ReadSignal`]
///   (obtained from a [`Signal`]) and therefore reactive.
/// * `map_fn` - A closure that maps from the input type to the output type.
Function that maps a `Vec` to another `Vec` via a map function. The
mapped `Vec` is lazy computed, meaning that it's value will only be
updated when requested. Modifications to the input `Vec` are diffed
by index to prevent recomputing values that have not changed.

Generally, it is preferred to use [`map_keyed`](Self::map_keyed) instead
when a key function is available.

This function is the underlying utility behind `Indexed`.
Function that maps a ` Vec ` to another ` Vec ` via a map function . The mapped ` Vec ` is lazy computed meaning that it ' s value will only be updated when requested . Modifications to the input ` Vec ` are diffed by index to prevent recomputing values that have not changed . Generally it is preferred to use [ ` map_keyed ` ] ( Self :: map_keyed ) instead when a key function is available . This function is the underlying utility behind ` Indexed ` .
pub fn map_indexed<T, U>(
        &'a self,
        list: &'a ReadSignal<Vec<T>>,
        map_fn: impl for<'child_lifetime> Fn(
                BoundedScopeRef<'child_lifetime, 'a>,
                T,
            ) -> U
            + 'a,
    ) -> &'a ReadSignal<Vec<U>>
    where
        T: PartialEq + Clone,
        U: Clone + 'a,
    {
        let map_fn = Rc::new(map_fn);
        // Previous state used for diffing.
        let mut items = Rc::new(Vec::new());
        let mut mapped = Vec::new();
        let mut disposers: Vec<ScopeDisposer<'a>> = Vec::new();
        let signal = self.create_signal(Vec::new());
        // Diff and update signal each time list is updated.
        self.create_effect(move || {
            let new_items = list.get();
            if new_items.is_empty() {
                // Fast path for removing all items.
                for dis in mem::take(&mut disposers) {
                    unsafe {
                        dis.dispose();
                    }
                }
                items = Rc::new(Vec::new());
                mapped = Vec::new();
            } else {
                // Pre-allocate space needed
                if new_items.len() > items.len() {
                    let new_count = new_items.len() - items.len();
                    mapped.reserve(new_count);
                    disposers.reserve(new_count);
                }
                for (i, new_item) in new_items.iter().enumerate() {
                    let new_item = new_item.clone();
                    let item = items.get(i);
                    // We lift the equality out of the else if branch to satisfy
                    // borrow checker.
                    let eqs = item != Some(&new_item);
                    let mut tmp = MaybeUninit::<U>::zeroed();
                    let ptr = &mut tmp as *mut MaybeUninit<U>;
                    if item.is_none() || eqs {
                        let new_disposer = self.create_child_scope({
                            let map_fn = Rc::clone(&map_fn);
                            move |ctx| unsafe {
                                // SAFETY: callback is called immediately in
                                // self.create_child_scope.
                                // ptr is still accessible after
                                // self.create_child_scope and
                                // therefore lives long enough.
                                // SAFETY: f takes the same parameter as the
                                // argument to
                                // self.create_child_scope(_).
                                (*ptr).write(map_fn(
                                    mem::transmute(ctx),
                                    new_item,
                                ));
                            }
                        });
                        if item.is_none() {
                            // SAFETY: tmp is written in self.create_child_scope
                            mapped.push(unsafe { tmp.assume_init() });
                            disposers.push(new_disposer);
                        } else if eqs {
                            // SAFETY: tmp is written in self.create_child_scope
                            mapped[i] = unsafe { tmp.assume_init() };
                            let prev =
                                mem::replace(&mut disposers[i], new_disposer);
                            unsafe {
                                prev.dispose();
                            }
                        }
                    }
                }
                if new_items.len() < items.len() {
                    for _i in new_items.len()..items.len() {
                        unsafe {
                            disposers.pop().unwrap().dispose();
                        }
                    }
                }
                // In case the new set is shorter than the old, set the length
                // of the mapped array.
                mapped.truncate(new_items.len());
                // save a copy of the mapped items for the next update.
                items = Rc::clone(&new_items);
                debug_assert!([items.len(), mapped.len(), disposers.len()]
                    .iter()
                    .all(|l| *l == new_items.len()));
            }
            // Update signal to trigger updates.
            signal.set(mapped.clone());
        });
        signal
    }
pub fn map_indexed < T , U > ( & ' a self , list : & ' a ReadSignal < Vec < T > > , map_fn : impl for < ' child_lifetime > Fn ( BoundedScopeRef < ' child_lifetime , ' a > , T , ) -> U + ' a , ) -> & ' a ReadSignal < Vec < U > > where T : PartialEq + Clone , U : Clone + ' a , { let map_fn = Rc :: new ( map_fn ) ; // Previous state used for diffing. let mut items = Rc :: new ( Vec :: new ( ) ) ; let mut mapped = Vec :: new ( ) ; let mut disposers : Vec < ScopeDisposer < ' a > > = Vec :: new ( ) ; let signal = self . create_signal ( Vec :: new ( ) ) ; // Diff and update signal each time list is updated. self . create_effect ( move | | { let new_items = list . get ( ) ; if new_items . is_empty ( ) { // Fast path for removing all items. for dis in mem :: take ( & mut disposers ) { unsafe { dis . dispose ( ) ; } } items = Rc :: new ( Vec :: new ( ) ) ; mapped = Vec :: new ( ) ; } else { // Pre-allocate space needed if new_items . len ( ) > items . len ( ) { let new_count = new_items . len ( ) - items . len ( ) ; mapped . reserve ( new_count ) ; disposers . reserve ( new_count ) ; } for ( i , new_item ) in new_items . iter ( ) . enumerate ( ) { let new_item = new_item . clone ( ) ; let item = items . get ( i ) ; // We lift the equality out of the else if branch to satisfy // borrow checker. let eqs = item != Some ( & new_item ) ; let mut tmp = MaybeUninit :: < U > :: zeroed ( ) ; let ptr = & mut tmp as * mut MaybeUninit < U > ; if item . is_none ( ) || eqs { let new_disposer = self . create_child_scope ( { let map_fn = Rc :: clone ( & map_fn ) ; move | ctx | unsafe { // SAFETY: callback is called immediately in // self.create_child_scope. // ptr is still accessible after // self.create_child_scope and // therefore lives long enough. // SAFETY: f takes the same parameter as the // argument to // self.create_child_scope(_). ( * ptr ) . write ( map_fn ( mem :: transmute ( ctx ) , new_item , ) ) ; } } ) ; if item . is_none ( ) { // SAFETY: tmp is written in self.create_child_scope mapped . push ( unsafe { tmp . assume_init ( ) } ) ; disposers . push ( new_disposer ) ; } else if eqs { // SAFETY: tmp is written in self.create_child_scope mapped [ i ] = unsafe { tmp . assume_init ( ) } ; let prev = mem :: replace ( & mut disposers [ i ] , new_disposer ) ; unsafe { prev . dispose ( ) ; } } } } if new_items . len ( ) < items . len ( ) { for _i in new_items . len ( ) .. items . len ( ) { unsafe { disposers . pop ( ) . unwrap ( ) . dispose ( ) ; } } } // In case the new set is shorter than the old, set the length // of the mapped array. mapped . truncate ( new_items . len ( ) ) ; // save a copy of the mapped items for the next update. items = Rc :: clone ( & new_items ) ; debug_assert ! ( [ items len ( ) mapped len ( ) disposers len ( ) ] iter ( ) all ( l l new_items len ( ) ) ) ; } // Update signal to trigger updates. signal . set ( mapped . clone ( ) ) ; } ) ; signal }
Function that maps a `Vec` to another `Vec` via a map function.
Function that maps a ` Vec ` to another ` Vec ` via a map function .
&'a self
list
&'a ReadSignal<Vec<T>>
map_fn
impl for<'child_lifetime> Fn(
                BoundedScopeRef<'child_lifetime, 'a>,
                T,
            ) -> U
            + 'a
&'a self
list
&'a ReadSignal<Vec<T>>
map_fn
impl for<'child_lifetime> Fn(
                BoundedScopeRef<'child_lifetime, 'a>,
                T,
            ) -> U
            + 'a
params
`list` - The list to be mapped. The list must be a [`ReadSignal`]
(obtained from a [`Signal`]) and therefore reactive.
`map_fn` - A closure that maps from the input type to the output type.
` list ` - The list to be mapped . The list must be a [ ` ReadSignal ` ] ( obtained from a [ ` Signal ` ] ) and therefore reactive . ` map_fn ` - A closure that maps from the input type to the output type .