Skip to content

Commit c20bb7e

Browse files
Implement clone (#35)
1 parent 5a5c928 commit c20bb7e

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

fuzz/fuzz_targets/static_vector.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ fuzz_target!(|data: &[u8]| {
2020
let mut prev_byte = None;
2121

2222
for (i, &byte) in data.iter().enumerate() {
23+
assert_eq!(vec.as_slice(), vec.clone().as_slice());
24+
2325
let is_full_before_push = vec.is_full();
2426
let result = vec.push(byte);
2527
let is_full_after_push = vec.is_full();

src/lib.rs

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,11 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
190190
#[doc(alias("add", "append", "insert"))]
191191
pub fn push(&mut self, value: T) -> Result<(), CapacityError> {
192192
if self.is_full() {
193-
return Err(CapacityError);
193+
Err(CapacityError)
194+
} else {
195+
self.push_unchecked(value);
196+
Ok(())
194197
}
195-
196-
self.data[self.length].write(value);
197-
self.length += 1;
198-
199-
Ok(())
200198
}
201199

202200
/// Removes all elements. Size will be zero.
@@ -272,14 +270,14 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
272270
}
273271

274272
if new_length > self.length {
275-
for i in self.length..new_length {
276-
self.data[i].write(T::default());
273+
while self.length < new_length {
274+
self.push_unchecked(T::default());
277275
}
278276
} else {
279277
self.drop_range(new_length, self.length);
278+
self.length = new_length;
280279
}
281280

282-
self.length = new_length;
283281
Ok(())
284282
}
285283

@@ -632,15 +630,21 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
632630
return Err(CapacityError);
633631
}
634632

635-
for (index, value) in slice.iter().enumerate() {
636-
self.data[self.len() + index].write(value.clone());
633+
for value in slice {
634+
self.push_unchecked(value.clone());
637635
}
638636

639-
self.length += slice.len();
640-
641637
Ok(())
642638
}
643639

640+
/// Adds the given `value` to the end of the vector without checking bounds.
641+
/// For internal and controlled use only.
642+
fn push_unchecked(&mut self, value: T) {
643+
debug_assert!(!self.is_full(), "cannot push to full vector");
644+
self.data[self.length].write(value);
645+
self.length += 1;
646+
}
647+
644648
/// Drops all elements in given range. Needed when elements are considered to be going out of scope.
645649
/// E.g.: when the vector is going out of scope, when methods such as [`Vec::clear()`] and [`Vec::set_len()`] are called.
646650
fn drop_range(&mut self, from: usize, to: usize) {
@@ -661,6 +665,16 @@ impl<T, const CAPACITY: usize> Drop for Vec<T, CAPACITY> {
661665
}
662666
}
663667

668+
impl<T: Clone, const CAPACITY: usize> Clone for Vec<T, CAPACITY> {
669+
fn clone(&self) -> Self {
670+
let mut vec = Self::new();
671+
for value in self {
672+
vec.push_unchecked(value.clone());
673+
}
674+
vec
675+
}
676+
}
677+
664678
/// Immutable iterator over a [`Vec`].
665679
///
666680
/// Created by calling [`Vec::iter()`].
@@ -1133,6 +1147,17 @@ mod tests {
11331147
assert_eq!(dst.as_slice(), [1, 2, 3]);
11341148
}
11351149

1150+
#[test]
1151+
fn clone() {
1152+
let mut vec = Vec::<i32, 5>::new();
1153+
let elements = [1, 2, 3];
1154+
vec.extend_from_slice(&elements).unwrap();
1155+
1156+
let new = vec.clone();
1157+
assert_eq!(new.len(), 3);
1158+
assert_eq!(new.as_slice(), elements);
1159+
}
1160+
11361161
#[test]
11371162
fn construct_should_not_create_default_elements() {
11381163
let _ = Vec::<Struct, 10>::new();

0 commit comments

Comments
 (0)