use crate::types::int;
#[allow(non_snake_case)]
pub fn Equal<T: PartialEq>(s1: &[T], s2: &[T]) -> bool {
s1 == s2
}
#[allow(non_snake_case)]
pub fn EqualFunc<T, U, F: Fn(&T, &U) -> bool>(s1: &[T], s2: &[U], eq: F) -> bool {
if s1.len() != s2.len() { return false; }
s1.iter().zip(s2).all(|(a, b)| eq(a, b))
}
#[allow(non_snake_case)]
pub fn Compare<T: PartialOrd>(s1: &[T], s2: &[T]) -> int {
for (a, b) in s1.iter().zip(s2) {
let c = crate::cmp::Compare(a, b);
if c != 0 { return c; }
}
if s1.len() < s2.len() { -1 }
else if s1.len() > s2.len() { 1 }
else { 0 }
}
#[allow(non_snake_case)]
pub fn Index<T: PartialEq>(s: &[T], v: &T) -> int {
match s.iter().position(|x| x == v) {
Some(i) => i as int,
None => -1,
}
}
#[allow(non_snake_case)]
pub fn IndexFunc<T, F: Fn(&T) -> bool>(s: &[T], f: F) -> int {
match s.iter().position(f) {
Some(i) => i as int,
None => -1,
}
}
#[allow(non_snake_case)]
pub fn Contains<T: PartialEq>(s: &[T], v: &T) -> bool {
s.iter().any(|x| x == v)
}
#[allow(non_snake_case)]
pub fn ContainsFunc<T, F: Fn(&T) -> bool>(s: &[T], f: F) -> bool {
s.iter().any(f)
}
#[allow(non_snake_case)]
pub fn Insert<T: Clone>(s: &mut Vec<T>, i: int, values: &[T]) {
let i = i as usize;
if i > s.len() { panic!("slices.Insert: index out of range"); }
let mut splice: Vec<T> = values.to_vec();
let tail: Vec<T> = s.drain(i..).collect();
s.append(&mut splice);
s.extend(tail);
}
#[allow(non_snake_case)]
pub fn Delete<T>(s: &mut Vec<T>, i: int, j: int) {
let i = i as usize;
let j = j as usize;
if i > j || j > s.len() { panic!("slices.Delete: invalid range"); }
s.drain(i..j);
}
#[allow(non_snake_case)]
pub fn DeleteFunc<T, F: FnMut(&T) -> bool>(s: &mut Vec<T>, mut del: F) {
s.retain(|x| !del(x));
}
#[allow(non_snake_case)]
pub fn Replace<T: Clone>(s: &mut Vec<T>, i: int, j: int, values: &[T]) {
let i = i as usize;
let j = j as usize;
if i > j || j > s.len() { panic!("slices.Replace: invalid range"); }
s.splice(i..j, values.iter().cloned());
}
#[allow(non_snake_case)]
pub fn Clone<T: Clone>(s: &[T]) -> Vec<T> {
s.to_vec()
}
#[allow(non_snake_case)]
pub fn Compact<T: PartialEq>(s: &mut Vec<T>) {
s.dedup();
}
#[allow(non_snake_case)]
pub fn CompactFunc<T, F: FnMut(&mut T, &mut T) -> bool>(s: &mut Vec<T>, eq: F) {
s.dedup_by(eq);
}
#[allow(non_snake_case)]
pub fn Concat<T: Clone>(slices: &[&[T]]) -> Vec<T> {
let total: usize = slices.iter().map(|s| s.len()).sum();
let mut out = Vec::with_capacity(total);
for s in slices { out.extend_from_slice(s); }
out
}
#[allow(non_snake_case)]
pub fn Repeat<T: Clone>(x: &[T], count: int) -> Vec<T> {
if count <= 0 { return Vec::new(); }
let mut out = Vec::with_capacity(x.len() * count as usize);
for _ in 0..count { out.extend_from_slice(x); }
out
}
#[allow(non_snake_case)]
pub fn Reverse<T>(s: &mut [T]) {
s.reverse();
}
#[allow(non_snake_case)]
pub fn Sort<T: PartialOrd>(s: &mut [T]) {
s.sort_by(|a, b| {
let c = crate::cmp::Compare(a, b);
if c < 0 { std::cmp::Ordering::Less }
else if c > 0 { std::cmp::Ordering::Greater }
else { std::cmp::Ordering::Equal }
});
}
#[allow(non_snake_case)]
pub fn SortFunc<T, F: FnMut(&T, &T) -> int>(s: &mut [T], mut cmp: F) {
s.sort_by(|a, b| {
let c = cmp(a, b);
if c < 0 { std::cmp::Ordering::Less }
else if c > 0 { std::cmp::Ordering::Greater }
else { std::cmp::Ordering::Equal }
});
}
#[allow(non_snake_case)]
pub fn SortStableFunc<T, F: FnMut(&T, &T) -> int>(s: &mut [T], mut cmp: F) {
s.sort_by(|a, b| {
let c = cmp(a, b);
if c < 0 { std::cmp::Ordering::Less }
else if c > 0 { std::cmp::Ordering::Greater }
else { std::cmp::Ordering::Equal }
});
}
#[allow(non_snake_case)]
pub fn IsSorted<T: PartialOrd>(s: &[T]) -> bool {
s.windows(2).all(|w| crate::cmp::Compare(&w[0], &w[1]) <= 0)
}
#[allow(non_snake_case)]
pub fn IsSortedFunc<T, F: FnMut(&T, &T) -> int>(s: &[T], mut cmp: F) -> bool {
s.windows(2).all(|w| cmp(&w[0], &w[1]) <= 0)
}
#[allow(non_snake_case)]
pub fn Min<T: PartialOrd + Clone>(s: &[T]) -> T {
if s.is_empty() { panic!("slices.Min: empty slice"); }
let mut best = &s[0];
for x in &s[1..] {
if crate::cmp::Compare(x, best) < 0 { best = x; }
}
best.clone()
}
#[allow(non_snake_case)]
pub fn Max<T: PartialOrd + Clone>(s: &[T]) -> T {
if s.is_empty() { panic!("slices.Max: empty slice"); }
let mut best = &s[0];
for x in &s[1..] {
if crate::cmp::Compare(x, best) > 0 { best = x; }
}
best.clone()
}
#[allow(non_snake_case)]
pub fn MinFunc<T: Clone, F: FnMut(&T, &T) -> int>(s: &[T], mut cmp: F) -> T {
if s.is_empty() { panic!("slices.MinFunc: empty slice"); }
let mut best = &s[0];
for x in &s[1..] {
if cmp(x, best) < 0 { best = x; }
}
best.clone()
}
#[allow(non_snake_case)]
pub fn MaxFunc<T: Clone, F: FnMut(&T, &T) -> int>(s: &[T], mut cmp: F) -> T {
if s.is_empty() { panic!("slices.MaxFunc: empty slice"); }
let mut best = &s[0];
for x in &s[1..] {
if cmp(x, best) > 0 { best = x; }
}
best.clone()
}
#[allow(non_snake_case)]
pub fn BinarySearch<T: PartialOrd>(s: &[T], target: &T) -> (int, bool) {
let mut lo = 0usize;
let mut hi = s.len();
while lo < hi {
let mid = lo + (hi - lo) / 2;
if crate::cmp::Compare(&s[mid], target) < 0 {
lo = mid + 1;
} else {
hi = mid;
}
}
let found = lo < s.len() && crate::cmp::Compare(&s[lo], target) == 0;
(lo as int, found)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn equal_and_index() {
let a = [1i64, 2, 3];
let b = [1i64, 2, 3];
let c = [1i64, 2, 4];
assert!(Equal(&a, &b));
assert!(!Equal(&a, &c));
assert_eq!(Index(&a, &2), 1);
assert_eq!(Index(&a, &99), -1);
assert!(Contains(&a, &3));
assert!(!Contains(&a, &10));
}
#[test]
fn sort_and_search() {
let mut s = vec![3i64, 1, 4, 1, 5, 9, 2, 6];
Sort(&mut s);
assert_eq!(s, vec![1i64, 1, 2, 3, 4, 5, 6, 9]);
assert!(IsSorted(&s));
let (i, found) = BinarySearch(&s, &5);
assert!(found);
assert_eq!(i, 5);
}
#[test]
fn min_max() {
assert_eq!(Min(&[3i64, 1, 4]), 1);
assert_eq!(Max(&[3i64, 1, 4]), 4);
}
#[test]
fn insert_delete_reverse() {
let mut s = vec![1i64, 2, 4];
Insert(&mut s, 2, &[3]);
assert_eq!(s, vec![1, 2, 3, 4]);
Delete(&mut s, 1, 3);
assert_eq!(s, vec![1i64, 4]);
Reverse(&mut s);
assert_eq!(s, vec![4i64, 1]);
}
#[test]
fn compact_concat_clone() {
let mut s = vec![1i64, 1, 2, 3, 3, 3, 4];
Compact(&mut s);
assert_eq!(s, vec![1, 2, 3, 4]);
let c: Vec<i64> = Concat(&[&[1, 2], &[3, 4]]);
assert_eq!(c, vec![1i64, 2, 3, 4]);
let cl = Clone(&s);
assert_eq!(cl, s);
}
}