Amanieu / intrusive-rs

Intrusive collections for Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Merging 2 lists without iterating

Matthias247 opened this issue · comments

Is there currently any possibility to append a list (or a CursorMut) to another list, without manually iterating through it? I haven't found a way in the API docs, but it should be as simple as joining the 2 related pointers.

What I'm trying to do is process a list. While doing the list processing, updates to the list as well as to other lists can happen. Therefore I .take() the original list and move it in a temporary other one. Just acting on the original Cursor and doing mutable changes there is a bit tricky, since I use a shared helper function for list updates which is also used by other methods.

Below is a part of the workflow I try to perform

let mut temp_list = self.actual_list.take();

let mut cursor = temp_list.cursor_mut();
while let Some(elem) = cursor.remove() {
    // For each List item I perform an operation
    let result = elem.do_something();
    // Then I obtain a status, which instructs in which list(s) the
    // element will still be member of
    let status = elem.get_status();
    
    // This manipulates the original list as well as some other lists
    // based on the new status of the element
    self.update_lists_based_on_status(&elem, status);

    if result.is_err() {
        // In the error case I want to abort and all elements which
        // were not processed back to the original list.
        // Ideally to the front in the order they are now in `temp_list`.
        // So something like
        // self.actual_list.push_all_front(elem);
        // would be great

        // This is a workaround. Actually it's wrong since it adds the entries
        // after entries that might have been added through
        // ùpdate_lists_based_on_status()`.
        // Using a reverse iterator and pushing at the front would help here
        while let Some(elem) = cursor.remove() {
            self.actual_list.push_back(elem);
        }

        return result;
    }
}

You need to use the splice_before/splice_after methods on CursorMut.

Oh thanks, I missed that one. It works!