Skip to main content

Module slist

Module slist 

Source
Available on crate feature slist only.
Expand description

An intrusive singly linked list implementation.

This module provides SLinkedList, a singly linked list optimized for FIFO (First-In, First-Out) queue-like behavior. Elements embed the list nodes themselves, offering memory efficiency and explicit control over allocation.

§Features

  • O(1) push to back and pop from front.
  • Generic over pointer types (Box, Arc, NonNull, raw pointers).

§Example

use embed_collections::{slist::{SLinkedList, SListItem, SListNode}, Pointer};
use core::cell::UnsafeCell;
use std::sync::Arc;
use core::ptr::NonNull;

struct MyTask {
    priority: u8,
    description: String,
    node: UnsafeCell<SListNode<MyTask, ()>>,
}

impl MyTask {
    fn new(priority: u8, desc: &str) -> Self {
        MyTask {
            priority,
            description: desc.to_string(),
            node: UnsafeCell::new(SListNode::default()),
        }
    }
}

unsafe impl SListItem<()> for MyTask {
    fn get_node(&self) -> &mut SListNode<Self, ()> {
        unsafe { &mut *self.node.get() }
    }
}

// Using Box<T> (owned pointers)
{
    let mut task_queue = SLinkedList::<Box<MyTask>, ()>::new();
    task_queue.push_back(Box::new(MyTask::new(1, "Handle user login")));
    task_queue.push_back(Box::new(MyTask::new(2, "Process analytics data")));
    task_queue.push_back(Box::new(MyTask::new(1, "Send welcome email")));
    assert_eq!(task_queue.len(), 3);
    assert_eq!(task_queue.pop_front().unwrap().description, "Handle user login");
    assert_eq!(task_queue.pop_front().unwrap().description, "Process analytics data");
    assert_eq!(task_queue.pop_front().unwrap().description, "Send welcome email");
    assert!(task_queue.is_empty());
}

// Using Arc<T> (shared ownership)
{
    let mut task_queue = SLinkedList::<Arc<MyTask>, ()>::new();
    task_queue.push_back(Arc::new(MyTask::new(1, "Handle user login")));
    task_queue.push_back(Arc::new(MyTask::new(2, "Process analytics data")));
    task_queue.push_back(Arc::new(MyTask::new(1, "Send welcome email")));
    assert_eq!(task_queue.len(), 3);
    assert_eq!(task_queue.pop_front().unwrap().description, "Handle user login");
    assert_eq!(task_queue.pop_front().unwrap().description, "Process analytics data");
    assert_eq!(task_queue.pop_front().unwrap().description, "Send welcome email");
    assert!(task_queue.is_empty());
}

// Using NonNull<T> (raw pointers without ownership)
{
    let mut task_queue = SLinkedList::<NonNull<MyTask>, ()>::new();
    let task1 = Box::leak(Box::new(MyTask::new(1, "Handle user login")));
    let task2 = Box::leak(Box::new(MyTask::new(2, "Process analytics data")));
    let task3 = Box::leak(Box::new(MyTask::new(1, "Send welcome email")));
    task_queue.push_back(NonNull::from(task1));
    task_queue.push_back(NonNull::from(task2));
    task_queue.push_back(NonNull::from(task3));
    assert_eq!(task_queue.len(), 3);
    assert_eq!(unsafe { &task_queue.pop_front().unwrap().as_ref().description }, "Handle user login");
    assert_eq!(unsafe { &task_queue.pop_front().unwrap().as_ref().description }, "Process analytics data");
    assert_eq!(unsafe { &task_queue.pop_front().unwrap().as_ref().description }, "Send welcome email");
    assert!(task_queue.is_empty());
}

Structs§

SLinkedList
A singly linked list with head and tail pointers (FIFO queue).
SLinkedListDrainer
SLinkedListIterator
SListNode
The node structure that must be embedded in items to be stored in a SLinkedList.

Traits§

SListItem
A trait to return internal mutable SListNode for specified list.