pub struct OnceList<T: ?Sized, A: Allocator = Global> { /* private fields */ }Expand description
A single linked list which behaves like std::cell::OnceCell, but for multiple values.
§Usage
A simple example:
use once_list2::OnceList;
// Create a new empty list. Note that the variable is immutable.
let list = OnceList::<i32>::new();
// You can push values to the list without the need for mutability.
list.push(1);
list.push(2);
// Or you can push multiple values at once.
list.extend([3, 4, 5]);
// You can iterate over the list.
assert_eq!(list.iter().copied().collect::<Vec<_>>(), vec![1, 2, 3, 4, 5]);
// Some methods are mutable only.
let mut list_mut = list;
// You can remove (take) a value from the list.
let removed = list_mut.remove(|&x| x % 2 == 0);
assert_eq!(removed, Some(2));
assert_eq!(list_mut.iter().copied().collect::<Vec<_>>(), vec![1, 3, 4, 5]);§Unsized types support
You can use the unsized types like str, [u8] or dyn Display as the value type of the OnceList.
If you are using the stable rust compiler, you can only use the dyn Any type as the unsized type.
(Strictly speaking, you can use ANY type as the unsized type, but you can’t do any actual operations
like pushing, removing, etc.)
In the nightly compiler and with the nightly feature enabled, the additional methods like push_unsized
and remove_unsized_as become available:
// This code only works with the nightly compiler and the `nightly` feature enabled.
use once_list2::OnceList;
// Creating a `OnceList` for `[i32]`, the unsized type.
let list = OnceList::<[i32]>::new();
list.push_unsized([1] /* A sized array type, `[i32; 1]`, can be coerced into [i32].*/);
list.push_unsized([2, 3] /* Same for `[i32; 2] type. */);
// The normal methods like `iter` are available because it returns a reference to the value.
assert_eq!(list.iter().nth(0).unwrap(), &[1]);
assert_eq!(list.iter().nth(1).unwrap(), &[2, 3]);
let mut list_mut = list;
// `remove_unsized_as` method allows you to check the unsized value type and remove it.
let removed: Option<[i32; 2]> = unsafe {
list_mut.remove_unsized_as(|x| if x.len() == 2 {
Some(x.try_into().unwrap())
} else {
None
})
};
// The removed value is an array, not a slice!
assert_eq!(removed, Some([2, 3]));Implementations§
Source§impl<T: ?Sized, A: Allocator> OnceList<T, A>
impl<T: ?Sized, A: Allocator> OnceList<T, A>
Sourcepub fn new_in(alloc: A) -> Self
pub fn new_in(alloc: A) -> Self
Creates a new empty OnceList with the given allocator. This method does not allocate.
Sourcepub fn contains(&self, val: &T) -> boolwhere
T: PartialEq,
pub fn contains(&self, val: &T) -> boolwhere
T: PartialEq,
Returns true if the list contains the value.
Sourcepub fn first_mut(&mut self) -> Option<&mut T>
pub fn first_mut(&mut self) -> Option<&mut T>
Returns a mutable reference to the first value, if it exists.
Sourcepub fn last_mut(&mut self) -> Option<&mut T>
pub fn last_mut(&mut self) -> Option<&mut T>
Returns a mutable reference to the last value, if it exists. This method is O(n).
Sourcepub fn iter(&self) -> impl Iterator<Item = &T>
pub fn iter(&self) -> impl Iterator<Item = &T>
Returns an iterator over the &T references in the list.
Source§impl<T: ?Sized, A: Allocator> OnceList<T, A>
impl<T: ?Sized, A: Allocator> OnceList<T, A>
Sourcepub fn remove_into_box<P>(&mut self, pred: P) -> Option<Box<T, A>>
Available on crate feature nightly only.
pub fn remove_into_box<P>(&mut self, pred: P) -> Option<Box<T, A>>
nightly only.Removes the first value in the list that matches the predicate, and returns the value as a boxed value.
This method supports the unsized value type T as well.
Note that even though this method returns a boxed value, the box is something re-allcoated. So this method might not be efficient as you expect.
Sourcepub unsafe fn remove_unsized_as<P, U>(&mut self, pred: P) -> Option<U>
Available on crate feature nightly only.
pub unsafe fn remove_unsized_as<P, U>(&mut self, pred: P) -> Option<U>
nightly only.Removes the first value in the list that matches the predicate, and returns the value.
The predicate function pred should return Some(&U) if the value is found,
and the returned reference &U must be the same address as the value given in the pred.
§Safety
This method is unsafe because it requires the predicate to return a reference to the same address as the value.
Source§impl<T: ?Sized, A: Allocator + Clone> OnceList<T, A>
impl<T: ?Sized, A: Allocator + Clone> OnceList<T, A>
Sourcepub fn push_unsized<U: Unsize<T>>(&self, val: U) -> &U
Available on crate feature nightly only.
pub fn push_unsized<U: Unsize<T>>(&self, val: U) -> &U
nightly only.An unsized version of the OnceList::push method.
You can push a sized value to the list. For exaple, you can push [i32; 3] to the list of [i32].
Source§impl<T, A: Allocator + Clone> OnceList<T, A>
impl<T, A: Allocator + Clone> OnceList<T, A>
Sourcepub fn push(&self, val: T) -> &T
pub fn push(&self, val: T) -> &T
Appends a value to the list, and returns the reference to that value.
Note that this method takes &self, not &mut self.
Sourcepub fn extend<U: IntoIterator<Item = T>>(&self, iter: U)
pub fn extend<U: IntoIterator<Item = T>>(&self, iter: U)
An almost same method with the std::iter::Extend::extend,
though this method takes &self instead of &mut self.
Source§impl<A: Allocator + Clone> OnceList<dyn Any, A>
impl<A: Allocator + Clone> OnceList<dyn Any, A>
Sourcepub fn push_any<T: Any>(&self, val: T) -> &T
pub fn push_any<T: Any>(&self, val: T) -> &T
Pushes an aribitrary value to the list, and returns the reference to that value.
use once_list2::OnceList;
use std::any::Any;
let list = OnceList::<dyn Any>::new();
list.push_any(1);
list.push_any("hello");
assert_eq!(list.iter().nth(0).unwrap().downcast_ref::<i32>(), Some(&1));
assert_eq!(list.iter().nth(1).unwrap().downcast_ref::<&str>(), Some(&"hello"));Source§impl<A: Allocator> OnceList<dyn Any, A>
impl<A: Allocator> OnceList<dyn Any, A>
Sourcepub fn find_by_type<T: Any>(&self) -> Option<&T>
pub fn find_by_type<T: Any>(&self) -> Option<&T>
Finds the first value in the list that is the same type as T, and returns the reference to that value.
use once_list2::OnceList;
use std::any::Any;
let list = OnceList::<dyn Any>::new();
list.push_any(1);
list.push_any("hello");
assert_eq!(list.find_by_type::<i32>(), Some(&1));
assert_eq!(list.find_by_type::<&str>(), Some(&"hello"));
assert_eq!(list.find_by_type::<Vec<u8>>(), None);Sourcepub fn remove_by_type<T: Any>(&mut self) -> Option<T>
pub fn remove_by_type<T: Any>(&mut self) -> Option<T>
Removes the first value in the list that is the same type as T, and returns the value.
use once_list2::OnceList;
use std::any::Any;
let mut list = OnceList::<dyn Any>::new();
list.push_any(1);
list.push_any("hello");
assert_eq!(list.remove_by_type::<i32>(), Some(1));
assert_eq!(list.len(), 1);
assert_eq!(list.iter().nth(0).unwrap().downcast_ref::<&str>(), Some(&"hello"));Trait Implementations§
Source§impl<T, A: Allocator + Clone> Extend<T> for OnceList<T, A>
impl<T, A: Allocator + Clone> Extend<T> for OnceList<T, A>
Source§fn extend<U: IntoIterator<Item = T>>(&mut self, iter: U)
fn extend<U: IntoIterator<Item = T>>(&mut self, iter: U)
Due to the definition of the Extend trait, this method takes &mut self.
Use the OnceList::extend method instead if you want to use &self.
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)