@@ -4,7 +4,7 @@ use std::{
4
4
collections:: BTreeMap ,
5
5
hash:: Hash ,
6
6
str:: FromStr ,
7
- sync:: atomic:: { AtomicUsize , Ordering } ,
7
+ sync:: atomic:: { AtomicU32 , Ordering } ,
8
8
} ;
9
9
use thiserror:: Error ;
10
10
@@ -18,22 +18,23 @@ use thiserror::Error;
18
18
/// another map where it will likely be invalid.
19
19
#[ derive( Serialize , Deserialize ) ]
20
20
pub ( crate ) struct Id < T > {
21
- index : usize ,
21
+ index : u32 ,
22
22
// If we do not skip this field it will simply serialize as `"_marker":null` which is useless extra data
23
23
#[ serde( skip) ]
24
24
_marker : std:: marker:: PhantomData < T > ,
25
25
}
26
26
27
27
impl < T > Id < T > {
28
28
/// Constructs a new Id for the given index.
29
- /// This constructor is deliberately private to prevent
30
- /// constructing invalid IDs.
31
- pub ( crate ) fn new ( index : usize ) -> Self {
29
+ ///
30
+ /// This is private so that we can guarantee ids created from this function
31
+ /// point to valid T values in their external maps.
32
+ fn new ( index : u32 ) -> Self {
32
33
Self { index, _marker : std:: marker:: PhantomData }
33
34
}
34
35
35
36
/// Returns the underlying index of this Id.
36
- pub ( crate ) fn to_usize ( self ) -> usize {
37
+ pub ( crate ) fn to_u32 ( self ) -> u32 {
37
38
self . index
38
39
}
39
40
@@ -43,7 +44,7 @@ impl<T> Id<T> {
43
44
/// as unlike DenseMap::push and SparseMap::push, the Ids created
44
45
/// here are likely invalid for any particularly map.
45
46
#[ cfg( test) ]
46
- pub ( crate ) fn test_new ( index : usize ) -> Self {
47
+ pub ( crate ) fn test_new ( index : u32 ) -> Self {
47
48
Self :: new ( index)
48
49
}
49
50
}
@@ -187,15 +188,15 @@ impl<T> DenseMap<T> {
187
188
/// Adds an element to the map.
188
189
/// Returns the identifier/reference to that element.
189
190
pub ( crate ) fn insert ( & mut self , element : T ) -> Id < T > {
190
- let id = Id :: new ( self . storage . len ( ) ) ;
191
+ let id = Id :: new ( self . storage . len ( ) . try_into ( ) . unwrap ( ) ) ;
191
192
self . storage . push ( element) ;
192
193
id
193
194
}
194
195
195
196
/// Given the Id of the element being created, adds the element
196
197
/// returned by the given function to the map
197
198
pub ( crate ) fn insert_with_id ( & mut self , f : impl FnOnce ( Id < T > ) -> T ) -> Id < T > {
198
- let id = Id :: new ( self . storage . len ( ) ) ;
199
+ let id = Id :: new ( self . storage . len ( ) . try_into ( ) . unwrap ( ) ) ;
199
200
self . storage . push ( f ( id) ) ;
200
201
id
201
202
}
@@ -204,7 +205,7 @@ impl<T> DenseMap<T> {
204
205
///
205
206
/// The id-element pairs are ordered by the numeric values of the ids.
206
207
pub ( crate ) fn iter ( & self ) -> impl ExactSizeIterator < Item = ( Id < T > , & T ) > {
207
- let ids_iter = ( 0 ..self . storage . len ( ) ) . map ( |idx| Id :: new ( idx) ) ;
208
+ let ids_iter = ( 0 ..self . storage . len ( ) as u32 ) . map ( |idx| Id :: new ( idx) ) ;
208
209
ids_iter. zip ( self . storage . iter ( ) )
209
210
}
210
211
}
@@ -219,13 +220,13 @@ impl<T> std::ops::Index<Id<T>> for DenseMap<T> {
219
220
type Output = T ;
220
221
221
222
fn index ( & self , id : Id < T > ) -> & Self :: Output {
222
- & self . storage [ id. index ]
223
+ & self . storage [ id. index as usize ]
223
224
}
224
225
}
225
226
226
227
impl < T > std:: ops:: IndexMut < Id < T > > for DenseMap < T > {
227
228
fn index_mut ( & mut self , id : Id < T > ) -> & mut Self :: Output {
228
- & mut self . storage [ id. index ]
229
+ & mut self . storage [ id. index as usize ]
229
230
}
230
231
}
231
232
@@ -253,15 +254,15 @@ impl<T> SparseMap<T> {
253
254
/// Adds an element to the map.
254
255
/// Returns the identifier/reference to that element.
255
256
pub ( crate ) fn insert ( & mut self , element : T ) -> Id < T > {
256
- let id = Id :: new ( self . storage . len ( ) ) ;
257
+ let id = Id :: new ( self . storage . len ( ) . try_into ( ) . unwrap ( ) ) ;
257
258
self . storage . insert ( id, element) ;
258
259
id
259
260
}
260
261
261
262
/// Given the Id of the element being created, adds the element
262
263
/// returned by the given function to the map
263
264
pub ( crate ) fn insert_with_id ( & mut self , f : impl FnOnce ( Id < T > ) -> T ) -> Id < T > {
264
- let id = Id :: new ( self . storage . len ( ) ) ;
265
+ let id = Id :: new ( self . storage . len ( ) . try_into ( ) . unwrap ( ) ) ;
265
266
self . storage . insert ( id, f ( id) ) ;
266
267
id
267
268
}
@@ -365,15 +366,15 @@ impl<K: Eq + Hash, V> std::ops::Index<&K> for TwoWayMap<K, V> {
365
366
/// This type wraps an AtomicUsize so it can safely be used across threads.
366
367
#[ derive( Debug , Serialize , Deserialize ) ]
367
368
pub ( crate ) struct AtomicCounter < T > {
368
- next : AtomicUsize ,
369
+ next : AtomicU32 ,
369
370
_marker : std:: marker:: PhantomData < T > ,
370
371
}
371
372
372
373
impl < T > AtomicCounter < T > {
373
374
/// Create a new counter starting after the given Id.
374
375
/// Use AtomicCounter::default() to start at zero.
375
376
pub ( crate ) fn starting_after ( id : Id < T > ) -> Self {
376
- Self { next : AtomicUsize :: new ( id. index + 1 ) , _marker : Default :: default ( ) }
377
+ Self { next : AtomicU32 :: new ( id. index + 1 ) , _marker : Default :: default ( ) }
377
378
}
378
379
379
380
/// Return the next fresh id
0 commit comments