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 new FixedSizeCollection with the specified capacity and ExpansionMode.
  • 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 - Returns true if the collection is full. Checks if the length of the collection is equal to the capacity.
  • mode - Returns the ExpansionMode 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 the mode 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

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));

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);

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);

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

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());

Implementors