diff --git a/src/set.rs b/src/set.rs index e2560843..d52b0382 100644 --- a/src/set.rs +++ b/src/set.rs @@ -353,6 +353,20 @@ where (index, existing.is_none()) } + /// Insert the value into the set at the given index. + /// + /// If an equivalent item already exists in the set, it returns + /// `false` leaving the original value in the set, but moving it to + /// the new position in the set. Otherwise, it inserts the new + /// item at the given index and returns `true`. + /// + /// ***Panics*** if `index` is out of bounds. + /// + /// Computes in **O(n)** time (average). + pub fn shift_insert(&mut self, index: usize, value: T) -> bool { + self.map.shift_insert(index, value, ()).is_none() + } + /// Adds a value to the set, replacing the existing value, if any, that is /// equal to the given one, without altering its insertion order. Returns /// the replaced value. diff --git a/src/set/tests.rs b/src/set/tests.rs index a02d8a4f..a67e5d37 100644 --- a/src/set/tests.rs +++ b/src/set/tests.rs @@ -127,6 +127,25 @@ fn insert_order() { } } +#[test] +fn shift_insert() { + let insert = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23]; + let mut set = IndexSet::new(); + + for &elt in &insert { + set.shift_insert(0, elt); + } + + assert_eq!(set.iter().count(), set.len()); + assert_eq!(set.iter().count(), insert.len()); + for (a, b) in insert.iter().rev().zip(set.iter()) { + assert_eq!(a, b); + } + for (i, v) in (0..insert.len()).zip(set.iter()) { + assert_eq!(set.get_index(i).unwrap(), v); + } +} + #[test] fn replace() { let replace = [0, 4, 2, 12, 8, 7, 11, 5];