1use std::ptr::NonNull;
2use std::marker::PhantomData;
3use std::ops::Add;
4use std::mem;
5
6use std::alloc::{handle_alloc_error, Allocator, Global, Layout};
7
8pub struct RawTwoSidedVec<T> {
9 middle: NonNull<T>,
10 marker: PhantomData<T>,
11 capacity: Capacity
12}
13impl<T> RawTwoSidedVec<T> {
14 #[inline]
15 pub fn new() -> Self {
16 assert_ne!(mem::size_of::<T>(), 0, "Zero sized type!");
17 RawTwoSidedVec {
18 middle: NonNull::dangling(),
19 marker: PhantomData,
20 capacity: Capacity { back: 0, front: 0 }
21 }
22 }
23 pub fn with_capacity(capacity: Capacity) -> Self {
24 assert_ne!(mem::size_of::<T>(), 0, "Zero sized type!");
25 if capacity.is_empty() {
26 return RawTwoSidedVec::new()
27 }
28 let heap = Global::default();
29 let layout = capacity.layout::<T>();
30 unsafe {
31 let memory = heap.allocate(layout)
32 .unwrap_or_else(|_| handle_alloc_error(layout));
33 let middle = (memory.as_ptr() as *mut T).add(capacity.back);
34 RawTwoSidedVec::from_raw_parts(
35 middle,
36 capacity
37 )
38 }
39 }
40 #[inline]
46 pub unsafe fn from_raw_parts(middle: *mut T, capacity: Capacity) -> Self {
47 assert_ne!(mem::size_of::<T>(), 0, "Zero sized type!");
48 debug_assert!(!middle.is_null());
49 RawTwoSidedVec { middle: NonNull::new_unchecked(middle), marker: PhantomData, capacity }
50 }
51 #[inline]
52 pub fn capacity(&self) -> &Capacity {
53 &self.capacity
54 }
55 #[inline]
56 pub fn middle(&self) -> *mut T {
57 self.middle.as_ptr()
58 }
59 #[inline]
61 fn alloc_start(&self) -> *mut T {
62 unsafe { self.middle.as_ptr().sub(self.capacity.back) }
63 }
64 pub fn reserve(&mut self, request: CapacityRequest) {
65 assert!(self.capacity.can_fit(request.used));
66 let requested_capacity = request.used + request.needed;
67 unsafe {
68 let result = Self::with_capacity(requested_capacity);
70 result.middle().sub(request.used.back).copy_from_nonoverlapping(
71 self.middle().sub(request.used.back),
72 request.used.back
73 );
74 result.middle().copy_from_nonoverlapping(
75 self.middle(),
76 request.used.front
77 );
78 *self = result; }
80 debug_assert!(self.capacity.can_fit(requested_capacity));
81 }
82}
83unsafe impl<#[may_dangle] T> Drop for RawTwoSidedVec<T> {
84 #[inline]
85 fn drop(&mut self) {
86 if !self.capacity.is_empty() {
87 let heap = Global::default();
88 unsafe {
89 let layout = self.capacity.layout::<T>();
90 heap.deallocate(
91 NonNull::new_unchecked(self.alloc_start() as *mut u8),
92 layout
93 );
94 }
95 }
96 }
97}
98#[derive(Copy, Clone, Debug)]
99pub struct Capacity {
100 pub back: usize,
101 pub front: usize
102}
103impl Capacity {
104 #[inline]
105 pub fn empty() -> Self {
106 Capacity { back: 0, front: 0 }
107 }
108 #[inline]
109 pub fn checked_total(&self) -> usize {
110 self.back.checked_add(self.front).expect("Capacity overflow")
111 }
112 #[inline]
113 pub fn total(&self) -> usize {
114 self.back + self.front
115 }
116 #[inline]
117 pub fn can_fit(&self, other: Capacity) -> bool {
118 self.back >= other.back && self.front >= other.front
119 }
120 #[inline]
121 fn layout<T>(&self) -> Layout {
122 Layout::array::<T>(self.checked_total()).expect("Capacity overflow")
123 }
124 #[inline]
125 pub fn is_empty(&self) -> bool {
126 self.back == 0 && self.front == 0
127 }
128}
129impl Add for Capacity {
130 type Output = Capacity;
131
132 #[inline]
133 fn add(self, rhs: Capacity) -> Capacity {
134 match (self.front.checked_add(rhs.front), self.back.checked_add(rhs.back)) {
135 (Some(front), Some(back)) => Capacity { front, back },
136 _ => panic!("Capacity overflow")
137 }
138 }
139}
140#[derive(Copy, Clone, Debug)]
141pub struct CapacityRequest {
142 pub used: Capacity,
143 pub needed: Capacity
144}