type_vec/
vect.rs

1//! Defines the type-safe vector.
2
3use crate::{
4    common::*,
5    impls,
6    size::{Dyn, IntoSize, Size},
7};
8
9/// The type-safe vector with type-level length.
10#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
11pub struct Vect<T, S>
12where
13    S: Size,
14{
15    pub(crate) data: Vec<T>,
16    pub(crate) _phantom: PhantomData<S>,
17}
18
19impl<T> Vect<T, U0> {
20    /// Creates an empty vector with static length.
21    pub fn new() -> Self {
22        Self {
23            data: vec![],
24            _phantom: PhantomData,
25        }
26    }
27
28    /// Creates an empty vector with static length and with specified capacity.
29    pub fn with_capacity(capacity: usize) -> Self {
30        Self {
31            data: Vec::with_capacity(capacity),
32            _phantom: PhantomData,
33        }
34    }
35
36    /// Gets the number of elements.
37    pub fn len(&self) -> usize {
38        U0::USIZE
39    }
40}
41
42impl<T> Vect<T, Dyn> {
43    /// Creates an empty vector with dynamic length.
44    pub fn new() -> Self {
45        Self {
46            data: vec![],
47            _phantom: PhantomData,
48        }
49    }
50
51    /// Creates a vector from [Vec](Vec).
52    pub fn from_vec(data: Vec<T>) -> Self {
53        Self {
54            data,
55            _phantom: PhantomData,
56        }
57    }
58
59    /// Creates an empty vector with dynamic length and with specified capacity.
60    pub fn with_capacity(capacity: usize) -> Self {
61        Self {
62            data: Vec::with_capacity(capacity),
63            _phantom: PhantomData,
64        }
65    }
66
67    /// Gets the number of elements.
68    pub fn len(&self) -> usize {
69        self.data.len()
70    }
71
72    /// Converts a vector with static length.
73    ///
74    /// The vector size must be equal to the specified static size.
75    /// Otherwise it returns `None`.
76    pub fn into_static<S>(self) -> Option<Vect<T, S>>
77    where
78        S: Unsigned + Size,
79    {
80        let data = self.data;
81        if data.len() == S::USIZE {
82            Some(Vect {
83                data,
84                _phantom: PhantomData,
85            })
86        } else {
87            None
88        }
89    }
90}
91
92impl<T, U, B> Vect<T, UInt<U, B>>
93where
94    U: Unsigned,
95    B: Bit,
96{
97    /// Gets the number of elements.
98    pub fn len(&self) -> usize {
99        UInt::<U, B>::USIZE
100    }
101}
102
103impl<T, S> Vect<T, S>
104where
105    S: Size,
106{
107    /// Appends an element to the end of the vector.
108    pub fn push(self, elem: T) -> impls::PushImplOp<Self, T>
109    where
110        (): impls::PushImpl<Self, T>,
111    {
112        <() as impls::PushImpl<Self, T>>::impl_push(self, elem)
113    }
114
115    /// Removes an element from the end of the vector.
116    pub fn pop(self) -> impls::PopImplOp<Self>
117    where
118        (): impls::PopImpl<Self>,
119    {
120        <() as impls::PopImpl<Self>>::impl_pop(self)
121    }
122
123    /// Returns a reference to an element depending on the index.
124    ///
125    /// If both length and index have static sizes, it returns `&T`. Otherwise, it returns `Option<&T>`.
126    pub fn get<'a, I>(&'a self, index: I) -> impls::GetImplOp<'a, Self, I::Output>
127    where
128        I: IntoSize,
129        (): impls::GetImpl<'a, Self, I::Output>,
130    {
131        <() as impls::GetImpl<'a, Self, I::Output>>::impl_get(self, index.into_size())
132    }
133
134    /// Inserts an element at specified index.
135    ///
136    /// If both length and index have static sizes, it checks if the index is valid in compile time.
137    /// Otherwise, it panics if the index is out of bound.
138    pub fn insert<I>(self, index: I, elem: T) -> impls::InsertImplOp<Self, I::Output, T>
139    where
140        I: IntoSize,
141        (): impls::InsertImpl<Self, I::Output, T>,
142    {
143        <() as impls::InsertImpl<Self, I::Output, T>>::impl_insert(self, index.into_size(), elem)
144    }
145
146    /// Removes an element at specified index.
147    ///
148    /// If both length and index have static sizes, it checks if the index is valid in compile time.
149    /// Otherwise, it panics if the index is out of bound.
150    pub fn remove<I>(self, index: I) -> impls::RemoveImplOp<Self, I::Output>
151    where
152        I: IntoSize,
153        (): impls::RemoveImpl<Self, I::Output>,
154    {
155        <() as impls::RemoveImpl<Self, I::Output>>::impl_remove(self, index.into_size())
156    }
157
158    /// Converts to a vector with dynamic length type.
159    pub fn into_dyn(self) -> Vect<T, Dyn> {
160        Vect {
161            data: self.data,
162            _phantom: PhantomData,
163        }
164    }
165
166    /// Converts to [Vec](Vec).
167    pub fn into_vec(self) -> Vec<T> {
168        self.data
169    }
170}