rust/hedgewars-server/src/core/indexslab.rs
changeset 15074 c5a6e8566425
parent 14693 6a2e13e36b7f
child 15120 febccab419b1
equal deleted inserted replaced
15073:7732013ce64c 15074:c5a6e8566425
       
     1 use std::{
       
     2     iter,
       
     3     mem::replace,
       
     4     ops::{Index, IndexMut},
       
     5 };
       
     6 
       
     7 pub struct IndexSlab<T> {
       
     8     data: Vec<Option<T>>,
       
     9 }
       
    10 
       
    11 impl<T> IndexSlab<T> {
       
    12     pub fn new() -> Self {
       
    13         Self { data: Vec::new() }
       
    14     }
       
    15 
       
    16     pub fn with_capacity(capacity: usize) -> Self {
       
    17         Self {
       
    18             data: Vec::with_capacity(capacity),
       
    19         }
       
    20     }
       
    21 
       
    22     pub fn insert(&mut self, index: usize, value: T) {
       
    23         if index >= self.data.len() {
       
    24             self.data.reserve(index - self.data.len() + 1);
       
    25             self.data.extend((self.data.len()..index).map(|_| None));
       
    26             self.data.push(Some(value))
       
    27         } else {
       
    28             self.data[index] = Some(value);
       
    29         }
       
    30     }
       
    31 
       
    32     pub fn contains(&self, index: usize) -> bool {
       
    33         self.data.get(index).and_then(|x| x.as_ref()).is_some()
       
    34     }
       
    35 
       
    36     pub fn remove(&mut self, index: usize) -> Option<T> {
       
    37         if let Some(x) = self.data.get_mut(index) {
       
    38             replace(x, None)
       
    39         } else {
       
    40             None
       
    41         }
       
    42     }
       
    43 
       
    44     pub fn iter(&self) -> impl Iterator<Item = (usize, &T)> {
       
    45         self.data
       
    46             .iter()
       
    47             .enumerate()
       
    48             .filter_map(|(index, opt)| opt.as_ref().and_then(|x| Some((index, x))))
       
    49     }
       
    50 
       
    51     pub fn iter_mut(&mut self) -> impl Iterator<Item = (usize, &mut T)> {
       
    52         self.data
       
    53             .iter_mut()
       
    54             .enumerate()
       
    55             .filter_map(|(index, opt)| opt.as_mut().and_then(|x| Some((index, x))))
       
    56     }
       
    57 }
       
    58 
       
    59 impl<T> Index<usize> for IndexSlab<T> {
       
    60     type Output = T;
       
    61 
       
    62     fn index(&self, index: usize) -> &Self::Output {
       
    63         self.data[index].as_ref().unwrap()
       
    64     }
       
    65 }
       
    66 
       
    67 impl<T> IndexMut<usize> for IndexSlab<T> {
       
    68     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
       
    69         self.data[index].as_mut().unwrap()
       
    70     }
       
    71 }