pub trait FixedSizeCollection<'a, T>: Collection<'a, T> {
fn with_mode(capacity: usize, mode: ExpansionMode) -> Self
where
Self: Sized;
fn capacity(&self) -> usize;
fn expand(&mut self, extra_size: usize);
fn mode(&self) -> &ExpansionMode;
fn is_full(&self) -> bool { ... }
}Expand description
A Collection that can easily be expanded, as the capacity is fixed. Normally, this are data
structures that use a fixed size buffer in memory (Array-like).
Similar to Collection, the FixedSizeCollection is a trait that is generic over any type
without the need of any extra traits. This allows the user to create a collection of any type
that they want.
To create a new FixedSizeCollection, the user must add the following extra code into the
add method at the beginning of the method. This code will manage the expansion of the
collection depending on the ExpansionMode of the collection :
if check_expansion(self) {
return;
}An alternative way is to call the check_expansion_add macro. This macro will add the
the previous code into the add method.
For a full example, see the Examples section.
The trait provide extra methods related with the capacity of the collection . The capacity is
the amount of items that the collection can hold. The FixedSizeCollection provides the
following methods:
with_mode- Creates a newFixedSizeCollectionwith the specified capacity andExpansionMode.capacity- Returns the maximum amount of items that the collection can hold.expand- Expands the capacity of the collection by a specific amount. This amount or more will be added to the capacity.is_full- Returnstrueif the collection is full. Checks if the length of the collection is equal to the capacity.mode- Returns theExpansionModeof expansion of the collection .
For implementation of the FixedSizeCollection data structure, there also exists the
following method:
check_expansion- Checks if the collection is full and if it is, it will behave depending on themodeof the collection .
Examples
Expands the example shown in Collection by modifying a bit the struct with a mode and
implementing the FixedSizeCollection trait. The example contains only the modified code.
use trait_based_collection::{prelude::*, macros::{check_expansion_add, All}};
#[derive(All)]
struct MyCollection<T> {
data: Vec<T>,
mode: ExpansionMode,
}
impl<'a, T: 'a> Collection<'a, T> for MyCollection<T> {
fn new_default() -> Self where Self: Sized {
MyCollection::with_mode(16, ExpansionMode::default())
}
fn with_capacity(capacity: usize) -> Self {
MyCollection::with_mode(capacity, ExpansionMode::Panic)
}
fn with_approximate_capacity(approx_capacity: usize) -> Self{
MyCollection::with_mode(approx_capacity, ExpansionMode::default())
}
#[check_expansion_add]
fn add(&mut self, value: T) {
self.data.push(value);
}
}
impl<'a, T: 'a> FixedSizeCollection<'a, T> for MyCollection<T> {
fn with_mode(capacity: usize, mode: ExpansionMode) -> Self {
assert_ne!(capacity, 0, "Capacity must be greater than 0");
MyCollection {
data: Vec::with_capacity(capacity),
mode,
}
}
fn capacity(&self) -> usize {
self.data.capacity()
}
fn expand(&mut self, extra_size: usize) {
self.data.reserve(extra_size);
}
fn mode(&self) -> &ExpansionMode {
&self.mode
}
}Safety
The FixedSizeCollection trait is currently safe as it is based on the Vec
implementation. However, in the future, Vec could also be implemented in the project and
the FixedSizeCollection trait would be unsafe. Similarly to Collection, the trait
is implemented in unsafe code but the usage of the trait should be safe.
Required Methods
sourcefn with_mode(capacity: usize, mode: ExpansionMode) -> Selfwhere
Self: Sized,
fn with_mode(capacity: usize, mode: ExpansionMode) -> Selfwhere
Self: Sized,
Creates a new fixed size Collection with the specified capacity and ExpansionMode.
Panics
This method will panic if the specified capacity is equal to zero.
Examples
Example using ArrayStack:
use trait_based_collection::{prelude::*, ArrayStack};
let mut stack: ArrayStack<i32> = ArrayStack::with_mode(16, ExpansionMode::Expand(2.0));
assert_eq!(stack.capacity(), 16);
assert_eq!(stack.mode(), &ExpansionMode::Expand(2.0));sourcefn capacity(&self) -> usize
fn capacity(&self) -> usize
Returns the maximum amount of items that the collection can hold without expanding.
The number of items on the FixedSizeCollection can never be greater than the capacity.
Examples
Example using CircularDeque:
use trait_based_collection::{prelude::*, CircularDeque};
let mut queue: CircularDeque<usize> = CircularDeque::with_capacity(10);
assert_eq!(queue.capacity(), 10);sourcefn expand(&mut self, extra_size: usize)
fn expand(&mut self, extra_size: usize)
Expands the capacity of the collection by at least the specified amount. This amount or more will be dded to the capacity.
This method is called automatically if the mode of the collection is Expand, it will
be called when the collection is full through the check_expansion method.
This method ensures that after the expansion, the integrity of the FixedSizeCollection
is not compromised.
Examples
Example using ArrayStack:
use trait_based_collection::{prelude::*, ArrayStack};
let mut stack: ArrayStack<usize> = ArrayStack::with_capacity(10);
assert_eq!(stack.capacity(), 10);
stack.expand(10);
assert!(stack.capacity() >= 20);sourcefn mode(&self) -> &ExpansionMode
fn mode(&self) -> &ExpansionMode
Returns the ExpansionMode of the collection . This is used to determine how the
collection will behave when it is full.
The possibility of modifying the ExpansionMode will be determined by the implementation.
The built-in implementations of FixedSizeCollection will allow modifications through
a public attribute.
Examples
Example using ArrayStack with default constructor:
use trait_based_collection::{prelude::*, ArrayStack};
let mut stack: ArrayStack<u8> = ArrayStack::default();
assert_eq!(stack.mode(), &ExpansionMode::default());Another example but using the with_capacity constructor:
use trait_based_collection::{prelude::*, ArrayStack};
let mut stack: ArrayStack<u8> = ArrayStack::with_capacity(10);
assert_eq!(stack.mode(), &ExpansionMode::Panic);Provided Methods
sourcefn is_full(&self) -> bool
fn is_full(&self) -> bool
Checks if the number of items in the FixedSizeCollection is equal to the capacity.
Examples
Example using CircularDeque:
use trait_based_collection::{prelude::*, CircularDeque};
let mut queue = CircularDeque::with_capacity(10);
assert!(!queue.is_full());
for i in 0..10 {
queue.add(i);
}
assert!(queue.is_full());