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