1#![no_std]
7
8#![feature(allocator_api)]
10#![feature(const_trait_impl)]
11#![feature(const_destruct)]
12#![feature(const_cmp)]
13#![feature(const_default)]
14#![feature(const_heap)]
15#![feature(const_convert)]
16#![feature(const_slice_make_iter)]
17#![feature(const_iter)]
18#![feature(test)]
19#![feature(const_result_trait_fn)]
20#![feature(const_result_unwrap_unchecked)]
21
22extern crate alloc;
24extern crate test;
25
26#[cfg(test)]
28mod benches;
29mod conversions;
30mod iterators;
31mod references;
32#[cfg(test)]
33mod tests;
34
35use core::{
37 fmt::{
38 Debug,
39 Formatter,
40 Result as Format
41 },
42 alloc::{
43 Allocator,
44 Layout
45 },
46 slice::Iter,
47 marker::Destruct
48};
49
50use alloc::alloc::Global;
52
53use libutils_pointer::Pointer;
55
56
57#[derive(Clone)]
63pub struct Log<Type> {
64 pointer: Pointer<Type>,
65 length: usize,
66 capacity: usize
67}
68
69impl<Type> Log<Type> {
71 #[inline]
72 const fn grow(&mut self) -> () {
73 self.pointer = match self.pointer.take() {
74 None => Global.allocate(Layout::from_size_align(size_of::<Type>(), align_of::<Type>()).ok().unwrap()),
75 Some(pointer) => unsafe {Global.grow(
76 pointer.cast(),
77 Layout::from_size_align(self.capacity * size_of::<Type>(), align_of::<Type>()).ok().unwrap(),
78 Layout::from_size_align(self.capacity * 2 * size_of::<Type>(), align_of::<Type>()).ok().unwrap()
79 )}
80 }.ok().unwrap().cast().into();
81 self.capacity = (self.capacity * 2).max(1);
82 }
83 #[inline]
84 pub const fn new() -> Self {return Self::default()}
85 #[inline]
86 pub const fn len(&self) -> usize {return self.length}
87 #[inline]
88 pub const fn is_empty(&self) -> bool {return self.length == 0}
89 #[inline]
90 pub const fn iter<'valid>(&'valid self) -> Iter<'valid, Type> {return self.as_ref().iter()}
91}
92
93const impl<Type: [const] Destruct> Log<Type> {
95 #[inline]
96 pub fn push(&mut self, value: Type) -> () {
97 if self.length == self.capacity {self.grow()}
98 unsafe {self.pointer.add(self.length).write(value)};
99 self.length += 1;
100 }
101}
102
103const impl<Type> Default for Log<Type> {
105 fn default() -> Self {return Self {
106 pointer: Pointer::default(),
107 length: 0,
108 capacity: 0
109 }}
110}
111
112impl<Type> Extend<Type> for Log<Type> {
114 #[inline]
115 fn extend<T: IntoIterator<Item = Type>>(&mut self, iter: T) {iter.into_iter().for_each(|item| self.push(item))}
116}
117
118impl<Type: Debug> Debug for Log<Type> {
120 fn fmt(&self, formatter: &mut Formatter<'_>) -> Format {Debug::fmt(self.as_ref(), formatter)}
121}
122
123impl<Type> Drop for Log<Type> {
125 fn drop(&mut self) {if let Some(pointer) = self.pointer.take() {
126 for index in 0..self.length {drop(unsafe {pointer.add(index).read()})}
127 unsafe {Global.deallocate(pointer.cast(), Layout::from_size_align(self.capacity * size_of::<Type>(), align_of::<Type>()).unwrap());}
128 }}
129}