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 newFixedSizeCollection
with 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
- Returnstrue
if the collection is full. Checks if the length of the collection is equal to the capacity.mode
- Returns theExpansionMode
of 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 themode
of 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());