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}