Skip to content

Commit ebcf839

Browse files
committed
docs pass on AVec
1 parent 98b445f commit ebcf839

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

src/vec/avec.rs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,37 @@ impl<T, A: Free> AVec<T, A> {
3535
/// data between <code>[avec](Self).[len](Self::len)\(\) .. [avec](Self).[capacity](Self::capacity)\(\)</code>, which can be used to initialize elements in-place before calling <code>[avec](Self).[set_len](Self::set_len)\(\)</code>.
3636
#[inline(always)] pub fn as_mut_ptr(&mut self) -> *mut T { ABox::as_mut_ptr(&mut self.data).cast() }
3737

38+
/// Return a slice containing the entire vector. Equivalent to `&avec[..]`.
3839
#[inline(always)] pub fn as_slice(&self) -> &[T] { unsafe { core::slice::from_raw_parts(self.as_ptr(), self.len) } }
40+
41+
/// Return a slice containing the entire vector. Equivalent to `&mut avec[..]`.
3942
#[inline(always)] pub fn as_slice_mut(&mut self) -> &mut [T] { unsafe { core::slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } }
43+
44+
/// Return the maximum number of elements this vector can store before reallocating.
4045
#[inline(always)] pub fn capacity(&self) -> usize { self.data.len() }
46+
47+
/// Return `true` if the vector contains no elements. Equivalent to <code>avec.[len](Self::len)() == 0</code>.
4148
#[inline(always)] pub fn is_empty(&self) -> bool { self.len() == 0 }
49+
50+
/// Return the number of elements in the vector. Valid indicies into said vector are `0 .. avec.len()`.
4251
#[inline(always)] pub fn len(&self) -> usize { self.len }
52+
53+
/// Change the length of the vector without:
54+
/// * initializing new elements if grown (UB hazard!)
55+
/// * reallocating if the length specified is larger than capacity (UB hazard!)
56+
/// * [`Drop`]ing old elements if shrunk (leak hazard!)
57+
///
58+
/// ### Safety
59+
/// * `new_len` must be less than or equal to <code>[capacity](Self::capacity)()</code>.
60+
/// * If <code>new_len &gt; [avec](Self).[len](Self::len)()</code>, the elements between <code>[avec](Self).[len](Self::len)() .. new_len</code> must have been initialized.
4361
#[inline(always)] pub unsafe fn set_len(&mut self, new_len: usize) { self.len = new_len; }
62+
63+
/// Return a slice to the uninitialized elements between <code>[avec](Self).[len](Self::len)() .. [avec](Self).[capacity](Self::capacity)()</code>.
4464
#[inline(always)] pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] { self.data.get_mut(self.len..).unwrap_or(&mut []) }
4565

66+
/// Move all elements from `other` to `self` without [`Clone`]ing. Results in `other` being emptied.
67+
///
68+
/// Returns an <code>[Err]\(...\)</code> without moving anything if (re)allocating the vector fails.
4669
fn try_append(&mut self, other: &mut AVec<T, impl Free>) -> Result<(), A::Error> where A : Realloc {
4770
self.try_reserve(other.len())?;
4871
debug_assert!(self.len() + other.len() <= self.capacity());
@@ -51,21 +74,34 @@ impl<T, A: Free> AVec<T, A> {
5174
Ok(())
5275
}
5376

77+
/// Move all elements from `other` to `self` without [`Clone`]ing. Results in `other` being emptied.
78+
///
79+
/// Panics without moving anything if (re)allocating the vector fails.
5480
#[cfg(global_oom_handling)] pub fn append(&mut self, other: &mut AVec<T, impl Free>) where A : Realloc { self.try_append(other).expect("out of memory") }
5581

82+
/// Remove all elements from `self` by [`Drop`]ing them.
5683
pub fn clear(&mut self) { self.truncate(0) }
5784

5885
// TODO: dedup, dedup_by, dedup_by_key
5986
// TODO: drain, drain_filter
6087

88+
/// Append all elements from `slice` to `self` by [`Clone`]ing.
89+
///
90+
/// Returns an <code>[Err]\(...\)</code> without [`Clone`]ing anything if (re)allocating the vector fails.
6191
pub(crate) fn try_extend_from_slice(&mut self, slice: &[T]) -> Result<(), A::Error> where T : Clone, A : Realloc {
6292
self.try_reserve(slice.len())?;
6393
for value in slice.iter().cloned() { unsafe { self.push_within_capacity_unchecked(value) } }
6494
Ok(())
6595
}
6696

97+
/// Append all elements from `slice` to `self` by [`Clone`]ing.
98+
///
99+
/// Panics without [`Clone`]ing anything if (re)allocating the vector fails.
67100
#[cfg(global_oom_handling)] pub fn extend_from_slice(&mut self, slice: &[T]) where T : Clone, A : Realloc { self.try_extend_from_slice(slice).expect("out of memory") }
68101

102+
/// [`Clone`] elements from within `self` and append them to `self`.
103+
///
104+
/// Panics without [`Clone`]ing anything if (re)allocating the vector fails.
69105
#[cfg(global_oom_handling)]
70106
#[cfg(feature = "panicy-bounds")]
71107
pub fn extend_from_within<R: RangeBounds<usize>>(&mut self, src: R) where T : Clone, A : Realloc {
@@ -89,10 +125,26 @@ impl<T, A: Free> AVec<T, A> {
89125
}
90126
}
91127

128+
/// Construct an [`AVec`] from it's raw pointer, length, capacity, and default allocator.
129+
///
130+
/// You *generally* only want to do this when you previously broke down a vector of the same type with <code>[into_raw_parts](Self::into_raw_parts)</code>.
131+
///
132+
/// ### Safety
133+
/// * `(data, capacity, align_of::<T>())` should exactly describe an allocation belonging to allocator `A`.
134+
/// * `0 .. length` should be initialized elements of type `T`.
135+
/// * [`AVec`] takes exclusive ownership of said allocation.
92136
pub unsafe fn from_raw_parts(data: NonNull<T>, length: usize, capacity: usize) -> Self where A : Stateless {
93137
unsafe { Self::from_raw_parts_in(data, length, capacity, A::default()) }
94138
}
95139

140+
/// Construct an [`AVec`] from it's raw pointer, length, capacity, and allocator.
141+
///
142+
/// You *generally* only want to do this when you previously broke down a vector of the same type with <code>[into_raw_parts_with_allocator](Self::into_raw_parts_with_allocator)</code>.
143+
///
144+
/// ### Safety
145+
/// * `(data, capacity, align_of::<T>())` should exactly describe an allocation belonging to `allocator`.
146+
/// * `0 .. length` should be initialized elements of type `T`.
147+
/// * [`AVec`] takes exclusive ownership of said allocation.
96148
pub unsafe fn from_raw_parts_in(data: NonNull<T>, length: usize, capacity: usize, allocator: A) -> Self {
97149
let data = crate::util::nn::slice_from_raw_parts(data.cast(), capacity);
98150
let data = unsafe { ABox::from_raw_in(data, allocator) };
@@ -101,6 +153,9 @@ impl<T, A: Free> AVec<T, A> {
101153

102154
// TODO: insert
103155

156+
/// Convert an <code>[AVec]&lt;T, A&gt;</code> into an <code>[ABox]&lt;\[T\], A&gt;</code>.
157+
///
158+
/// Returns an <code>[Err]\(...\)</code> if the allocation could not be shrunk to match it's length exactly.
104159
fn try_into_boxed_slice(self) -> Result<ABox<[T], A>, (Self, A::Error)> where A : Realloc {
105160
let mut v = self;
106161
if let Err(err) = v.try_shrink_to_fit() { return Err((v, err)) }
@@ -115,15 +170,24 @@ impl<T, A: Free> AVec<T, A> {
115170
Ok(unsafe { data.assume_init() })
116171
}
117172

173+
/// Convert an <code>[AVec]&lt;T, A&gt;</code> into an <code>[ABox]&lt;\[T\], A&gt;</code>.
174+
///
175+
/// Panics if the allocation could not be shrunk to match it's length exactly.
118176
#[cfg(global_oom_handling)] pub fn into_boxed_slice(self) -> ABox<[T], A> where A : Realloc { self.try_into_boxed_slice().map_err(|(_, err)| err).expect("unable to shrink alloc") }
119177

120178
// TODO: into_flattened
121179

180+
/// Convert an [`AVec`] into it's raw pointer, length, and capacity.
181+
///
182+
/// This will leak memory unless you later free said memory yourself (perhaps by reconstructing an [`AVec`] through [`AVec::from_raw_parts`].)
122183
pub fn into_raw_parts(self) -> (NonNull<T>, usize, usize) where A : Stateless {
123184
let (data, len, cap, _) = self.into_raw_parts_with_allocator();
124185
(data, len, cap)
125186
}
126187

188+
/// Convert an [`AVec`] into it's raw pointer, length, capacity, and allocator.
189+
///
190+
/// This will leak memory unless you later free said memory yourself (perhaps by reconstructing an [`AVec`] through [`AVec::from_raw_parts_in`].)
127191
pub fn into_raw_parts_with_allocator(self) -> (NonNull<T>, usize, usize, A) {
128192
let this = ManuallyDrop::new(self);
129193
let len = this.len;
@@ -136,28 +200,45 @@ impl<T, A: Free> AVec<T, A> {
136200

137201
// TODO: leak
138202

203+
/// Create an empty [`AVec`] using a default allocator.
139204
pub fn new() -> Self where A : Alloc + Default + ZstInfalliableOrGlobalOomHandling { Self::try_with_capacity(0).unwrap() }
205+
206+
/// Create an empty [`AVec`] using `allocator`.
140207
pub fn new_in(allocator: A) -> Self where A : Alloc + ZstInfalliableOrGlobalOomHandling { Self::try_with_capacity_in(0, allocator).unwrap() }
141208

209+
/// Remove and return the last (highest index) element from the [`AVec`], if any.
142210
pub fn pop(&mut self) -> Option<T> {
143211
let idx_to_pop = self.len.checked_sub(1)?;
144212
self.len = idx_to_pop;
145213
unsafe { Some(self.as_mut_ptr().add(idx_to_pop).read()) }
146214
}
147215

216+
/// Attempt to push `value` to the end of the [`AVec`].
217+
///
218+
/// Returns <code>[Err]\(\(value, ...\)\)</code> if <code>[len](Self::len)() == [capacity](Self::capacity)()</code> and reallocation fails.
148219
pub(crate) fn try_push(&mut self, value: T) -> Result<(), (T, A::Error)> where A : Realloc {
149220
if let Err(e) = self.try_reserve(1) { return Err((value, e)) }
150221
debug_assert!(self.len < self.capacity());
151222
Ok(unsafe { self.push_within_capacity_unchecked(value) })
152223
}
153224

225+
/// Attempt to push `value` to the end of the [`AVec`].
226+
///
227+
/// Panics if <code>[len](Self::len)() == [capacity](Self::capacity)()</code> and reallocation fails.
154228
#[cfg(global_oom_handling)] pub fn push(&mut self, value: T) where A : Realloc { self.try_push(value).map_err(|(_, e)| e).expect("out of memory") }
155229

230+
/// Attempt to push `value` to the end of the [`AVec`].
231+
///
232+
/// ### Safety
233+
/// * There must be unused capacity (e.g. it must be the case that <code>[len](Self::len)() &lt; [capacity](Self::capacity)()</code>.)
156234
unsafe fn push_within_capacity_unchecked(&mut self, value: T) {
157235
unsafe { self.as_mut_ptr().add(self.len).write(value) };
158236
self.len += 1;
159237
}
160238

239+
/// Attempt to push `value` to the end of the [`AVec`].
240+
///
241+
/// Returns <code>[Err]\(value\)</code> without attempting to reallocate if <code>[len](Self::len)() == [capacity](Self::capacity)()</code>.
161242
pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
162243
if self.len < self.capacity() {
163244
Ok(unsafe { self.push_within_capacity_unchecked(value) })
@@ -166,6 +247,9 @@ impl<T, A: Free> AVec<T, A> {
166247
}
167248
}
168249

250+
/// Remove and return the element at `index`, shifting all elements after it down by 1.
251+
///
252+
/// Returns [`None`] if <code>index >= [len](Self::len)()</code>.
169253
pub(crate) fn try_remove(&mut self, index: usize) -> Option<T> {
170254
if index < self.len {
171255
let count = self.len - index;
@@ -180,9 +264,25 @@ impl<T, A: Free> AVec<T, A> {
180264
}
181265
}
182266

267+
/// Remove and return the element at `index`, shifting all elements after it down by 1.
268+
///
269+
/// Panics if <code>index >= [len](Self::len)()</code>.
183270
#[cfg(feature = "panicy-bounds")] pub fn remove(&mut self, index: usize) -> T { self.try_remove(index).expect("index out of bounds") }
184271

272+
/// Reserve enough <code>[capacity](Self::capacity)()</code> for *at least* <code>[len](Self::len)() + additional</code> elements.
273+
/// This may allocate more capacity than requested to encourage amortized constant behavior via exponential growth patterns.
274+
///
275+
/// Noop if <code>[len](Self::len)() + additional <= [capacity](Self::capacity)()</code>.
276+
///
277+
/// Panics if reallocation was necessary but failed.
185278
#[cfg(global_oom_handling)] pub fn reserve(&mut self, additional: usize) where A : Realloc { self.try_reserve(additional).expect("unable to reserve more memory") }
279+
280+
/// Reserve enough <code>[capacity](Self::capacity)()</code> for *exactly* <code>[len](Self::len)() + additional</code> elements.
281+
/// Beware: This will avoid exponential growth, which can easily lead to O(N<sup>2</sup>) behavior!
282+
///
283+
/// Noop if <code>[len](Self::len)() + additional <= [capacity](Self::capacity)()</code>.
284+
///
285+
/// Panics if reallocation was necessary but failed.
186286
#[cfg(global_oom_handling)] pub fn reserve_exact(&mut self, additional: usize) where A : Realloc { self.try_reserve_exact(additional).expect("unable to reserve more memory") }
187287

188288
pub(crate) fn try_resize_with<F: FnMut() -> T>(&mut self, new_len: usize, mut f: F) -> Result<(), A::Error> where A : Realloc {
@@ -199,21 +299,49 @@ impl<T, A: Free> AVec<T, A> {
199299
self.try_resize_with(new_len, || value.clone())
200300
}
201301

302+
/// Resize `self` to be `new_len` elements. `value` will be repeatedly [`Clone`]ed if <code>new_len &gt; [len](Self::len)()</code>, or ignored otherwise.
303+
///
304+
/// Panics if reallocation was necessary but failed.
202305
#[cfg(global_oom_handling)] pub fn resize(&mut self, new_len: usize, value: T) where T : Clone, A : Realloc { self.try_resize(new_len, value).expect("unable to reserve more memory") }
306+
307+
/// Resize `self` to be `new_len` elements. If <code>new_len &gt; [len](Self::len)()</code>, `f()` will be called to create new elements, otherwise `f` is ignored.
308+
///
309+
/// Panics if reallocation was necessary but failed.
203310
#[cfg(global_oom_handling)] pub fn resize_with<F: FnMut() -> T>(&mut self, new_len: usize, f: F) where A : Realloc { self.try_resize_with(new_len, f).expect("unable to reserve more memory") }
204311

312+
/// Remove all elements `e` of `self` where `!f(e)`.
205313
pub fn retain <F: FnMut(& T) -> bool>(&mut self, mut f: F) { self.retain_mut(|v| f(v)) }
314+
315+
/// Remove all elements `e` of `self` where `!f(e)`.
206316
pub fn retain_mut<F: FnMut(&mut T) -> bool>(&mut self, mut f: F) { self.retain_imp(|v| f(v)) }
207317

318+
/// Shrink <code>self.[capacity](Self::capacity)()</code> to <code>min_capacity.max(self.[len](Self::len)())</code>.
319+
///
320+
/// Returns an <code>[Err]\(...\)</code> if reallocation fails.
208321
pub(crate) fn try_shrink_to(&mut self, min_capacity: usize) -> Result<(), A::Error> where A : Realloc { let c = min_capacity.max(self.len()); ABox::try_realloc_uninit_slice(&mut self.data, c) }
322+
323+
/// Shrink <code>self.[capacity](Self::capacity)()</code> to <code>self.[len](Self::len)()</code>.
324+
///
325+
/// Returns an <code>[Err]\(...\)</code> if reallocation fails.
209326
pub(crate) fn try_shrink_to_fit(&mut self) -> Result<(), A::Error> where A : Realloc { self.try_shrink_to(self.len()) }
327+
328+
/// Shrink <code>self.[capacity](Self::capacity)()</code> to <code>min_capacity.max(self.[len](Self::len)())</code>.
329+
///
330+
/// Panics if reallocation fails.
210331
#[cfg(global_oom_handling)] pub fn shrink_to(&mut self, min_capacity: usize) where A : Realloc { self.try_shrink_to(min_capacity).expect("unable to reallocate") }
332+
333+
/// Shrink <code>self.[capacity](Self::capacity)()</code> to <code>self.[len](Self::len)()</code>.
334+
///
335+
/// Panics if reallocation fails.
211336
#[cfg(global_oom_handling)] pub fn shrink_to_fit(&mut self) where A : Realloc { self.try_shrink_to_fit().expect("unable to reallocate") }
212337

213338
// TODO: splice
214339
// TODO: split_at_sparse_mut
215340
// TODO: split_off
216341

342+
/// Attempt to remove and return the element at `index` by swapping it with the last element and <code>[pop](Self::pop)()</code>ing it.
343+
///
344+
/// Returns [`None`] if <code>index &gt;= [len](Self::len)()</code>.
217345
pub(crate) fn try_swap_remove(&mut self, index: usize) -> Option<T> {
218346
if index < self.len {
219347
self.data.swap(index, self.len-1);
@@ -223,8 +351,14 @@ impl<T, A: Free> AVec<T, A> {
223351
}
224352
}
225353

354+
/// Remove and return the element at `index` by swapping it with the last element and <code>[pop](Self::pop)()</code>ing it.
355+
///
356+
/// Panics if <code>index &gt;= [len](Self::len)()</code>.
226357
#[cfg(feature = "panicy-bounds")] pub fn swap_remove(&mut self, index: usize) -> T { self.try_swap_remove(index).expect("index out of bounds") }
227358

359+
/// [`Drop`] the elements at <code>self\[len..\]</code>.
360+
///
361+
/// Noop if <code>len &gt;= [self](Self).[len](Self::len)()</code>.
228362
pub fn truncate(&mut self, len: usize) {
229363
if let Some(to_drop) = self.len.checked_sub(len) {
230364
let to_drop = core::ptr::slice_from_raw_parts_mut(unsafe { self.as_mut_ptr().add(len) }, to_drop);
@@ -233,21 +367,48 @@ impl<T, A: Free> AVec<T, A> {
233367
}
234368
}
235369

370+
/// Reserve enough <code>[capacity](Self::capacity)()</code> for *at least* <code>[len](Self::len)() + additional</code> elements.
371+
/// This may allocate more capacity than requested to encourage amortized constant behavior via exponential growth patterns.
372+
///
373+
/// Noop if <code>[len](Self::len)() + additional <= [capacity](Self::capacity)()</code>.
374+
///
375+
/// Returns an <code>[Err]\(...\)</code> if reallocation was necessary but failed.
236376
pub fn try_reserve(&mut self, additional: usize) -> Result<(), A::Error> where A : Realloc {
237377
let new_capacity = self.len().checked_add(additional).ok_or_else(|| ExcessiveSliceRequestedError { requested: !0 })?;
238378
if new_capacity <= self.capacity() { return Ok(()) }
239379
let new_capacity = new_capacity.max(self.capacity().saturating_mul(2));
240380
ABox::try_realloc_uninit_slice(&mut self.data, new_capacity)
241381
}
242382

383+
/// Reserve enough <code>[capacity](Self::capacity)()</code> for *exactly* <code>[len](Self::len)() + additional</code> elements.
384+
/// Beware: This will avoid exponential growth, which can easily lead to O(N<sup>2</sup>) behavior!
385+
///
386+
/// Noop if <code>[len](Self::len)() + additional <= [capacity](Self::capacity)()</code>.
387+
///
388+
/// Returns an <code>[Err]\(...\)</code> if reallocation was necessary but failed.
243389
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), A::Error> where A : Realloc {
244390
let new_capacity = self.len().checked_add(additional).ok_or_else(|| ExcessiveSliceRequestedError { requested: !0 })?;
245391
if new_capacity <= self.capacity() { return Ok(()) }
246392
ABox::try_realloc_uninit_slice(&mut self.data, new_capacity)
247393
}
248394

395+
/// Create an empty [`AVec`] using `allocator`, with a <code>[capacity](Self::capacity)()</code> of at least `capacity`.
396+
///
397+
/// Returns an <code>[Err]\(...\)</code> if allocation fails.
249398
pub(crate) fn try_with_capacity_in(capacity: usize, allocator: A) -> Result<Self, A::Error> where A : Alloc + ZstSupported { Ok(Self { data: ABox::try_new_uninit_slice_in(capacity, allocator)?, len: 0 }) }
399+
400+
/// Create an empty [`AVec`] using a default allocator, with a <code>[capacity](Self::capacity)()</code> of at least `capacity`.
401+
///
402+
/// Returns an <code>[Err]\(...\)</code> if allocation fails.
250403
pub(crate) fn try_with_capacity( capacity: usize) -> Result<Self, A::Error> where A : Alloc + Default + ZstSupported { Self::try_with_capacity_in(capacity, A::default()) }
404+
405+
/// Create an empty [`AVec`] using `allocator`, with a <code>[capacity](Self::capacity)()</code> of at least `capacity`.
406+
///
407+
/// Panics if allocation fails.
251408
#[cfg(global_oom_handling)] pub fn with_capacity_in(capacity: usize, allocator: A) -> Self where A : Alloc + ZstSupported { Self::try_with_capacity_in(capacity, allocator).expect("out of memory") }
409+
410+
/// Create an empty [`AVec`] using a default allocator, with a <code>[capacity](Self::capacity)()</code> of at least `capacity`.
411+
///
412+
/// Panics if allocation fails.
252413
#[cfg(global_oom_handling)] pub fn with_capacity( capacity: usize) -> Self where A : Alloc + Default + ZstSupported { Self::try_with_capacity(capacity ).expect("out of memory") }
253414
}

0 commit comments

Comments
 (0)