cel_runtime/
raw_sequence.rs1use crate::memory::align_index;
2use crate::raw_vec::RawVec;
3use std::mem;
4
5pub struct RawSequence {
12 buffer: RawVec,
13}
14
15impl Default for RawSequence {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20
21impl RawSequence {
22 #[must_use]
25 pub fn new() -> Self {
26 RawSequence {
27 buffer: RawVec::with_base_alignment(4096),
28 }
29 }
30
31 pub fn push<T>(&mut self, value: T) {
39 assert!(mem::align_of::<T>() <= 4096);
40 let len = self.buffer.len();
41 let aligned: usize = align_index(mem::align_of::<T>(), len);
42 let new_len = aligned + mem::size_of::<T>();
43
44 self.buffer.reserve(new_len - len);
45 unsafe {
46 self.buffer.set_len(new_len);
47 std::ptr::write(self.buffer.as_mut_ptr().add(aligned).cast::<T>(), value);
48 }
49 }
50
51 pub unsafe fn drop_in_place<T>(&mut self, p: usize) -> usize {
59 let aligned: usize = align_index(mem::align_of::<T>(), p);
60 unsafe { std::ptr::drop_in_place(self.buffer.as_ptr().add(aligned) as *mut T) };
61 aligned + mem::size_of::<T>()
62 }
63
64 #[must_use]
74 pub unsafe fn next<T>(&self, p: usize) -> (&T, usize) {
75 let aligned: usize = align_index(mem::align_of::<T>(), p);
76 let ptr = unsafe { self.buffer.as_ptr().add(aligned).cast::<T>() };
77 unsafe { (&*ptr, aligned + mem::size_of::<T>()) }
78 }
79
80 #[must_use]
82 pub fn len(&self) -> usize {
83 self.buffer.len()
84 }
85
86 #[must_use]
88 pub fn is_empty(&self) -> bool {
89 self.buffer.is_empty()
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
102
103 #[test]
104 fn sequence_operations() {
105 let mut seq = RawSequence::new();
106
107 seq.push(100u32);
108 seq.push(200u32);
109 seq.push(42.0f64);
110 seq.push("Hello, world!");
111
112 let (value, p) = unsafe { seq.next::<u32>(0) };
113 assert_eq!(*value, 100);
114 let (value, p) = unsafe { seq.next::<u32>(p) };
115 assert_eq!(*value, 200);
116 let (value, p) = unsafe { seq.next::<f64>(p) };
117 assert_eq!(*value, 42.0);
118 let (value, _) = unsafe { seq.next::<&str>(p) };
119 assert_eq!(*value, "Hello, world!");
120
121 let p = unsafe { seq.drop_in_place::<u32>(0) };
122 let p = unsafe { seq.drop_in_place::<u32>(p) };
123 let p = unsafe { seq.drop_in_place::<f64>(p) };
124 let _ = unsafe { seq.drop_in_place::<&str>(p) };
125 }
126}