Skip to main content

nibblecode/
list.rs

1use core::borrow::Borrow;
2use core::cmp::Ordering;
3use core::fmt::{self, Debug};
4use core::hash::{Hash, Hasher};
5use core::marker::PhantomData;
6use core::ops::{Deref, DerefMut, Index, IndexMut};
7use core::slice;
8use core::slice::SliceIndex;
9
10use crate::primitive::ArchivedUsize;
11
12pub struct ArchivedList<T> {
13	pub(crate) len: ArchivedUsize,
14	pub(crate) offset: ArchivedUsize,
15	_phantom_data: PhantomData<T>,
16}
17impl<T> ArchivedList<T> {
18	/// Create a new `ArchivedList` from its parts.
19	///
20	/// # Safety
21	/// `len` and `offset` must be small enough to fit in `FixedUsize`s
22	pub(crate) unsafe fn new(len: usize, offset: usize) -> ArchivedList<T> {
23		ArchivedList {
24			offset: ArchivedUsize::from_native(offset as _),
25			len: ArchivedUsize::from_native(len as _),
26			_phantom_data: PhantomData,
27		}
28	}
29
30	/// Returns a pointer to the first element of the archived vec.
31	#[must_use]
32	pub fn as_ptr(&self) -> *const T {
33		unsafe { <*const ArchivedList<T>>::cast::<u8>(self).add(self.offset.to_native() as usize) }
34			.cast()
35	}
36
37	/// Returns the number of elements in the archived vec.
38	#[must_use]
39	pub fn len(&self) -> ArchivedUsize {
40		self.len
41	}
42
43	/// Returns whether the archived vec is empty.
44	#[must_use]
45	pub fn is_empty(&self) -> bool {
46		self.len == 0
47	}
48
49	/// Gets the elements of the archived vec as a slice.
50	#[must_use]
51	pub fn as_slice(&self) -> &[T] {
52		unsafe { slice::from_raw_parts(self.as_ptr(), self.len.to_native() as usize) }
53	}
54
55	/// Gets the elements of the archived vec as a mutable slice.
56	#[must_use]
57	pub fn as_slice_mut(&mut self) -> &mut [T] {
58		unsafe {
59			slice::from_raw_parts_mut(self.as_ptr().cast_mut(), self.len.to_native() as usize)
60		}
61	}
62}
63
64impl<T> AsRef<[T]> for ArchivedList<T> {
65	fn as_ref(&self) -> &[T] {
66		self.as_slice()
67	}
68}
69
70impl<T> Borrow<[T]> for ArchivedList<T> {
71	fn borrow(&self) -> &[T] {
72		self.as_slice()
73	}
74}
75
76impl<T: Debug> Debug for ArchivedList<T> {
77	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78		f.debug_list().entries(self.as_slice()).finish()
79	}
80}
81
82impl<T> Deref for ArchivedList<T> {
83	type Target = [T];
84
85	fn deref(&self) -> &[T] {
86		self.as_slice()
87	}
88}
89
90impl<T> DerefMut for ArchivedList<T> {
91	fn deref_mut(&mut self) -> &mut [T] {
92		self.as_slice_mut()
93	}
94}
95
96impl<T: Eq> Eq for ArchivedList<T> {}
97
98impl<T: Hash> Hash for ArchivedList<T> {
99	fn hash<H: Hasher>(&self, state: &mut H) {
100		self.as_slice().hash(state);
101	}
102}
103
104impl<T, I: SliceIndex<[T]>> Index<I> for ArchivedList<T> {
105	type Output = <[T] as Index<I>>::Output;
106
107	fn index(&self, index: I) -> &<[T] as Index<I>>::Output {
108		self.as_slice().index(index)
109	}
110}
111
112impl<T, I: SliceIndex<[T]>> IndexMut<I> for ArchivedList<T> {
113	fn index_mut(&mut self, index: I) -> &mut <[T] as Index<I>>::Output {
114		self.as_slice_mut().index_mut(index)
115	}
116}
117
118impl<T: Ord> Ord for ArchivedList<T> {
119	fn cmp(&self, other: &ArchivedList<T>) -> Ordering {
120		self.as_slice().cmp(other.as_slice())
121	}
122}
123
124impl<T: PartialEq<U>, U> PartialEq<ArchivedList<U>> for ArchivedList<T> {
125	fn eq(&self, other: &ArchivedList<U>) -> bool {
126		self.as_slice().eq(other.as_slice())
127	}
128}
129
130impl<T: PartialEq<U>, U, const N: usize> PartialEq<[U; N]> for ArchivedList<T> {
131	fn eq(&self, other: &[U; N]) -> bool {
132		self.as_slice().eq(&other[..])
133	}
134}
135
136impl<T: PartialEq<U>, U, const N: usize> PartialEq<ArchivedList<T>> for [U; N] {
137	fn eq(&self, other: &ArchivedList<T>) -> bool {
138		other.eq(self)
139	}
140}
141
142impl<T: PartialEq<U>, U> PartialEq<[U]> for ArchivedList<T> {
143	fn eq(&self, other: &[U]) -> bool {
144		self.as_slice().eq(other)
145	}
146}
147
148impl<T: PartialEq<U>, U> PartialEq<ArchivedList<U>> for [T] {
149	fn eq(&self, other: &ArchivedList<U>) -> bool {
150		self.eq(other.as_slice())
151	}
152}
153
154impl<T: PartialOrd> PartialOrd<ArchivedList<T>> for ArchivedList<T> {
155	fn partial_cmp(&self, other: &ArchivedList<T>) -> Option<Ordering> {
156		self.as_slice().partial_cmp(other.as_slice())
157	}
158}
159
160impl<T: PartialOrd> PartialOrd<[T]> for ArchivedList<T> {
161	fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
162		self.as_slice().partial_cmp(other)
163	}
164}
165
166impl<T: PartialOrd> PartialOrd<ArchivedList<T>> for [T] {
167	fn partial_cmp(&self, other: &ArchivedList<T>) -> Option<Ordering> {
168		self.partial_cmp(other.as_slice())
169	}
170}