1use std::{
18	alloc,
19	alloc::Layout,
20	borrow::{Borrow, BorrowMut},
21	cell::Cell,
22	fmt,
23	mem::{self, ManuallyDrop},
24	ops::{Deref, DerefMut},
25	ptr,
26	ptr::NonNull,
27};
28
29pub struct ConstVec<T> {
31	ptr: NonNull<T>,
32	capacity: usize,
33	len: Cell<usize>,
34}
35
36impl<T> ConstVec<T> {
37	pub fn new(capacity: usize) -> ConstVec<T> {
39		let ptr = if capacity == 0 {
40			NonNull::dangling()
41		} else {
42			let layout = Layout::array::<T>(capacity).unwrap();
43			let ptr = unsafe { alloc::alloc(layout) };
44			match NonNull::new(ptr as *mut T) {
45				Some(ptr) => ptr,
46				None => alloc::handle_alloc_error(layout),
47			}
48		};
49
50		ConstVec {
51			ptr,
52			capacity,
53			len: Cell::new(0),
54		}
55	}
56
57	#[inline]
90	pub unsafe fn from_raw_parts(ptr: *mut T, len: usize, capacity: usize) -> Self {
91		Self {
92			ptr: NonNull::new_unchecked(ptr),
93			len: Cell::new(len),
94			capacity,
95		}
96	}
97
98	pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
135		let mut me = ManuallyDrop::new(self);
136		(me.as_mut_ptr(), me.len(), me.capacity())
137	}
138
139	#[inline]
140	pub fn capacity(&self) -> usize {
141		self.capacity
142	}
143
144	#[inline]
145	pub fn len(&self) -> usize {
146		self.len.get()
147	}
148
149	#[inline]
150	pub fn is_empty(&self) -> bool {
151		self.len() == 0
152	}
153
154	#[inline]
155	pub fn as_ptr(&self) -> *const T {
156		self.ptr.as_ptr()
157	}
158
159	#[inline]
160	pub fn as_mut_ptr(&mut self) -> *mut T {
161		self.ptr.as_ptr()
162	}
163
164	#[inline]
165	pub fn as_slice(&self) -> &[T] {
166		unsafe { std::slice::from_raw_parts(self.as_ptr(), self.len()) }
167	}
168
169	#[inline]
170	pub fn as_mut_slice(&mut self) -> &mut [T] {
171		unsafe { std::slice::from_raw_parts_mut(self.as_mut_ptr(), self.len()) }
172	}
173
174	#[inline]
175	pub fn push(&self, value: T) {
176		if self.len() < self.capacity() {
177			unsafe {
178				let len = self.len.get();
179				let end = self.ptr.as_ptr().add(len);
180				std::ptr::write(end, value);
181				self.len.set(len + 1);
182			}
183		} else {
184			panic!("not enough capacity")
185		}
186	}
187
188	#[inline]
204	pub fn pop(&mut self) -> Option<T> {
205		if self.len.get() == 0 {
206			None
207		} else {
208			unsafe {
209				self.len.set(self.len.get() - 1);
210				Some(ptr::read(self.as_ptr().add(self.len())))
211			}
212		}
213	}
214
215	pub fn append(&self, other: &mut Vec<T>) {
237		if self.len() + other.len() <= self.capacity() {
238			unsafe {
239				self.append_elements(other.as_slice() as _);
240				other.set_len(0)
241			}
242		} else {
243			panic!("not enough capacity")
244		}
245	}
246
247	#[cfg(not(no_global_oom_handling))]
252	#[inline]
253	unsafe fn append_elements(&self, other: *const [T]) {
254		let count = unsafe { (*other).len() };
255		let len = self.len();
256		unsafe { ptr::copy_nonoverlapping(other as *const T, self.ptr.as_ptr().add(len), count) };
257		self.len.set(len + count);
258	}
259
260	#[inline]
279	pub fn clear(&mut self) {
280		let elems: *mut [T] = self.as_mut_slice();
281
282		unsafe {
289			self.len.set(0);
290			ptr::drop_in_place(elems);
291		}
292	}
293}
294
295impl<T> IntoIterator for ConstVec<T> {
296	type IntoIter = IntoIter<T>;
297	type Item = T;
298
299	fn into_iter(self) -> Self::IntoIter {
300		let iter = IntoIter {
301			ptr: self.ptr,
302			capacity: self.capacity,
303			start: self.ptr.as_ptr(),
304			end: unsafe { self.ptr.as_ptr().add(self.len()) },
305		};
306
307		mem::forget(self);
308		iter
309	}
310}
311
312impl<'a, T> IntoIterator for &'a ConstVec<T> {
313	type IntoIter = std::slice::Iter<'a, T>;
314	type Item = &'a T;
315
316	fn into_iter(self) -> Self::IntoIter {
317		self.iter()
318	}
319}
320
321impl<T: Clone> Clone for ConstVec<T> {
322	fn clone(&self) -> Self {
323		let result = Self::new(self.capacity);
324
325		for item in self {
326			result.push(item.clone())
327		}
328
329		result
330	}
331}
332
333impl<T> AsRef<[T]> for ConstVec<T> {
334	fn as_ref(&self) -> &[T] {
335		self.as_slice()
336	}
337}
338
339impl<T> AsMut<[T]> for ConstVec<T> {
340	fn as_mut(&mut self) -> &mut [T] {
341		self.as_mut_slice()
342	}
343}
344
345impl<T> Borrow<[T]> for ConstVec<T> {
346	fn borrow(&self) -> &[T] {
347		self.as_slice()
348	}
349}
350
351impl<T> BorrowMut<[T]> for ConstVec<T> {
352	fn borrow_mut(&mut self) -> &mut [T] {
353		self.as_mut_slice()
354	}
355}
356
357impl<T> Deref for ConstVec<T> {
358	type Target = [T];
359
360	#[inline]
361	fn deref(&self) -> &[T] {
362		self.as_slice()
363	}
364}
365
366impl<T> DerefMut for ConstVec<T> {
367	#[inline]
368	fn deref_mut(&mut self) -> &mut [T] {
369		self.as_mut_slice()
370	}
371}
372
373impl<T> Drop for ConstVec<T> {
374	fn drop(&mut self) {
375		if self.capacity != 0 {
376			unsafe {
377				ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len()));
381
382				let layout = Layout::array::<T>(self.capacity).unwrap();
383				alloc::dealloc(self.ptr.as_ptr() as *mut u8, layout);
384			}
385		}
386	}
387}
388
389impl<T: fmt::Debug> fmt::Debug for ConstVec<T> {
390	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391		fmt::Debug::fmt(&**self, f)
392	}
393}
394
395impl<T: PartialEq<U>, U> PartialEq<[U]> for ConstVec<T> {
396	#[inline]
397	fn eq(&self, other: &[U]) -> bool {
398		*self.as_slice() == *other
399	}
400}
401
402impl<'a, T: PartialEq<U>, U> PartialEq<&'a [U]> for ConstVec<T> {
403	#[inline]
404	fn eq(&self, other: &&'a [U]) -> bool {
405		*self.as_slice() == **other
406	}
407}
408
409impl<T: PartialEq<U>, U, const N: usize> PartialEq<[U; N]> for ConstVec<T> {
410	#[inline]
411	fn eq(&self, other: &[U; N]) -> bool {
412		*self.as_slice() == *other
413	}
414}
415
416impl<'a, T: PartialEq<U>, U, const N: usize> PartialEq<&'a [U; N]> for ConstVec<T> {
417	#[inline]
418	fn eq(&self, other: &&'a [U; N]) -> bool {
419		*self.as_slice() == **other
420	}
421}
422
423impl<T: PartialEq<U>, U> PartialEq<ConstVec<U>> for ConstVec<T> {
424	#[inline]
425	fn eq(&self, other: &ConstVec<U>) -> bool {
426		*self.as_slice() == *other.as_slice()
427	}
428}
429
430impl<T> From<Vec<T>> for ConstVec<T> {
431	fn from(value: Vec<T>) -> Self {
432		let mut value = ManuallyDrop::new(value);
433		let ptr = value.as_mut_ptr();
434		let len = value.len();
435		let capacity = value.capacity();
436		unsafe { Self::from_raw_parts(ptr, len, capacity) }
437	}
438}
439
440impl<T> From<ConstVec<T>> for Vec<T> {
441	fn from(value: ConstVec<T>) -> Self {
442		let (ptr, len, capacity) = value.into_raw_parts();
443		unsafe { Vec::from_raw_parts(ptr, len, capacity) }
444	}
445}
446
447pub struct IntoIter<T> {
448	ptr: NonNull<T>,
449	capacity: usize,
450	start: *mut T,
451	end: *mut T,
452}
453
454impl<T> IntoIter<T> {
455	#[inline]
456	pub fn len(&self) -> usize {
457		(self.end as usize - self.start as usize) / mem::size_of::<T>()
458	}
459
460	#[inline]
461	pub fn is_empty(&self) -> bool {
462		self.start == self.end
463	}
464
465	#[inline]
466	pub fn as_ptr(&self) -> *const T {
467		self.start
468	}
469
470	#[inline]
471	pub fn as_mut_ptr(&mut self) -> *mut T {
472		self.start
473	}
474
475	#[inline]
476	pub fn as_slice(&self) -> &[T] {
477		unsafe { std::slice::from_raw_parts(self.as_ptr(), self.len()) }
478	}
479
480	#[inline]
481	pub fn as_mut_slice(&mut self) -> &mut [T] {
482		unsafe { std::slice::from_raw_parts_mut(self.as_mut_ptr(), self.len()) }
483	}
484}
485
486impl<T> Iterator for IntoIter<T> {
487	type Item = T;
488
489	fn size_hint(&self) -> (usize, Option<usize>) {
490		let len = self.len();
491		(len, Some(len))
492	}
493
494	fn next(&mut self) -> Option<Self::Item> {
495		if self.start == self.end {
496			None
497		} else {
498			unsafe {
499				let result = ptr::read(self.start);
500				self.start = self.start.offset(1);
501				Some(result)
502			}
503		}
504	}
505}
506
507impl<T> ExactSizeIterator for IntoIter<T> {}
508
509impl<T> DoubleEndedIterator for IntoIter<T> {
510	fn next_back(&mut self) -> Option<Self::Item> {
511		if self.start == self.end {
512			None
513		} else {
514			unsafe {
515				self.end = self.end.offset(-1);
516				Some(ptr::read(self.end))
517			}
518		}
519	}
520}
521
522impl<T> Drop for IntoIter<T> {
523	fn drop(&mut self) {
524		if self.capacity != 0 {
525			unsafe {
526				ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len()));
530
531				let layout = Layout::array::<T>(self.capacity).unwrap();
532				alloc::dealloc(self.ptr.as_ptr() as *mut u8, layout);
533			}
534		}
535	}
536}