/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::{iter::Extend, ops, marker::PhantomData, u32}; use crate::util::Recycler; #[derive(Debug, Hash)] #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] pub struct Index(u32, PhantomData); // We explicitly implement Copy + Clone instead of using #[derive(Copy, Clone)] // because we don't want to require that T implements Clone + Copy. impl Clone for Index { fn clone(&self) -> Self { *self } } impl Copy for Index {} impl PartialEq for Index { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } impl Index { fn new(idx: usize) -> Self { debug_assert!(idx < u32::max_value() as usize); Index(idx as u32, PhantomData) } pub const INVALID: Index = Index(u32::MAX, PhantomData); pub const UNUSED: Index = Index(u32::MAX-1, PhantomData); } #[derive(Debug)] pub struct OpenRange { start: Index, } #[derive(Debug)] #[cfg_attr(feature = "capture", derive(Serialize))] pub struct Range { pub start: Index, pub end: Index, } // We explicitly implement Copy + Clone instead of using #[derive(Copy, Clone)] // because we don't want to require that T implements Clone + Copy. impl Clone for Range { fn clone(&self) -> Self { Range { start: self.start, end: self.end } } } impl Copy for Range {} impl Range { /// Create an empty `Range` pub fn empty() -> Self { Range { start: Index::new(0), end: Index::new(0), } } /// Check for an empty `Range` pub fn is_empty(self) -> bool { self.start.0 >= self.end.0 } } #[cfg_attr(feature = "capture", derive(Serialize))] pub struct Storage { data: Vec, } impl Storage { pub fn new(initial_capacity: usize) -> Self { Storage { data: Vec::with_capacity(initial_capacity), } } pub fn len(&self) -> usize { self.data.len() } pub fn clear(&mut self) { self.data.clear(); } pub fn push(&mut self, t: T) -> Index { let index = self.data.len(); self.data.push(t); Index(index as u32, PhantomData) } pub fn reserve(&mut self, count: usize) { self.data.reserve(count); } pub fn recycle(&mut self, recycler: &mut Recycler) { recycler.recycle_vec(&mut self.data); } pub fn extend>(&mut self, iter: II) -> Range { let range = self.open_range(); self.data.extend(iter); self.close_range(range) } pub fn open_range(&self) -> OpenRange { OpenRange { start: Index::new(self.data.len()) } } pub fn close_range(&self, range: OpenRange) -> Range { Range { start: range.start, end: Index::new(self.data.len()), } } } impl ops::Index> for Storage { type Output = T; fn index(&self, index: Index) -> &Self::Output { &self.data[index.0 as usize] } } impl ops::IndexMut> for Storage { fn index_mut(&mut self, index: Index) -> &mut Self::Output { &mut self.data[index.0 as usize] } } impl ops::Index> for Storage { type Output = [T]; fn index(&self, index: Range) -> &Self::Output { let start = index.start.0 as _; let end = index.end.0 as _; &self.data[start..end] } } impl ops::IndexMut> for Storage { fn index_mut(&mut self, index: Range) -> &mut Self::Output { let start = index.start.0 as _; let end = index.end.0 as _; &mut self.data[start..end] } }