1use crate::sealed::Sealed;
2use crate::AllocError;
3use std::alloc::{Allocator, Global};
4
5pub trait VecAllocExt<T, A: Allocator>: Sized + Sealed {
7 fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, AllocError>;
8 fn try_push(&mut self, value: T) -> Result<(), AllocError>;
9 fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), AllocError>
10 where
11 T: Copy;
12 fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), AllocError>
13 where
14 F: FnMut() -> T;
15 fn try_copy_from_slice(&mut self, other: &[T]) -> Result<(), AllocError>
16 where
17 T: Copy;
18}
19
20pub trait VecExt<T>: VecAllocExt<T, Global> {
22 fn try_with_capacity(capacity: usize) -> Result<Self, AllocError>;
23}
24
25impl<T, A: Allocator> Sealed for Vec<T, A> {}
26
27impl<T, A: Allocator> VecAllocExt<T, A> for Vec<T, A> {
28 #[inline]
29 fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, AllocError> {
30 let mut vec = Vec::new_in(alloc);
31 vec.try_reserve(capacity)?;
32 Ok(vec)
33 }
34
35 #[inline]
36 fn try_push(&mut self, value: T) -> Result<(), AllocError> {
37 if self.len() == self.capacity() {
38 self.try_reserve(1)?;
39 }
40 self.push(value);
41 Ok(())
42 }
43
44 #[inline]
45 fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), AllocError>
46 where
47 T: Copy,
48 {
49 if new_len > self.len() {
50 self.try_reserve(new_len - self.len())?;
51 }
52 self.resize(new_len, value);
53 Ok(())
54 }
55
56 #[inline]
57 fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), AllocError>
58 where
59 F: FnMut() -> T,
60 {
61 if new_len > self.len() {
62 self.try_reserve(new_len - self.len())?;
63 }
64 self.resize_with(new_len, f);
65 Ok(())
66 }
67
68 fn try_copy_from_slice(&mut self, other: &[T]) -> Result<(), AllocError>
69 where
70 T: Copy,
71 {
72 self.try_reserve(other.len())?;
73 self.extend_from_slice(other);
74 Ok(())
75 }
76}
77
78impl<T> VecExt<T> for Vec<T> {
79 #[inline]
80 fn try_with_capacity(capacity: usize) -> Result<Self, AllocError> {
81 let mut vec = Vec::new();
82 vec.try_reserve(capacity)?;
83 Ok(vec)
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90 use std::alloc::{AllocError, Layout};
91 use std::ptr::NonNull;
92
93 struct Alloc {
94 inner: Global,
95 _mark: u64,
96 }
97
98 impl Alloc {
99 pub const fn new() -> Self {
100 Alloc {
101 inner: Global,
102 _mark: u64::MAX,
103 }
104 }
105 }
106
107 unsafe impl Allocator for Alloc {
108 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
109 self.inner.allocate(layout)
110 }
111
112 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
113 self.inner.deallocate(ptr, layout)
114 }
115 }
116
117 #[test]
118 fn test_vec() {
119 let mut v = Vec::try_with_capacity(1).unwrap();
120 v.try_push(1).unwrap();
121 v.try_push(2).unwrap();
122 v.try_push(3).unwrap();
123 assert_eq!(v, [1, 2, 3]);
124 }
125
126 #[test]
127 fn test_vec_with_alloc() {
128 let mut v = Vec::try_with_capacity_in(1, Alloc::new()).unwrap();
129 v.try_push(1).unwrap();
130 v.try_push(2).unwrap();
131 v.try_push(3).unwrap();
132 assert_eq!(v, [1, 2, 3]);
133 }
134
135 #[test]
136 fn test_vec_resize() {
137 let mut v = Vec::new_in(Alloc::new());
138 v.try_resize(3, 1).unwrap();
139 assert_eq!(v, [1, 1, 1]);
140 }
141
142 #[test]
143 fn test_vec_resize_with() {
144 let mut v = Vec::new_in(Alloc::new());
145 let mut i = 0;
146 v.try_resize_with(3, || {
147 i += 1;
148 i
149 })
150 .unwrap();
151 assert_eq!(v, [1, 2, 3]);
152 }
153
154 #[test]
155 fn test_vec_extend_from_slice() {
156 let mut v = Vec::new_in(Alloc::new());
157 v.try_copy_from_slice(&[1, 2, 3]).unwrap();
158 assert_eq!(v, [1, 2, 3]);
159 }
160}