Skip to content

Commit 1f26cae

Browse files
authored
Merge pull request #19 from programble/revert-17-nonzero
Revert "Use NonZeroUsize inside NodeId"
2 parents d488a5c + aa877cc commit 1f26cae

File tree

2 files changed

+20
-86
lines changed

2 files changed

+20
-86
lines changed

src/iter.rs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use std::{mem, slice, vec};
2-
use std::num::NonZeroUsize;
1+
use std::{slice, vec};
32
use std::ops::Range;
43

54
use {Tree, NodeId, Node, NodeRef};
@@ -78,56 +77,43 @@ impl<'a, T: 'a> Clone for Nodes<'a, T> {
7877
}
7978
}
8079
impl<'a, T: 'a> ExactSizeIterator for Nodes<'a, T> { }
81-
impl<'a, T: 'a> Nodes<'a, T> {
82-
unsafe fn from_index(&self, i: usize) -> NodeRef<'a, T> {
83-
self.tree.get_unchecked(NodeId(NonZeroUsize::new_unchecked(i)))
84-
}
85-
}
8680
impl<'a, T: 'a> Iterator for Nodes<'a, T> {
8781
type Item = NodeRef<'a, T>;
8882
fn next(&mut self) -> Option<Self::Item> {
89-
// Safety: `i` is in `1..self.vec.len()`, so it is non-zero and in bounds.
90-
self.iter.next().map(|i| unsafe { self.from_index(i) })
83+
self.iter.next().map(|i| unsafe { self.tree.get_unchecked(NodeId(i)) })
9184
}
9285
fn size_hint(&self) -> (usize, Option<usize>) {
9386
self.iter.size_hint()
9487
}
9588
}
9689
impl<'a, T: 'a> DoubleEndedIterator for Nodes<'a, T> {
9790
fn next_back(&mut self) -> Option<Self::Item> {
98-
// Safety: `i` is in `1..self.vec.len()`, so it is non-zero and in bounds.
99-
self.iter.next_back().map(|i| unsafe { self.from_index(i) })
91+
self.iter.next_back().map(|i| unsafe { self.tree.get_unchecked(NodeId(i)) })
10092
}
10193
}
10294

10395
impl<T> IntoIterator for Tree<T> {
10496
type Item = T;
10597
type IntoIter = IntoIter<T>;
10698
fn into_iter(self) -> Self::IntoIter {
107-
let mut iter = self.vec.into_iter();
108-
// Don’t yield the uninitialized node at index 0 or run its destructor.
109-
mem::forget(iter.next());
110-
IntoIter(iter)
99+
IntoIter(self.vec.into_iter())
111100
}
112101
}
113102

114103
impl<T> Tree<T> {
115104
/// Returns an iterator over values in insert order.
116105
pub fn values(&self) -> Values<T> {
117-
// Skip over the uninitialized node at index 0
118-
Values(self.vec[1..].iter())
106+
Values(self.vec.iter())
119107
}
120108

121109
/// Returns a mutable iterator over values in insert order.
122110
pub fn values_mut(&mut self) -> ValuesMut<T> {
123-
// Skip over the uninitialized node at index 0
124-
ValuesMut(self.vec[1..].iter_mut())
111+
ValuesMut(self.vec.iter_mut())
125112
}
126113

127114
/// Returns an iterator over nodes in insert order.
128115
pub fn nodes(&self) -> Nodes<T> {
129-
// Skip over the uninitialized node at index 0
130-
Nodes { tree: self, iter: 1..self.vec.len() }
116+
Nodes { tree: self, iter: 0..self.vec.len() }
131117
}
132118
}
133119

src/lib.rs

Lines changed: 13 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -36,49 +36,20 @@
3636
)]
3737

3838
use std::fmt::{self, Debug, Formatter};
39-
use std::num::NonZeroUsize;
4039

4140
/// Vec-backed ID-tree.
4241
///
4342
/// Always contains at least a root node.
43+
#[derive(Clone, PartialEq, Eq, Hash)]
4444
pub struct Tree<T> {
45-
// Safety note: node at index 0 is uninitialized!
4645
vec: Vec<Node<T>>,
4746
}
4847

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-
7548
/// Node ID.
7649
///
7750
/// Index into a `Tree`-internal `Vec`.
7851
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
79-
pub struct NodeId(NonZeroUsize);
80-
81-
const ROOT: NodeId = NodeId(unsafe { NonZeroUsize::new_unchecked(1) });
52+
pub struct NodeId(usize);
8253

