Source code

Revision control

Other Tools

1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
use std::{iter::Extend, ops, marker::PhantomData, u32};
6
use crate::util::Recycler;
7
8
#[derive(Debug, Hash)]
9
#[cfg_attr(feature = "capture", derive(Serialize))]
10
#[cfg_attr(feature = "replay", derive(Deserialize))]
11
pub struct Index<T>(u32, PhantomData<T>);
12
13
// We explicitly implement Copy + Clone instead of using #[derive(Copy, Clone)]
14
// because we don't want to require that T implements Clone + Copy.
15
impl<T> Clone for Index<T> {
16
fn clone(&self) -> Self { *self }
17
}
18
19
impl<T> Copy for Index<T> {}
20
21
impl<T> PartialEq for Index<T> {
22
fn eq(&self, other: &Self) -> bool {
23
self.0 == other.0
24
}
25
}
26
27
impl<T> Index<T> {
28
fn new(idx: usize) -> Self {
29
debug_assert!(idx < u32::max_value() as usize);
30
Index(idx as u32, PhantomData)
31
}
32
33
pub const INVALID: Index<T> = Index(u32::MAX, PhantomData);
34
pub const UNUSED: Index<T> = Index(u32::MAX-1, PhantomData);
35
}
36
37
#[derive(Debug)]
38
#[cfg_attr(feature = "capture", derive(Serialize))]
39
pub struct Range<T> {
40
pub start: Index<T>,
41
pub end: Index<T>,
42
}
43
44
// We explicitly implement Copy + Clone instead of using #[derive(Copy, Clone)]
45
// because we don't want to require that T implements Clone + Copy.
46
impl<T> Clone for Range<T> {
47
fn clone(&self) -> Self {
48
Range { start: self.start, end: self.end }
49
}
50
}
51
impl<T> Copy for Range<T> {}
52
53
impl<T> Range<T> {
54
/// Create an empty `Range`
55
pub fn empty() -> Self {
56
Range {
57
start: Index::new(0),
58
end: Index::new(0),
59
}
60
}
61
62
/// Check for an empty `Range`
63
pub fn is_empty(self) -> bool {
64
self.start.0 >= self.end.0
65
}
66
}
67
68
#[cfg_attr(feature = "capture", derive(Serialize))]
69
pub struct Storage<T> {
70
data: Vec<T>,
71
}
72
73
impl<T> Storage<T> {
74
pub fn new(initial_capacity: usize) -> Self {
75
Storage {
76
data: Vec::with_capacity(initial_capacity),
77
}
78
}
79
80
pub fn len(&self) -> usize {
81
self.data.len()
82
}
83
84
pub fn clear(&mut self) {
85
self.data.clear();
86
}
87
88
pub fn push(&mut self, t: T) -> Index<T> {
89
let index = self.data.len();
90
self.data.push(t);
91
Index(index as u32, PhantomData)
92
}
93
94
pub fn recycle(&mut self, recycler: &mut Recycler) {
95
recycler.recycle_vec(&mut self.data);
96
}
97
98
pub fn extend<II: IntoIterator<Item=T>>(&mut self, iter: II) -> Range<T> {
99
let start = Index::new(self.data.len());
100
self.data.extend(iter);
101
let end = Index::new(self.data.len());
102
Range { start, end }
103
}
104
}
105
106
impl<T> ops::Index<Index<T>> for Storage<T> {
107
type Output = T;
108
fn index(&self, index: Index<T>) -> &Self::Output {
109
&self.data[index.0 as usize]
110
}
111
}
112
113
impl<T> ops::IndexMut<Index<T>> for Storage<T> {
114
fn index_mut(&mut self, index: Index<T>) -> &mut Self::Output {
115
&mut self.data[index.0 as usize]
116
}
117
}
118
119
impl<T> ops::Index<Range<T>> for Storage<T> {
120
type Output = [T];
121
fn index(&self, index: Range<T>) -> &Self::Output {
122
let start = index.start.0 as _;
123
let end = index.end.0 as _;
124
&self.data[start..end]
125
}
126
}
127
128
impl<T> ops::IndexMut<Range<T>> for Storage<T> {
129
fn index_mut(&mut self, index: Range<T>) -> &mut Self::Output {
130
let start = index.start.0 as _;
131
let end = index.end.0 as _;
132
&mut self.data[start..end]
133
}
134
}