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
///
@@ -49,7 +50,20 @@ pub struct Tree<T> {
49
50
///
50
51
/// Index into a `Tree`-internal `Vec`.
51
52
#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
52
- pub struct NodeId ( usize ) ;
53
+ pub struct NodeId ( NonZeroUsize ) ;
54
+
55
+ impl NodeId {
56
+ // Safety: `n` must not equal `usize::MAX`.
57
+ // (This is never the case for `Vec::len()`, that would mean it owns
58
+ // the entire address space without leaving space for even the its pointer.)
59
+ unsafe fn from_index ( n : usize ) -> Self {
60
+ NodeId ( NonZeroUsize :: new_unchecked ( n + 1 ) )
61
+ }
62
+
63
+ fn to_index ( self ) -> usize {
64
+ self . 0 . get ( ) - 1
65
+ }
66
+ }
53
67
54
68
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
55
69
struct Node < T > {
@@ -60,6 +74,13 @@ struct Node<T> {
60
74
value : T ,
61
75
}
62
76
77
+ fn _static_assert_size_of_node ( ) {
78
+ // "Instanciating" the generic `transmute` function without calling it
79
+ // still triggers the magic compile-time check
80
+ // that input and output types have the same `size_of()`.
81
+ let _ = std:: mem:: transmute :: < Node < ( ) > , [ usize ; 5 ] > ;
82
+ }
83
+
63
84
impl < T > Node < T > {
64
85
fn new ( value : T ) -> Self {
65
86
Node {
@@ -125,21 +146,21 @@ impl<T> Tree<T> {
125
146
126
147
/// Returns a reference to the specified node.
127
148
pub fn get ( & self , id : NodeId ) -> Option < NodeRef < T > > {
128
- self . vec . get ( id. 0 ) . map ( |node| NodeRef { id, node, tree : self } )
149
+ self . vec . get ( id. to_index ( ) ) . map ( |node| NodeRef { id, node, tree : self } )
129
150
}
130
151
131
152
/// Returns a mutator of the specified node.
132
153
pub fn get_mut ( & mut self , id : NodeId ) -> Option < NodeMut < T > > {
133
- let exists = self . vec . get ( id. 0 ) . map ( |_| ( ) ) ;
154
+ let exists = self . vec . get ( id. to_index ( ) ) . map ( |_| ( ) ) ;
134
155
exists. map ( move |_| NodeMut { id, tree : self } )
135
156
}
136
157
137
158
unsafe fn node ( & self , id : NodeId ) -> & Node < T > {
138
- self . vec . get_unchecked ( id. 0 )
159
+ self . vec . get_unchecked ( id. to_index ( ) )
139
160
}
140
161
141
162
unsafe fn node_mut ( & mut self , id : NodeId ) -> & mut Node < T > {
142
- self . vec . get_unchecked_mut ( id. 0 )
163
+ self . vec . get_unchecked_mut ( id. to_index ( ) )
143
164
}
144
165
145
166
/// Returns a reference to the specified node.
@@ -154,17 +175,17 @@ impl<T> Tree<T> {
154
175
155
176
/// Returns a reference to the root node.
156
177
pub fn root ( & self ) -> NodeRef < T > {
157
- unsafe { self . get_unchecked ( NodeId ( 0 ) ) }
178
+ unsafe { self . get_unchecked ( NodeId :: from_index ( 0 ) ) }
158
179
}
159
180
160
181
/// Returns a mutator of the root node.
161
182
pub fn root_mut ( & mut self ) -> NodeMut < T > {
162
- unsafe { self . get_unchecked_mut ( NodeId ( 0 ) ) }
183
+ unsafe { self . get_unchecked_mut ( NodeId :: from_index ( 0 ) ) }
163
184
}
164
185
165
186
/// Creates an orphan node.
166
187
pub fn orphan ( & mut self , value : T ) -> NodeMut < T > {
167
- let id = NodeId ( self . vec . len ( ) ) ;
188
+ let id = unsafe { NodeId :: from_index ( self . vec . len ( ) ) } ;
168
189
self . vec . push ( Node :: new ( value) ) ;
169
190
unsafe { self . get_unchecked_mut ( id) }
170
191
}
0 commit comments