8354
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8455
struct Node<T> {
@@ -89,13 +60,6 @@ struct Node<T> {
8960
value: T,
9061
}
9162

92-
fn _static_assert_size_of_node() {
93-
// "Instanciating" the generic `transmute` function without calling it
94-
// still triggers the magic compile-time check
95-
// that input and output types have the same `size_of()`.
96-
let _ = std::mem::transmute::<Node<()>, [usize; 5]>;
97-
}
98-
9963
impl<T> Node<T> {
10064
fn new(value: T) -> Self {
10165
Node {
@@ -149,42 +113,33 @@ impl<'a, T: 'a> PartialEq for NodeRef<'a, T> {
149113
impl<T> Tree<T> {
150114
/// Creates a tree with a root node.
151115
pub fn new(root: T) -> Self {
152-
Self::with_capacity(root, 1)
116+
Tree { vec: vec![Node::new(root)] }
153117
}
154118

155119
/// Creates a tree with a root node and the specified capacity.
156120
pub fn with_capacity(root: T, capacity: usize) -> Self {
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
121+
let mut vec = Vec::with_capacity(capacity);
167122
vec.push(Node::new(root));
168123
Tree { vec }
169124
}
170125

171126
/// Returns a reference to the specified node.
172127
pub fn get(&self, id: NodeId) -> Option<NodeRef<T>> {
173-
self.vec.get(id.0.get()).map(|node| NodeRef { id, node, tree: self })
128+
self.vec.get(id.0).map(|node| NodeRef { id, node, tree: self })
174129
}
175130

176131
/// Returns a mutator of the specified node.
177132
pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<T>> {
178-
let exists = self.vec.get(id.0.get()).map(|_| ());
133+
let exists = self.vec.get(id.0).map(|_| ());
179134
exists.map(move |_| NodeMut { id, tree: self })
180135
}
181136

182137
unsafe fn node(&self, id: NodeId) -> &Node<T> {
183-
self.vec.get_unchecked(id.0.get())
138+
self.vec.get_unchecked(id.0)
184139
}
185140

186141
unsafe fn node_mut(&mut self, id: NodeId) -> &mut Node<T> {
187-
self.vec.get_unchecked_mut(id.0.get())
142+
self.vec.get_unchecked_mut(id.0)
188143
}
189144

190145
/// Returns a reference to the specified node.
@@ -199,19 +154,17 @@ impl<T> Tree<T> {
199154

200155
/// Returns a reference to the root node.
201156
pub fn root(&self) -> NodeRef<T> {
202-
unsafe { self.get_unchecked(ROOT) }
157+
unsafe { self.get_unchecked(NodeId(0)) }
203158
}
204159

205160
/// Returns a mutator of the root node.
206161
pub fn root_mut(&mut self) -> NodeMut<T> {
207-
unsafe { self.get_unchecked_mut(ROOT) }
162+
unsafe { self.get_unchecked_mut(NodeId(0)) }
208163
}
209164

210165
/// Creates an orphan node.
211166
pub fn orphan(&mut self, value: T) -> NodeMut<T> {
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()) });
167+
let id = NodeId(self.vec.len());
215168
self.vec.push(Node::new(value));
216169
unsafe { self.get_unchecked_mut(id) }
217170
}
@@ -675,8 +628,8 @@ macro_rules! tree {
675628
impl<T: Debug> Debug for Tree<T> {
676629
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
677630
use iter::Edge;
678-
write!(f, "Tree {{")?;
679631
if f.alternate() {
632+
write!(f, "Tree {{")?;
680633
for edge in self.root().traverse() {
681634
match edge {
682635
Edge::Open(node) if node.has_children() => {
@@ -700,12 +653,7 @@ impl<T: Debug> Debug for Tree<T> {
700653
}
701654
write!(f, " }}")
702655
} else {
703-
write!(f, "Tree {{ [<uninitialized>")?;
704-
for node in &self.vec[1..] {
705-
write!(f, ", ")?;
706-
node.fmt(f)?;
707-
}
708-
write!(f, "] }}")
656+
f.debug_struct("Tree").field("vec", &self.vec).finish()
709657
}
710658
}
711659
}

0 commit comments

Comments
 (0)