nanvm_lib/mem/flexible_array/
constructor.rs1use crate::{common::ref_mut::RefMut, mem::constructor::Constructor};
2
3use super::{header::FlexibleArrayHeader, FlexibleArray};
4
5pub struct FlexibleArrayConstructor<H: FlexibleArrayHeader, I: Iterator> {
6 header: H,
7 items: I,
8}
9
10impl<H: FlexibleArrayHeader, I: Iterator> FlexibleArrayConstructor<H, I> {
11 pub fn new(header: H, items: I) -> Self {
12 Self { header, items }
13 }
14}
15
16impl<H: FlexibleArrayHeader, I: Iterator> Constructor for FlexibleArrayConstructor<H, I> {
17 type Result = FlexibleArray<I::Item, H>;
18 #[inline(always)]
19 fn result_size(&self) -> usize {
20 Self::Result::flexible_size(self.header.len())
21 }
22 unsafe fn construct(self, p: *mut Self::Result) {
23 let v = &mut *p;
24 v.header.to_mut_ptr().write(self.header);
25 let mut src = self.items;
26 for dst in v.items_mut() {
27 dst.to_mut_ptr().write(src.next().unwrap());
28 }
29 }
30}
31
32impl<I: ExactSizeIterator> From<I> for FlexibleArrayConstructor<usize, I> {
33 #[inline(always)]
34 fn from(items: I) -> Self {
35 items.len().constructor(items)
36 }
37}
38
39#[cfg(test)]
40mod test {
41 use core::{mem::size_of, ptr::null_mut};
42
43 use wasm_bindgen_test::wasm_bindgen_test;
44
45 use crate::{
46 common::ref_mut::RefMut,
47 mem::{
48 constructor::Constructor, flexible_array::header::FlexibleArrayHeader, object::Object,
49 },
50 };
51
52 use super::FlexibleArrayConstructor;
53
54 #[repr(C)]
55 struct StaticVariable<T: FlexibleArrayHeader, I, const L: usize> {
56 header: T,
57 items: [I; L],
58 }
59
60 fn gen_test(t: usize) {
61 struct Header(u8, *mut u8);
62 impl Drop for Header {
63 fn drop(&mut self) {
64 unsafe {
65 *self.1 += 1;
66 }
67 }
68 }
69 impl FlexibleArrayHeader for Header {
70 fn len(&self) -> usize {
71 self.0 as usize
72 }
73 }
74 let mut i = 0;
75 {
76 let new = FlexibleArrayConstructor {
77 header: Header(5, &mut i),
78 items: [42u8, 43, 44, 45, 46, 47, 48].into_iter().take(t),
79 };
80 {
81 let mut mem = StaticVariable::<Header, u8, 5> {
82 header: Header(0, null_mut()),
83 items: [0; 5],
84 };
85 let v = unsafe { mem.to_mut_ptr() as *mut _ };
86 unsafe { new.construct(v) };
87 let r = unsafe { &mut *v };
88 assert_eq!(mem.header.len(), 5);
89 assert_eq!(r.header.len(), 5);
90 assert_eq!(mem.header.0, 5);
91 assert_eq!(r.header.0, 5);
92 assert_eq!(mem.header.1, unsafe { i.to_mut_ptr() });
93 assert_eq!(r.header.1, unsafe { i.to_mut_ptr() });
94 assert_eq!(r.object_size(), size_of::<usize>() * 2 + 5);
95 assert_eq!(mem.items, [42, 43, 44, 45, 46]);
96 assert_eq!(r.items_mut(), &[42, 43, 44, 45, 46]);
97 assert_eq!(i, 0);
98 unsafe { (*v).object_drop() };
99 assert_eq!(i, 1);
100 }
101 assert_eq!(i, 2);
102 }
103 assert_eq!(i, 2);
104 }
105
106 #[test]
107 #[wasm_bindgen_test]
108 fn test_5() {
109 gen_test(5);
110 }
111
112 #[test]
113 #[wasm_bindgen_test]
114 fn test_10() {
115 gen_test(10);
116 }
117
118 #[test]
119 #[should_panic]
120 #[wasm_bindgen_test]
121 fn test_2() {
122 gen_test(2);
123 }
124}