QueueInner

Struct QueueInner 

Source
pub struct QueueInner<T, S: Storage> { /* private fields */ }
Expand description

Base struct for Queue and QueueView, generic over the Storage.

In most cases you should use Queue or QueueView directly. Only use this struct if you want to write code that’s generic over both.

Implementations§

Source§

impl<T, const N: usize> QueueInner<T, OwnedStorage<N>>

Source

pub const fn new() -> Self

Creates an empty queue.

Source§

impl<T, S: Storage> QueueInner<T, S>

Source

pub fn as_view(&self) -> &QueueView<T>

Get a reference to the Queue, erasing the N const-generic.

Source

pub fn as_mut_view(&mut self) -> &mut QueueView<T>

Get a mutable reference to the Queue, erasing the N const-generic.

Source

pub fn capacity(&self) -> usize

Returns the maximum number of elements the queue can hold.

Source

pub fn len(&self) -> usize

Returns the number of elements in the queue.

Source

pub fn is_empty(&self) -> bool

Returns whether the queue is empty.

Source

pub fn is_full(&self) -> bool

Returns whether the queue is full.

Source

pub fn iter(&self) -> Iter<'_, T>

Iterates from the front of the queue to the back.

Source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

Source

pub fn enqueue(&mut self, item: T) -> Result<(), T>

Adds an item to the end of the queue.

Returns back the item if the queue is full.

Source

pub fn dequeue(&mut self) -> Option<T>

Returns the item in the front of the queue, or None if the queue is empty.

Source

pub fn peek(&self) -> Option<&T>

Returns a reference to the item in the front of the queue without dequeuing it, or None if the queue is empty.

§Examples
use heapless::spsc::Queue;

let mut queue: Queue<u8, 235> = Queue::new();
let (mut producer, mut consumer) = queue.split();
assert_eq!(None, consumer.peek());
producer.enqueue(1);
assert_eq!(Some(&1), consumer.peek());
assert_eq!(Some(1), consumer.dequeue());
assert_eq!(None, consumer.peek());
Source

pub unsafe fn enqueue_unchecked(&mut self, item: T)

Adds an item to the end of the queue, without checking if it’s full.

§Safety

If the queue is full, this operation will leak a value (T’s destructor won’t run on the value that got overwritten by item), and will allow the dequeue operation to create a copy of item, which could result in T’s destructor running on item twice.

Source

pub unsafe fn dequeue_unchecked(&mut self) -> T

Returns the item in the front of the queue, without checking if there is something in the queue.

§Safety

The queue must not be empty. Calling this on an empty queue causes undefined behavior.

Source

pub fn split(&mut self) -> (Producer<'_, T>, Consumer<'_, T>)

Splits a queue into producer and consumer endpoints.

If you need this function in a const context, check out Queue::split_const and QueueView::split_const.

§Examples

Create a queue and split it at runtime

let mut queue: Queue<(), 4> = Queue::new();
let (mut producer, mut consumer) = queue.split();
producer.enqueue(()).unwrap();
assert_eq!(consumer.dequeue(), Some(()));

Create a queue at compile time, split it at runtime, and pass it to an interrupt handler via a mutex.

use core::cell::RefCell;
use critical_section::Mutex;
use heapless::spsc::{Producer, Queue};

static PRODUCER: Mutex<RefCell<Option<Producer<'static, ()>>>> =
    { Mutex::new(RefCell::new(None)) };

fn interrupt() {
    let mut producer = {
        static mut P: Option<Producer<'static, ()>> = None;
        // SAFETY: Mutable access to `P` is allowed exclusively in this scope
        // and `interrupt` cannot be called directly or preempt itself.
        unsafe { &mut P }
    }
    .get_or_insert_with(|| {
        critical_section::with(|cs| PRODUCER.borrow_ref_mut(cs).take().unwrap())
    });

    producer.enqueue(()).unwrap();
}

fn main() {
    let mut consumer = {
        let (p, c) = {
            static mut Q: Queue<(), 4> = Queue::new();
            // SAFETY: `Q` is only accessible in this scope
            // and `main` is only called once.
            #[allow(static_mut_refs)]
            unsafe {
                Q.split()
            }
        };

        critical_section::with(move |cs| {
            let mut producer = PRODUCER.borrow_ref_mut(cs);
            *producer = Some(p);
        });

        c
    };

    // Interrupt occurs.

    consumer.dequeue().unwrap();
}
Source§

impl<T, const N: usize> QueueInner<T, OwnedStorage<N>>

Source

pub const fn split_const(&mut self) -> (Producer<'_, T>, Consumer<'_, T>)

Splits a queue into producer and consumer endpoints.

Unlike Queue::split, this method can be used in a const context

§Example

Create and split a queue at compile time, and pass it to the main function and an interrupt handler via a mutex at runtime.

use core::cell::RefCell;

use critical_section::Mutex;
use heapless::spsc::{Consumer, Producer, Queue};

