static_collections/
vec.rs1use core::{mem::MaybeUninit, ops::{Deref, DerefMut}, ptr, slice};
4
5#[derive(Debug)]
6pub struct StaticVec<const N:usize,T>
7{
8 length:usize,
9 buff:MaybeUninit<[T;N]>
10}
11
12impl<const N:usize,T:Copy> Clone for StaticVec<N,T>
13{
14 fn clone(&self) -> Self
15 {
16 Self
17 {
18 length:self.length,
19 buff:self.buff
20 }
21 }
22}
23
24impl<const N:usize,T> Default for StaticVec<N,T>
25{
26 fn default() -> Self
27 {
28 Self::new()
29 }
30}
31
32impl<const N:usize,T> StaticVec<N,T>
33{
34 pub const fn new()->Self
44 {
45 Self
46 {
47 length:0,
48 buff:MaybeUninit::uninit()
49 }
50 }
51
52 pub const fn as_slice(&self)->&[T]
53 {
54 unsafe
55 {
56 slice::from_raw_parts(self.as_ptr(),self.length)
57 }
58 }
59
60 pub const fn as_mut_slice(&mut self)->&mut [T]
61 {
62 unsafe
63 {
64 slice::from_raw_parts_mut(self.as_mut_ptr(),self.length)
65 }
66 }
67
68 pub const fn as_ptr(&self)->*const T
69 {
70 unsafe
71 {
72 self.buff.assume_init_ref().as_ptr()
73 }
74 }
75
76 pub const fn as_mut_ptr(&mut self)->*mut T
77 {
78 unsafe
79 {
80 self.buff.assume_init_mut().as_mut_ptr()
81 }
82 }
83
84 pub fn push(&mut self,v:T)
96 {
97 if self.length<N
98 {
99 unsafe
100 {
101 let vector=self.buff.assume_init_mut();
102 ptr::write(&raw mut vector[self.length],v);
104 }
105 self.length+=1;
106 }
107 }
108
109 pub fn pop(&mut self)->T
119 {
120 if self.length>0
121 {
122 self.length-=1;
123 unsafe
125 {
126 ptr::read(self.as_ptr().add(self.length))
127 }
128 }
129 else
130 {
131 panic!("popping a value from an empty static vector!");
132 }
133 }
134
135 pub fn insert(&mut self,index:usize,v:T)
147 {
148 if self.length<N && index<=self.length
149 {
150 unsafe
152 {
153 let p=self.as_mut_ptr().add(index);
154 ptr::copy(p,p.add(1),self.length-index);
155 ptr::write(p,v);
156 }
157 self.length+=1;
158 }
159 }
160
161 pub fn remove(&mut self,index:usize)->T
174 {
175 if self.length>index
176 {
177 unsafe
179 {
180 let p=self.as_mut_ptr().add(index);
181 let v=ptr::read(self.as_ptr().add(index));
182 ptr::copy(p.add(1),p,self.length-index-1);
183 self.length-=1;
184 v
185 }
186 }
187 else
188 {
189 panic!("removal index ({index}) is out of bound ({})!",self.length);
190 }
191 }
192
193 pub fn truncate(&mut self,new_len:usize)
209 {
210 if new_len<self.length
211 {
212 self.length=new_len;
213 }
214 }
215
216 pub fn clear(&mut self)
228 {
229 for item in self.as_mut_slice()
230 {
231 drop(unsafe{ptr::read(item)});
233 }
234 self.length=0;
235 }
236
237 pub fn is_empty(&self)->bool
250 {
251 self.len()==0
252 }
253
254 pub const fn len(&self)->usize
265 {
266 self.length
267 }
268
269 pub const fn capacity(&self)->usize
278 {
279 N
280 }
281
282 pub const unsafe fn force_assign(&mut self,index:usize,value:T)
292 {
293 assert!(index<N);
294 unsafe
295 {
296 ptr::write(self.buff.assume_init_mut().as_mut_ptr().add(index),value);
297 }
298 }
299
300 pub const unsafe fn force_resize(&mut self,length:usize)
311 {
312 assert!(length<=N,"The new length exceeds capacity!");
313 self.length=length;
314 }
315}
316
317impl<const N:usize,T> Drop for StaticVec<N,T>
318{
319 fn drop(&mut self)
320 {
321 self.clear();
322 }
323}
324
325impl<const N:usize,T> Deref for StaticVec<N,T>
326{
327 type Target = [T];
328
329 fn deref(&self) -> &Self::Target
330 {
331 self.as_slice()
332 }
333}
334
335impl<const N:usize,T> DerefMut for StaticVec<N,T>
336{
337 fn deref_mut(&mut self) -> &mut Self::Target
338 {
339 self.as_mut_slice()
340 }
341}
342
343#[macro_export] macro_rules! vec_static
355{
356 ()=>
357 (
358 $crate::vec::StaticVec::new()
359 );
360 ($elem:expr;$len:expr)=>
361 (
362 {
363 let mut v=StaticVec::new();
364 unsafe
365 {
366 let mut i:usize=0;
367 while i<$len
368 {
369 v.force_assign(i,$elem);
370 i+=1;
371 }
372 v.force_resize($len);
373 }
374 v
375 }
376 );
377 ($($x:expr),+$(,)?)=>
378 (
379 {
380 let mut v=StaticVec::new();
381 let mut index:usize=0;
382 unsafe
383 {
384 $(
385 {
386 v.force_assign(index,$x);
387 index+=1;
388 }
389 )*
390 v.force_resize(index);
391 }
392 v
393 }
394 );
395}
396
397#[cfg(test)] mod test
398{
399 extern crate std;
400
401 use std::println;
402 use crate::vec::StaticVec;
403
404 #[should_panic]
405 #[test] fn vec_macro_overflow()
406 {
407 let x:StaticVec<12,u64>=vec_static![1234;16];
408 println!("{x:?}")
409 }
410
411 #[test] fn clone()
412 {
413 let x:StaticVec<16,u64>=vec_static![1,2,3,4,5,6,7,8,9,10];
414 assert_eq!(x.len(),10);
415 let y=x.clone();
416 assert_eq!(*y,[1,2,3,4,5,6,7,8,9,10]);
417 }
418
419 #[test] fn drop()
420 {
421 use core::sync::atomic::{AtomicUsize,Ordering};
422
423 struct DropCounter<'a>
424 {
425 counter:&'a AtomicUsize
426 }
427
428 impl<'a> Drop for DropCounter<'a>
429 {
430 fn drop(&mut self)
431 {
432 self.counter.fetch_add(1,Ordering::SeqCst);
433 }
434 }
435
436 let drop_count:AtomicUsize=AtomicUsize::new(0);
437 {
438 let mut v:StaticVec<8,DropCounter>=StaticVec::new();
439 v.push(DropCounter{counter:&drop_count});
440 v.push(DropCounter{counter:&drop_count});
441 assert_eq!(drop_count.load(Ordering::SeqCst),0);
442 v.pop();
443 assert_eq!(drop_count.load(Ordering::SeqCst),1);
444 v.clear();
445 assert_eq!(drop_count.load(Ordering::SeqCst),2);
446 v.push(DropCounter{counter:&drop_count});
447 v.push(DropCounter{counter:&drop_count});
448 assert_eq!(drop_count.load(Ordering::SeqCst),2);
449 }
450 assert_eq!(drop_count.load(Ordering::SeqCst),4);
451 }
452}