type_vec/
impls.rs

1//! The implementations of vector operations.
2
3use crate::{
4    common::*,
5    size::{self, Dyn, Size},
6    vect::Vect,
7};
8
9typ! {
10    pub fn Push<ty, size: Size>(Vect::<ty, size>: _) {
11        let new_size: Size = size::IncreaseOne(size);
12        Vect::<ty, new_size>
13    }
14
15    pub fn Pop<ty, size: Size>(Vect::<ty, size>: _) {
16        match size::DecreaseOne(size) {
17            Option::<Dyn> => Option::<Vect<ty, Dyn>>,
18            UTerm => Vect::<ty, UTerm>,
19            #[generics(uint: Unsigned, bit: Bit)]
20            UInt::<uint, bit> => {
21                let new_size = UInt::<uint, bit>;
22                Vect::<ty, new_size>
23            }
24        }
25    }
26}
27
28// VectFactory
29
30pub trait VectFactory<T> {
31    fn from_vec(vec: Vec<T>) -> Self;
32}
33
34impl<T, S> VectFactory<T> for Vect<T, S>
35where
36    S: Size,
37{
38    fn from_vec(vec: Vec<T>) -> Self {
39        Vect {
40            data: vec,
41            _phantom: PhantomData,
42        }
43    }
44}
45
46// push
47pub use push::{PushImpl, PushImplOp};
48
49mod push {
50    use super::*;
51
52    /// Implements vector appending.
53    pub trait PushImpl<Input, Item> {
54        type Output;
55        fn impl_push(input: Input, elem: Item) -> Self::Output;
56    }
57
58    impl<T, S> PushImpl<Vect<T, S>, T> for ()
59    where
60        S: Size,
61        (): Push<Vect<T, S>>,
62        PushOp<Vect<T, S>>: VectFactory<T>,
63    {
64        type Output = PushOp<Vect<T, S>>;
65
66        fn impl_push(input: Vect<T, S>, item: T) -> Self::Output {
67            let mut data = input.data;
68            data.push(item);
69            PushOp::<Vect<T, S>>::from_vec(data)
70        }
71    }
72
73    pub type PushImplOp<Input, Item> = <() as PushImpl<Input, Item>>::Output;
74}
75
76// pop
77pub use pop::{PopImpl, PopImplOp};
78
79mod pop {
80    use super::*;
81
82    /// Implements dropping an element at the end of vector.
83    pub trait PopImpl<Input> {
84        type Output;
85        fn impl_pop(input: Input) -> Self::Output;
86    }
87
88    impl<Input> PopImpl<Input> for ()
89    where
90        (): PopPrivate<Input, PopOp<Input>> + Pop<Input>,
91    {
92        type Output = <() as PopPrivate<Input, PopOp<Input>>>::Output;
93
94        fn impl_pop(input: Input) -> Self::Output {
95            <() as PopPrivate<Input, PopOp<Input>>>::impl_pop(input)
96        }
97    }
98
99    pub type PopImplOp<Input> = <() as PopImpl<Input>>::Output;
100
101    pub trait PopPrivate<Input, Out> {
102        type Output;
103        fn impl_pop(input: Input) -> Self::Output;
104    }
105
106    impl<T, S, Output> PopPrivate<Vect<T, S>, Option<Output>> for ()
107    where
108        S: Size,
109        Output: VectFactory<T>,
110    {
111        type Output = Option<(Output, T)>;
112
113        fn impl_pop(input: Vect<T, S>) -> Self::Output {
114            let mut data = input.data;
115            let elem = data.pop()?;
116            Some((Output::from_vec(data), elem))
117        }
118    }
119
120    impl<T, S1, S2> PopPrivate<Vect<T, S1>, Vect<T, S2>> for ()
121    where
122        S1: Size,
123        S2: Size,
124        Vect<T, S2>: VectFactory<T>,
125    {
126        type Output = (Vect<T, S2>, T);
127
128        fn impl_pop(input: Vect<T, S1>) -> Self::Output {
129            let mut data = input.data;
130            let elem = data.pop().unwrap();
131            (Vect::<T, S2>::from_vec(data), elem)
132        }
133    }
134}
135
136// get
137
138pub use get::{GetImpl, GetImplOp};
139
140mod get {
141    use super::*;
142
143    /// Implements accessing an vector on vector by type level index.
144    pub trait GetImpl<'a, Input, Index> {
145        type Output;
146        fn impl_get(input: &'a Input, index: Index) -> Self::Output;
147    }
148
149    impl<'a, T, S, Index> GetImpl<'a, Vect<T, S>, Index> for ()
150    where
151        S: Size,
152        Index: Size,
153        (): GetPrivate<'a, Vect<T, S>, Index, size::CheckIndexOp<S, Index>>
154            + size::CheckIndex<S, Index>,
155    {
156        type Output =
157            <() as GetPrivate<'a, Vect<T, S>, Index, size::CheckIndexOp<S, Index>>>::Output;
158
159        fn impl_get(input: &'a Vect<T, S>, index: Index) -> Self::Output {
160            <() as GetPrivate<'a, Vect<T, S>, Index, size::CheckIndexOp<S, Index>>>::impl_get(
161                input, index,
162            )
163        }
164    }
165
166    pub type GetImplOp<'a, Input, Index> = <() as GetImpl<'a, Input, Index>>::Output;
167
168    pub trait GetPrivate<'a, Input, Index, Out> {
169        type Output;
170        fn impl_get(input: &'a Input, index: Index) -> Self::Output;
171    }
172
173    impl<'a, T, S, Index> GetPrivate<'a, Vect<T, S>, Index, ()> for ()
174    where
175        T: 'a,
176        S: Size,
177        Index: Unsigned + Size,
178    {
179        type Output = &'a T;
180
181        fn impl_get(input: &'a Vect<T, S>, _index: Index) -> Self::Output {
182            unsafe { input.data.get_unchecked(Index::USIZE) }
183        }
184    }
185
186    impl<'a, T, S, Index> GetPrivate<'a, Vect<T, S>, Index, Option<()>> for ()
187    where
188        T: 'a,
189        S: Size,
190        Index: Size,
191    {
192        type Output = Option<&'a T>;
193
194        fn impl_get(input: &'a Vect<T, S>, index: Index) -> Self::Output {
195            input.data.get(index.to_usize())
196        }
197    }
198}
199
200// insert
201
202pub use insert::{InsertImpl, InsertImplOp};
203
204mod insert {
205    use super::*;
206
207    /// Implements element insertion to a vector.
208    pub trait InsertImpl<Input, Index, Item> {
209        type Output;
210        fn impl_insert(input: Input, index: Index, item: Item) -> Self::Output;
211    }
212    pub type InsertImplOp<Input, Index, Item> = <() as InsertImpl<Input, Index, Item>>::Output;
213
214    impl<S, Index, Item> InsertImpl<Vect<Item, S>, Index, Item> for ()
215    where
216        S: Size,
217        Index: Size,
218        (): size::IncreaseOne<S> + size::CheckIndexInclusive<S, Index>,
219    {
220        type Output = Vect<Item, size::IncreaseOneOp<S>>;
221
222        fn impl_insert(input: Vect<Item, S>, index: Index, item: Item) -> Self::Output {
223            let mut data = input.data;
224            data.insert(index.to_usize(), item);
225            <Self::Output as VectFactory<Item>>::from_vec(data)
226        }
227    }
228}
229
230// remove
231
232pub use remove::{RemoveImpl, RemoveImplOp};
233
234mod remove {
235    use super::*;
236
237    /// Implements element removal from a vector.
238    pub trait RemoveImpl<Input, Index> {
239        type Output;
240        fn impl_remove(input: Input, index: Index) -> Self::Output;
241    }
242    pub type RemoveImplOp<Input, Index> = <() as RemoveImpl<Input, Index>>::Output;
243
244    impl<S, Index, Item> RemoveImpl<Vect<Item, S>, Index> for ()
245    where
246        S: Size,
247        Index: Size,
248        (): size::DecreaseOne<S> + size::CheckIndex<S, Index>,
249    {
250        type Output = (Vect<Item, size::DecreaseOneOp<S>>, Item);
251
252        fn impl_remove(input: Vect<Item, S>, index: Index) -> Self::Output {
253            let mut data = input.data;
254            let item = data.remove(index.to_usize());
255            (
256                <Vect<Item, size::DecreaseOneOp<S>> as VectFactory<Item>>::from_vec(data),
257                item,
258            )
259        }
260    }
261}