static PC: (
    Mutex<RefCell<Option<Producer<'_, ()>>>>,
    Mutex<RefCell<Option<Consumer<'_, ()>>>>,
) = {
    static mut Q: Queue<(), 4> = Queue::new();
    // SAFETY: `Q` is only accessible in this scope.
    #[allow(static_mut_refs)]
    let (p, c) = unsafe { Q.split_const() };

    (
        Mutex::new(RefCell::new(Some(p))),
        Mutex::new(RefCell::new(Some(c))),
    )
};

fn interrupt() {
    let mut producer = {
        static mut P: Option<Producer<'_, ()>> = None;
        // SAFETY: Mutable access to `P` is allowed exclusively in this scope
        // and `interrupt` cannot be called directly or preempt itself.
        unsafe { &mut P }
    }
    .get_or_insert_with(|| {
        critical_section::with(|cs| PC.0.borrow_ref_mut(cs).take().unwrap())
    });

    producer.enqueue(()).unwrap();
}

fn main() {
    let mut consumer = critical_section::with(|cs| PC.1.borrow_ref_mut(cs).take().unwrap());

    // Interrupt occurs.

    consumer.dequeue().unwrap();
}
Source§

impl<T> QueueInner<T, ViewStorage>

Source

pub const fn split_const(&mut self) -> (Producer<'_, T>, Consumer<'_, T>)

Splits a queue into producer and consumer endpoints.

Unlike Queue::split, this method can be used in a const context

§Example

Create and split a queue at compile time, and pass it to the main function and an interrupt handler via a mutex at runtime.

use core::cell::RefCell;

use critical_section::Mutex;
use heapless::spsc::{Consumer, Producer, Queue, QueueView};

static PC: (
    Mutex<RefCell<Option<Producer<'_, ()>>>>,
    Mutex<RefCell<Option<Consumer<'_, ()>>>>,
) = {
    static mut Q: &mut QueueView<()> = &mut Queue::<(), 4>::new();
    // SAFETY: `Q` is only accessible in this scope.
    #[allow(static_mut_refs)]
    let (p, c) = unsafe { Q.split_const() };

    (
        Mutex::new(RefCell::new(Some(p))),
        Mutex::new(RefCell::new(Some(c))),
    )
};

fn interrupt() {
    let mut producer = {
        static mut P: Option<Producer<'_, ()>> = None;
        // SAFETY: Mutable access to `P` is allowed exclusively in this scope
        // and `interrupt` cannot be called directly or preempt itself.
        unsafe { &mut P }
    }
    .get_or_insert_with(|| {
        critical_section::with(|cs| PC.0.borrow_ref_mut(cs).take().unwrap())
    });

    producer.enqueue(()).unwrap();
}

fn main() {
    let mut consumer = critical_section::with(|cs| PC.1.borrow_ref_mut(cs).take().unwrap());

    // Interrupt occurs.

    consumer.dequeue().unwrap();
}

Trait Implementations§

Source§

impl<T, S> Debug for QueueInner<T, S>
where T: Debug, S: Storage,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T, S: Storage> Drop for QueueInner<T, S>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T, S> Hash for QueueInner<T, S>
where T: Hash, S: Storage,

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<'a, T, S: Storage> IntoIterator for &'a QueueInner<T, S>

Source§

type Item = &'a T

The type of the elements being iterated over.
Source§

type IntoIter = Iter<'a, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a, T, S: Storage> IntoIterator for &'a mut QueueInner<T, S>

Source§

type Item = &'a mut T

The type of the elements being iterated over.
Source§

type IntoIter = IterMut<'a, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<T, S, S2> PartialEq<QueueInner<T, S2>> for QueueInner<T, S>
where T: PartialEq, S: Storage, S2: Storage,

Source§

fn eq(&self, other: &QueueInner<T, S2>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T, S: Storage> Eq for QueueInner<T, S>
where T: Eq,

Auto Trait Implementations§

§

impl<T, S> !Freeze for QueueInner<T, S>

§

impl<T, S> RefUnwindSafe for QueueInner<T, S>
where <S as SealedStorage>::Buffer<UnsafeCell<MaybeUninit<T>>>: RefUnwindSafe,

§

impl<T, S> Send for QueueInner<T, S>
where <S as SealedStorage>::Buffer<UnsafeCell<MaybeUninit<T>>>: Send,

§

impl<T, S> Sync for QueueInner<T, S>
where <S as SealedStorage>::Buffer<UnsafeCell<MaybeUninit<T>>>: Sync,

§

impl<T, S> Unpin for QueueInner<T, S>
where <S as SealedStorage>::Buffer<UnsafeCell<MaybeUninit<T>>>: Unpin,

§

impl<T, S> UnwindSafe for QueueInner<T, S>
where <S as SealedStorage>::Buffer<UnsafeCell<MaybeUninit<T>>>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.