1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// This file is part of copy-stack-vec.
// SPDX-License-Identifier: MIT OR Apache-2.0
// Crate imports
use crate::vec::CopyStackVec;
impl<T: Copy, const N: usize> Extend<T> for CopyStackVec<T, N> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
let remaining = N - self.len;
if remaining == 0 {
return;
}
for item in iter.into_iter().take(remaining) {
self.buf[self.len].write(item);
self.len += 1;
}
}
}
impl<T: Copy, const N: usize> CopyStackVec<T, N> {
/// Extends from `src` if it fits; otherwise no-op and returns [`Error::Full`].
#[inline]
pub fn extend_from_slice(&mut self, src: &[T]) -> Result<(), crate::Error> {
let avail = N - self.len;
if src.len() > avail {
return Err(crate::Error::Full);
}
let len = self.len;
// Write elements into the uninitialized tail
for (i, item) in src.iter().enumerate() {
self.buf[len + i].write(*item);
}
self.len = len + src.len();
Ok(())
}
/// Copies as many elements from `src` as will fit and returns the count copied.
#[inline]
pub fn extend_from_slice_truncated(&mut self, src: &[T]) -> usize {
let len = self.len;
let avail = N - len;
let take = avail.min(src.len());
for (i, item) in src.iter().take(take).enumerate() {
self.buf[len + i].write(*item);
}
self.len = len + take;
take
}
/// Tries to extend `self` from an iterator **without truncation**.
///
/// Semantics:
/// - All-or-nothing:
/// - If the iterator yields at most `spare_capacity()` items, they are
/// appended in order and `Ok(())` is returned.
/// - If it yields more than `spare_capacity()`, this returns
/// `Err(Error::Full)` and `self` is left unchanged.
/// - The source iterator may be partially consumed on error.
#[inline]
pub fn try_extend_from_iter<I: IntoIterator<Item = T>>(
&mut self,
iter: I,
) -> Result<(), crate::Error> {
let spare = N - self.len;
// Temporary buffer to ensure `self` is unchanged on error.
let mut tmp: CopyStackVec<T, N> = CopyStackVec::default();
for item in iter {
if tmp.len() == spare {
return Err(crate::Error::Full);
}
tmp.push(item)?; // propagate Error::Full from tmp
}
let slice = tmp.as_slice();
self.extend_from_slice(slice)
}
}