@@ -14,6 +14,14 @@ pub(crate) struct SparseArray<I, V = I> {
1414 marker : PhantomData < I > ,
1515}
1616
17+ /// A space-optimized version of [`SparseArray`] that cannot be changed
18+ /// after construction.
19+ #[ derive( Debug ) ]
20+ pub ( crate ) struct ImmutableSparseArray < I , V = I > {
21+ values : Box < [ Option < V > ] > ,
22+ marker : PhantomData < I > ,
23+ }
24+
1725impl < I : SparseSetIndex , V > Default for SparseArray < I , V > {
1826 fn default ( ) -> Self {
1927 Self :: new ( )
@@ -30,6 +38,27 @@ impl<I, V> SparseArray<I, V> {
3038 }
3139}
3240
41+ macro_rules! impl_sparse_array {
42+ ( $ty: ident) => {
43+ impl <I : SparseSetIndex , V > $ty<I , V > {
44+ #[ inline]
45+ pub fn contains( & self , index: I ) -> bool {
46+ let index = index. sparse_set_index( ) ;
47+ self . values. get( index) . map( |v| v. is_some( ) ) . unwrap_or( false )
48+ }
49+
50+ #[ inline]
51+ pub fn get( & self , index: I ) -> Option <& V > {
52+ let index = index. sparse_set_index( ) ;
53+ self . values. get( index) . map( |v| v. as_ref( ) ) . unwrap_or( None )
54+ }
55+ }
56+ } ;
57+ }
58+
59+ impl_sparse_array ! ( SparseArray ) ;
60+ impl_sparse_array ! ( ImmutableSparseArray ) ;
61+
3362impl < I : SparseSetIndex , V > SparseArray < I , V > {
3463 #[ inline]
3564 pub fn insert ( & mut self , index : I , value : V ) {
@@ -40,18 +69,6 @@ impl<I: SparseSetIndex, V> SparseArray<I, V> {
4069 self . values [ index] = Some ( value) ;
4170 }
4271
43- #[ inline]
44- pub fn contains ( & self , index : I ) -> bool {
45- let index = index. sparse_set_index ( ) ;
46- self . values . get ( index) . map ( |v| v. is_some ( ) ) . unwrap_or ( false )
47- }
48-
49- #[ inline]
50- pub fn get ( & self , index : I ) -> Option < & V > {
51- let index = index. sparse_set_index ( ) ;
52- self . values . get ( index) . map ( |v| v. as_ref ( ) ) . unwrap_or ( None )
53- }
54-
5572 #[ inline]
5673 pub fn get_mut ( & mut self , index : I ) -> Option < & mut V > {
5774 let index = index. sparse_set_index ( ) ;
@@ -70,6 +87,13 @@ impl<I: SparseSetIndex, V> SparseArray<I, V> {
7087 pub fn clear ( & mut self ) {
7188 self . values . clear ( ) ;
7289 }
90+
91+ pub ( crate ) fn into_immutable ( self ) -> ImmutableSparseArray < I , V > {
92+ ImmutableSparseArray {
93+ values : self . values . into_boxed_slice ( ) ,
94+ marker : PhantomData ,
95+ }
96+ }
7397}
7498
7599/// A sparse data structure of [Components](crate::component::Component)
@@ -249,11 +273,75 @@ pub struct SparseSet<I, V: 'static> {
249273 sparse : SparseArray < I , usize > ,
250274}
251275
276+ /// A space-optimized version of [`SparseSet`] that cannot be changed
277+ /// after construction.
278+ #[ derive( Debug ) ]
279+ pub ( crate ) struct ImmutableSparseSet < I , V : ' static > {
280+ dense : Box < [ V ] > ,
281+ indices : Box < [ I ] > ,
282+ sparse : ImmutableSparseArray < I , usize > ,
283+ }
284+
285+ macro_rules! impl_sparse_set {
286+ ( $ty: ident) => {
287+ impl <I : SparseSetIndex , V > $ty<I , V > {
288+ #[ inline]
289+ pub fn len( & self ) -> usize {
290+ self . dense. len( )
291+ }
292+
293+ #[ inline]
294+ pub fn contains( & self , index: I ) -> bool {
295+ self . sparse. contains( index)
296+ }
297+
298+ pub fn get( & self , index: I ) -> Option <& V > {
299+ self . sparse. get( index) . map( |dense_index| {
300+ // SAFETY: if the sparse index points to something in the dense vec, it exists
301+ unsafe { self . dense. get_unchecked( * dense_index) }
302+ } )
303+ }
304+
305+ pub fn get_mut( & mut self , index: I ) -> Option <& mut V > {
306+ let dense = & mut self . dense;
307+ self . sparse. get( index) . map( move |dense_index| {
308+ // SAFETY: if the sparse index points to something in the dense vec, it exists
309+ unsafe { dense. get_unchecked_mut( * dense_index) }
310+ } )
311+ }
312+
313+ pub fn indices( & self ) -> impl Iterator <Item = I > + ' _ {
314+ self . indices. iter( ) . cloned( )
315+ }
316+
317+ pub fn values( & self ) -> impl Iterator <Item = & V > {
318+ self . dense. iter( )
319+ }
320+
321+ pub fn values_mut( & mut self ) -> impl Iterator <Item = & mut V > {
322+ self . dense. iter_mut( )
323+ }
324+
325+ pub fn iter( & self ) -> impl Iterator <Item = ( & I , & V ) > {
326+ self . indices. iter( ) . zip( self . dense. iter( ) )
327+ }
328+
329+ pub fn iter_mut( & mut self ) -> impl Iterator <Item = ( & I , & mut V ) > {
330+ self . indices. iter( ) . zip( self . dense. iter_mut( ) )
331+ }
332+ }
333+ } ;
334+ }
335+
336+ impl_sparse_set ! ( SparseSet ) ;
337+ impl_sparse_set ! ( ImmutableSparseSet ) ;
338+
252339impl < I : SparseSetIndex , V > Default for SparseSet < I , V > {
253340 fn default ( ) -> Self {
254341 Self :: new ( )
255342 }
256343}
344+
257345impl < I , V > SparseSet < I , V > {
258346 pub const fn new ( ) -> Self {
259347 Self {
@@ -306,36 +394,11 @@ impl<I: SparseSetIndex, V> SparseSet<I, V> {
306394 }
307395 }
308396
309- #[ inline]
310- pub fn len ( & self ) -> usize {
311- self . dense . len ( )
312- }
313-
314397 #[ inline]
315398 pub fn is_empty ( & self ) -> bool {
316399 self . dense . len ( ) == 0
317400 }
318401
319- #[ inline]
320- pub fn contains ( & self , index : I ) -> bool {
321- self . sparse . contains ( index)
322- }
323-
324- pub fn get ( & self , index : I ) -> Option < & V > {
325- self . sparse . get ( index) . map ( |dense_index| {
326- // SAFETY: if the sparse index points to something in the dense vec, it exists
327- unsafe { self . dense . get_unchecked ( * dense_index) }
328- } )
329- }
330-
331- pub fn get_mut ( & mut self , index : I ) -> Option < & mut V > {
332- let dense = & mut self . dense ;
333- self . sparse . get ( index) . map ( move |dense_index| {
334- // SAFETY: if the sparse index points to something in the dense vec, it exists
335- unsafe { dense. get_unchecked_mut ( * dense_index) }
336- } )
337- }
338-
339402 pub fn remove ( & mut self , index : I ) -> Option < V > {
340403 self . sparse . remove ( index) . map ( |dense_index| {
341404 let is_last = dense_index == self . dense . len ( ) - 1 ;
@@ -349,24 +412,12 @@ impl<I: SparseSetIndex, V> SparseSet<I, V> {
349412 } )
350413 }
351414
352- pub fn indices ( & self ) -> impl Iterator < Item = I > + ' _ {
353- self . indices . iter ( ) . cloned ( )
354- }
355-
356- pub fn values ( & self ) -> impl Iterator < Item = & V > {
357- self . dense . iter ( )
358- }
359-
360- pub fn values_mut ( & mut self ) -> impl Iterator < Item = & mut V > {
361- self . dense . iter_mut ( )
362- }
363-
364- pub fn iter ( & self ) -> impl Iterator < Item = ( & I , & V ) > {
365- self . indices . iter ( ) . zip ( self . dense . iter ( ) )
366- }
367-
368- pub fn iter_mut ( & mut self ) -> impl Iterator < Item = ( & I , & mut V ) > {
369- self . indices . iter ( ) . zip ( self . dense . iter_mut ( ) )
415+ pub ( crate ) fn into_immutable ( self ) -> ImmutableSparseSet < I , V > {
416+ ImmutableSparseSet {
417+ dense : self . dense . into_boxed_slice ( ) ,
418+ indices : self . indices . into_boxed_slice ( ) ,
419+ sparse : self . sparse . into_immutable ( ) ,
420+ }
370421 }
371422}
372423
0 commit comments