36
36
) ]
37
37
38
38
use std:: fmt:: { self , Debug , Formatter } ;
39
+ use std:: num:: NonZeroUsize ;
39
40
40
41
/// Vec-backed ID-tree.
41
42
///
42
43
/// Always contains at least a root node.
43
- #[ derive( Clone , PartialEq , Eq , Hash ) ]
44
44
pub struct Tree < T > {
45
+ // Safety note: node at index 0 is uninitialized!
45
46
vec : Vec < Node < T > > ,
46
47
}
47
48
49
+ impl < T > Clone for Tree < T > where T : Clone {
50
+ fn clone ( & self ) -> Self {
51
+ let mut vec = Vec :: with_capacity ( self . vec . len ( ) ) ;
52
+ // See Tree::with_capacity
53
+ unsafe {
54
+ vec. set_len ( 1 ) ;
55
+ }
56
+ vec. extend ( self . vec [ 1 ..] . iter ( ) . cloned ( ) ) ;
57
+ Tree { vec }
58
+ }
59
+ }
60
+
61
+ impl < T > std:: hash:: Hash for Tree < T > where T : std:: hash:: Hash {
62
+ fn hash < H > ( & self , state : & mut H ) where H : std:: hash:: Hasher {
63
+ self . vec [ 1 ..] . hash ( state)
64
+ }
65
+ }
66
+
67
+ impl < T > Eq for Tree < T > where T : Eq { }
68
+ impl < T > PartialEq for Tree < T > where T : PartialEq {
69
+ fn eq ( & self , other : & Self ) -> bool {
70
+ self . vec [ 1 ..] == other. vec [ 1 ..]
71
+ }
72
+ }
73
+
74
+
48
75
/// Node ID.
49
76
///
50
77
/// Index into a `Tree`-internal `Vec`.
51
78
#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
52
- pub struct NodeId ( usize ) ;
79
+ pub struct NodeId ( NonZeroUsize ) ;
80
+
81
+ const ROOT : NodeId = NodeId ( unsafe { NonZeroUsize :: new_unchecked ( 1 ) } ) ;
53
82
54
83
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
55
84
struct Node < T > {
@@ -64,7 +93,7 @@ fn _static_assert_size_of_node() {
64
93
// "Instanciating" the generic `transmute` function without calling it
65
94
// still triggers the magic compile-time check
66
95
// that input and output types have the same `size_of()`.
67
- let _ = std:: mem:: transmute :: < Node < ( ) > , [ usize ; 9 ] > ;
96
+ let _ = std:: mem:: transmute :: < Node < ( ) > , [ usize ; 5 ] > ;
68
97
}
69
98
70
99
impl < T > Node < T > {
@@ -120,33 +149,42 @@ impl<'a, T: 'a> PartialEq for NodeRef<'a, T> {
120
149
impl < T > Tree < T > {
121
150
/// Creates a tree with a root node.
122
151
pub fn new ( root : T ) -> Self {
123
- Tree { vec : vec ! [ Node :: new ( root) ] }
152
+ Self :: with_capacity ( root, 1 )
124
153
}
125
154
126
155
/// Creates a tree with a root node and the specified capacity.
127
156
pub fn with_capacity ( root : T , capacity : usize ) -> Self {
128
- let mut vec = Vec :: with_capacity ( capacity) ;
157
+ let mut vec = Vec :: with_capacity ( capacity. saturating_add ( 1 ) ) ;
158
+ // The node at index 0 is unused and uninitialized.
159
+ // This allows using NonZeroUsize directly as an index.
160
+ //
161
+ // Safety: we requested at least 1 of capacity, so this is in bounds.
162
+ // It is up to the rest of the crate to not access this uninitialized node.
163
+ unsafe {
164
+ vec. set_len ( 1 ) ;
165
+ }
166
+ // The root node is at index 1
129
167
vec. push ( Node :: new ( root) ) ;
130
168
Tree { vec }
131
169
}
132
170
133
171
/// Returns a reference to the specified node.
134
172
pub fn get ( & self , id : NodeId ) -> Option < NodeRef < T > > {
135
- self . vec . get ( id. 0 ) . map ( |node| NodeRef { id, node, tree : self } )
173
+ self . vec . get ( id. 0 . get ( ) ) . map ( |node| NodeRef { id, node, tree : self } )
136
174
}
137
175
138
176
/// Returns a mutator of the specified node.
139
177
pub fn get_mut ( & mut self , id : NodeId ) -> Option < NodeMut < T > > {
140
- let exists = self . vec . get ( id. 0 ) . map ( |_| ( ) ) ;
178
+ let exists = self . vec . get ( id. 0 . get ( ) ) . map ( |_| ( ) ) ;
141
179
exists. map ( move |_| NodeMut { id, tree : self } )
142
180
}
143
181
144
182
unsafe fn node ( & self , id : NodeId ) -> & Node < T > {
145
- self . vec . get_unchecked ( id. 0 )
183
+ self . vec . get_unchecked ( id. 0 . get ( ) )
146
184
}
147
185
148
186
unsafe fn node_mut ( & mut self , id : NodeId ) -> & mut Node < T > {
149
- self . vec . get_unchecked_mut ( id. 0 )
187
+ self . vec . get_unchecked_mut ( id. 0 . get ( ) )
150
188
}
151
189
152
190
/// Returns a reference to the specified node.
@@ -161,17 +199,19 @@ impl<T> Tree<T> {
161
199
162
200
/// Returns a reference to the root node.
163
201
pub fn root ( & self ) -> NodeRef < T > {
164
- unsafe { self . get_unchecked ( NodeId ( 0 ) ) }
202
+ unsafe { self . get_unchecked ( ROOT ) }
165
203
}
166
204
167
205
/// Returns a mutator of the root node.
168
206
pub fn root_mut ( & mut self ) -> NodeMut < T > {
169
- unsafe { self . get_unchecked_mut ( NodeId ( 0 ) ) }
207
+ unsafe { self . get_unchecked_mut ( ROOT ) }
170
208
}
171
209
172
210
/// Creates an orphan node.
173
211
pub fn orphan ( & mut self , value : T ) -> NodeMut < T > {
174
- let id = NodeId ( self . vec . len ( ) ) ;
212
+ // Safety: vec.len() starts at 2 in Self::with_capacity and never shrinks,
213
+ // so it is non-zero.
214
+ let id = NodeId ( unsafe { NonZeroUsize :: new_unchecked ( self . vec . len ( ) ) } ) ;
175
215
self . vec . push ( Node :: new ( value) ) ;
176
216
unsafe { self . get_unchecked_mut ( id) }
177
217
}
@@ -615,8 +655,8 @@ macro_rules! tree {
615
655
impl < T : Debug > Debug for Tree < T > {
616
656
fn fmt ( & self , f : & mut Formatter ) -> Result < ( ) , fmt:: Error > {
617
657
use iter:: Edge ;
658
+ write ! ( f, "Tree {{" ) ?;
618
659
if f. alternate ( ) {
619
- write ! ( f, "Tree {{" ) ?;
620
660
for edge in self . root ( ) . traverse ( ) {
621
661
match edge {
622
662
Edge :: Open ( node) if node. has_children ( ) => {
@@ -640,7 +680,12 @@ impl<T: Debug> Debug for Tree<T> {
640
680
}
641
681
write ! ( f, " }}" )
642
682
} else {
643
- f. debug_struct ( "Tree" ) . field ( "vec" , & self . vec ) . finish ( )
683
+ write ! ( f, "Tree {{ [<uninitialized>" ) ?;
684
+ for node in & self . vec [ 1 ..] {
685
+ write ! ( f, ", " ) ?;
686
+ node. fmt ( f) ?;
687
+ }
688
+ write ! ( f, "] }}" )
644
689
}
645
690
}
646
691
}
0 commit comments