Skip to content

Commit cbabf74

Browse files
committed
Tweak API
1 parent 437abd4 commit cbabf74

File tree

1 file changed

+23
-50
lines changed

1 file changed

+23
-50
lines changed

text/2978-stack_based_vec.md

Lines changed: 23 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -86,22 +86,28 @@ Of course, fixed buffers lead to some inflexibility because unlike `Vec`, the un
8686
# Reference-level explanation
8787
[reference-level-explanation]: #reference-level-explanation
8888

89-
`ArrayVec` is a contiguous memory block where elements can be collected, threfore, a collection by definition and even though `core::collections` doesn't exist, it is the most natural module placement.
89+
`ArrayVec` is a contiguous memory block where elements can be collected, therefore, a collection by definition and even though `core::collections` doesn't exist, it is the most natural module placement.
9090

91-
The API basically mimics most of the current `Vec` surface with some tweaks and additional methods to manage capacity. Notably, these additional methods are fallible versions of some well-known functions like `insert` that will return `Result` instead of panicking at run-time.
91+
The API basically mimics most of the current `Vec` surface with some tweaks to manage capacity.
92+
93+
Notably, these tweaked methods are fallible versions of some well-known functions like `push` that will return `Result` instead of panicking at run-time. Since the upper capacity bound is known at compile-time, the compiler is likely going to remove most of the conditional bounding checking.
9294

9395
```rust
9496
// core::collections
9597

9698
pub struct ArrayVec<T, const N: usize> {
9799
data: MaybeUninit<[T; N]>,
98-
len: usize
100+
len: usize,
99101
}
100102

101103
impl<T, const N: usize> ArrayVec<T, N> {
102104
// Constructors
103105

104-
pub unsafe fn from_raw_parts(_ptr: *mut T, _len: usize) -> Self;
106+
#[inline]
107+
pub fn from_array(array: [T; N]) -> Self;
108+
109+
#[inline]
110+
pub fn from_array_and_len(array: [T; N], len: usize) -> Self;
105111

106112
#[inline]
107113
pub const fn new() -> Self;
@@ -140,27 +146,28 @@ impl<T, const N: usize> ArrayVec<T, N> {
140146
where
141147
R: RangeBounds<usize>;
142148

143-
pub fn extend_from_cloneable_slice(&mut self, other: &[T])
149+
pub fn extend_from_cloneable_slice(&mut self, other: &[T]) -> Result<(), &[T]>
144150
where
145-
T: Clone; // Panics at run-time
151+
T: Clone;
146152

147-
pub fn extend_from_copyable_slice(&mut self, other: &[T])
153+
pub fn extend_from_copyable_slice(&mut self, other: &[T]) -> Result<(), &[T]>
148154
where
149-
T: Copy; // Panics at run-time
155+
T: Copy;
150156

151-
pub fn insert(&mut self, idx: usize, element: T); // Panics at run-time
157+
pub fn insert(&mut self, _idx: usize, element: T) -> Result<(), T>;
152158

153159
#[inline]
154160
pub const fn is_empty(&self) -> bool;
155161

156162
#[inline]
157163
pub const fn len(&self) -> usize;
158164

159-
pub fn pop(&mut self) -> T; // Panics at run-time
165+
pub fn pop(&mut self) -> Option<T>;
160166

161-
pub fn push(&mut self, element: T); // Panics at run-time
167+
#[inline]
168+
pub fn push(&mut self, element: T) -> Result<(), T>;
162169

163-
pub fn remove(&mut self, idx: usize) -> T; // Panics at run-time
170+
pub fn remove(&mut self, idx: usize) -> Option<T>;
164171

165172
pub fn retain<F>(&mut self, f: F)
166173
where
@@ -176,49 +183,15 @@ impl<T, const N: usize> ArrayVec<T, N> {
176183

177184
pub fn split_off(&mut self, at: usize) -> Self;
178185

179-
pub fn swap_remove(&mut self, idx: usize) -> T; // Panics at run-time
186+
pub fn swap_remove(&mut self, idx: usize) -> Option<T>;
180187

181188
pub fn truncate(&mut self, len: usize);
182-
183-
pub fn try_extend_from_cloneable_slice(&mut self, other: &[T]) -> Result<(), ArrayVecError>
184-
where
185-
T: Clone;
186-
187-
pub fn try_extend_from_copyable_slice(&mut self, other: &[T]) -> Result<(), ArrayVecError>
188-
where
189-
T: Copy;
190-
191-
pub fn try_insert(&mut self, _idx: usize, element: T) -> Result<(), ArrayVecError>;
192-
193-
pub fn try_pop(&mut self) -> Result<T, ArrayVecError>;
194-
195-
pub fn try_push(&mut self, element: T) -> Result<(), ArrayVecError>;
196-
197-
pub fn try_remove(&mut self, idx: usize) -> Result<T, ArrayVecError>;
198-
199-
pub fn try_swap_remove(&mut self, idx: usize) -> Result<T, ArrayVecError>;
200-
}
201-
202-
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
203-
pub enum ArrayVecError {
204-
CapacityOverflow,
205-
NoElement
206-
}
207-
208-
impl fmt::Display for ArrayVecError {
209-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210-
let s = match *self {
211-
Self::CapacityOverflow => "It is not possible to add more elements",
212-
Self::NoElement => "There are no elements in the vector",
213-
};
214-
write!(f, "{}", s)
215-
}
216189
}
217190
```
218191

219-
Meaningless, unstable and deprecated methods like `reserve` or `drain_filter` weren't considered and in general, everything that includes or removes elements have a fallible version: `extend_from_cloneable_slice`, `extend_from_copyable_slice`, `pop`, `remove` and `swap_remove`.
192+
Since it is known at compile-time the upper capacity bound, the compiler is likely going to remove the conditional bounding checking of the newly
220193

221-
A concrete implementation is available at https://github.com/c410-f3r/stack-based-vec.
194+
Meaningless, unstable and deprecated methods like `reserve` or `drain_filter` weren't considered. A concrete implementation is available at https://github.com/c410-f3r/stack-based-vec.
222195

223196
# Drawbacks
224197
[drawbacks]: #drawbacks
@@ -229,7 +202,7 @@ New and existing users are likely to find it difficult to differentiate the purp
229202

230203
### The current ecosystem is fine
231204

232-
Even with all the fragmentation, different types of memory usage is an overkill in certain situations. If someone wants to use stack memory in an embedded application, then it is just a matter of grabbing an appropriated crate.
205+
`ArrayVec` might be an overkill in certain situations. If someone wants to use stack memory in a specific application, then it is just a matter of grabbing the appropriated crate.
233206

234207
# Prior art
235208
[prior-art]: #prior-art

0 commit comments

Comments
 (0)