Skip to content

Commit 25d3e01

Browse files
committed
Implement append and split_off for VecMap (RFC 509)
Implements `append()` and `split_off()` for `VecMap`. It's worth noting that `append()` will overwrite existing keys (the RFC doesn't specify how `append()` should handle duplicate keys). cc #19986
1 parent 522d09d commit 25d3e01

File tree

1 file changed

+170
-2
lines changed

1 file changed

+170
-2
lines changed

src/libcollections/vec_map.rs

Lines changed: 170 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ use self::Entry::*;
1717

1818
use core::prelude::*;
1919

20-
use core::cmp::Ordering;
20+
use core::cmp::{max, Ordering};
2121
use core::default::Default;
2222
use core::fmt;
2323
use core::hash::{Hash, Hasher};
2424
#[cfg(stage0)] use core::hash::Writer;
2525
use core::iter::{Enumerate, FilterMap, Map, FromIterator, IntoIterator};
2626
use core::iter;
27-
use core::mem::replace;
27+
use core::mem::{replace, swap};
2828
use core::ops::{Index, IndexMut};
2929

3030
use {vec, slice};
@@ -335,6 +335,95 @@ impl<V> VecMap<V> {
335335
IntoIter { iter: self.v.into_iter().enumerate().filter_map(filter) }
336336
}
337337

338+
/// Moves all elements from `other` into the map while overwriting existing keys.
339+
///
340+
/// # Examples
341+
///
342+
/// ```
343+
/// use std::collections::VecMap;
344+
///
345+
/// let mut a = VecMap::new();
346+
/// a.insert(1, "a");
347+
/// a.insert(2, "b");
348+
///
349+
/// let mut b = VecMap::new();
350+
/// b.insert(3, "c");
351+
/// b.insert(4, "d");
352+
///
353+
/// a.append(&mut b);
354+
///
355+
/// assert_eq!(a.len(), 4);
356+
/// assert_eq!(b.len(), 0);
357+
/// assert_eq!(a[1], "a");
358+
/// assert_eq!(a[2], "b");
359+
/// assert_eq!(a[3], "c");
360+
/// assert_eq!(a[4], "d");
361+
/// ```
362+
#[unstable(feature = "collections",
363+
reason = "recently added as part of collections reform 2")]
364+
pub fn append(&mut self, other: &mut Self) {
365+
self.extend(other.drain());
366+
}
367+
368+
/// Splits the collection into two at the given key.
369+
///
370+
/// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
371+
/// and the returned `Self` contains elements `[at, max_key)`.
372+
///
373+
/// Note that the capacity of `self` does not change.
374+
///
375+
/// # Examples
376+
///
377+
/// ```
378+
/// use std::collections::VecMap;
379+
///
380+
/// let mut a = VecMap::new();
381+
/// a.insert(1, "a");
382+
/// a.insert(2, "b");
383+
/// a.insert(3, "c");
384+
/// a.insert(4, "d");
385+
///
386+
/// let b = a.split_off(3);
387+
///
388+
/// assert_eq!(a[1], "a");
389+
/// assert_eq!(a[2], "b");
390+
///
391+
/// assert_eq!(b[3], "c");
392+
/// assert_eq!(b[4], "d");
393+
/// ```
394+
#[unstable(feature = "collections",
395+
reason = "recently added as part of collections reform 2")]
396+
pub fn split_off(&mut self, at: usize) -> Self {
397+
let mut other = VecMap::new();
398+
399+
if at == 0 {
400+
// Move all elements to other
401+
swap(self, &mut other);
402+
return other
403+
} else if at > self.v.len() {
404+
// No elements to copy
405+
return other;
406+
}
407+
408+
// Look up the index of the first non-None item
409+
let first_index = self.v.iter().position(|el| el.is_some());
410+
let start_index = match first_index {
411+
Some(index) => max(at, index),
412+
None => {
413+
// self has no elements
414+
return other;
415+
}
416+
};
417+
418+
// Fill the new VecMap with `None`s until `start_index`
419+
other.v.extend((0..start_index).map(|_| None));
420+
421+
// Move elements beginning with `start_index` from `self` into `other`
422+
other.v.extend(self.v[start_index..].iter_mut().map(|el| el.take()));
423+
424+
other
425+
}
426+
338427
/// Returns an iterator visiting all key-value pairs in ascending order of
339428
/// the keys, emptying (but not consuming) the original `VecMap`.
340429
/// The iterator's element type is `(usize, &'r V)`. Keeps the allocated memory for reuse.
@@ -1156,6 +1245,85 @@ mod test_map {
11561245
assert_eq!(map.len(), 0);
11571246
}
11581247

1248+
#[test]
1249+
fn test_append() {
1250+
let mut a = VecMap::new();
1251+
a.insert(1, "a");
1252+
a.insert(2, "b");
1253+
a.insert(3, "c");
1254+
1255+
let mut b = VecMap::new();
1256+
b.insert(3, "d"); // Overwrite element from a
1257+
b.insert(4, "e");
1258+
b.insert(5, "f");
1259+
1260+
a.append(&mut b);
1261+
1262+
assert_eq!(a.len(), 5);
1263+
assert_eq!(b.len(), 0);
1264+
// Capacity shouldn't change for possible reuse
1265+
assert!(b.capacity() >= 4);
1266+
1267+
assert_eq!(a[1], "a");
1268+
assert_eq!(a[2], "b");
1269+
assert_eq!(a[3], "d");
1270+
assert_eq!(a[4], "e");
1271+
assert_eq!(a[5], "f");
1272+
}
1273+
1274+
#[test]
1275+
fn test_split_off() {
1276+
// Split within the key range
1277+
let mut a = VecMap::new();
1278+
a.insert(1, "a");
1279+
a.insert(2, "b");
1280+
a.insert(3, "c");
1281+
a.insert(4, "d");
1282+
1283+
let b = a.split_off(3);
1284+
1285+
assert_eq!(a.len(), 2);
1286+
assert_eq!(b.len(), 2);
1287+
1288+
assert_eq!(a[1], "a");
1289+
assert_eq!(a[2], "b");
1290+
1291+
assert_eq!(b[3], "c");
1292+
assert_eq!(b[4], "d");
1293+
1294+
// Split at 0
1295+
a.clear();
1296+
a.insert(1, "a");
1297+
a.insert(2, "b");
1298+
a.insert(3, "c");
1299+
a.insert(4, "d");
1300+
1301+
let b = a.split_off(0);
1302+
1303+
assert_eq!(a.len(), 0);
1304+
assert_eq!(b.len(), 4);
1305+
assert_eq!(b[1], "a");
1306+
assert_eq!(b[2], "b");
1307+
assert_eq!(b[3], "c");
1308+
assert_eq!(b[4], "d");
1309+
1310+
// Split behind max_key
1311+
a.clear();
1312+
a.insert(1, "a");
1313+
a.insert(2, "b");
1314+
a.insert(3, "c");
1315+
a.insert(4, "d");
1316+
1317+
let b = a.split_off(5);
1318+
1319+
assert_eq!(a.len(), 4);
1320+
assert_eq!(b.len(), 0);
1321+
assert_eq!(a[1], "a");
1322+
assert_eq!(a[2], "b");
1323+
assert_eq!(a[3], "c");
1324+
assert_eq!(a[4], "d");
1325+
}
1326+
11591327
#[test]
11601328
fn test_show() {
11611329
let mut map = VecMap::new();

0 commit comments

Comments
 (0)