You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+16-9Lines changed: 16 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,9 +3,9 @@
3
3
4
4
This crate provides types to safely store mutable references to parent nodes, for backtracking during traversal of tree & graph structures.
5
5
6
-
[MutCursor] is more efficient because it avoids dynamic allocation, while [MutCursorVec] provides for an arbitrarily deep stack.
6
+
[`MutCursor`] is more efficient because it avoids dynamic allocation, while [`MutCursorVec`] provides for an arbitrarily deep stack.
7
7
8
-
[MutCursorRootedVec] supports mutable references to a separate root type and a different leaf type. In the future I may generalize this pattern to be more flexible.**WARNING**`MutCursorRootedVec` is unsound when the root object owns the memory it references!
8
+
[`MutCursorRootedVec`] supports mutable references to a separate root type and a different leaf type. In the future I may generalize this pattern to be more flexible.
9
9
10
10
## Usage
11
11
```rust
@@ -49,15 +49,15 @@ impl TreeNode {
49
49
50
50
This crate basically does the same thing as [generic-cursors](https://crates.io/crates/generic-cursors). However, there are several reasons to choose this crate:
51
51
52
-
1. The fixed-size stack used by [MutCursor] has lower overhead than a [Vec](https://doc.rust-lang.org/std/vec/struct.Vec.html), and can be used in a `no_std` environment where dynamic allocation may be unavailable.
52
+
1. The fixed-size stack used by [`MutCursor`] has lower overhead than a [`Vec`], and can be used in a `no_std` environment where dynamic allocation may be unavailable.
53
53
54
-
2. The [MutCursor::try_map_into_mut] API enables some paterns that would be otherwise impossible.
54
+
2. The [`MutCursor::try_map_into_mut`] API enables some patterns that would be otherwise impossible.
55
55
56
56
## Safety Thesis
57
57
58
-
Each `&mut` reference stored by a [MutCursor] mutably borrows the reference beneath it in the stack. The stack root takes a mutable (and therefore exclusive) borrow of the node itself. Therefore the stack's [top](MutCursor::top) is an exclusive borrow.
58
+
Each `&mut` reference stored by a [`MutCursor`] mutably borrows the reference beneath it in the stack. The stack root takes a mutable (and therefore exclusive) borrow of the node itself. Therefore the stack's [`top`] is an exclusive borrow.
59
59
60
-
You can imagine unrolling tree traversal into something like the code below, but this isn't amenable to looping. In essence each `level` variable is preserved, but inaccessible because the level above is mutably borrowing it. The [MutCursor] object contains all the `level` variables but only provides access to the [top](MutCursor::top)
60
+
You can imagine unrolling tree traversal into something like the code below, but this isn't amenable to looping. In essence each `level` variable is preserved, but inaccessible because the level above is mutably borrowing it. The [`MutCursor`] object contains all the `level` variables but only provides access to the [`top`].
61
61
62
62
```rust ignore
63
63
letlevel_1=&mutroot;
@@ -76,12 +76,19 @@ let level_1 = &mut root;
76
76
77
77
#### Macro to define cursor types
78
78
79
-
In the current design of [MutCursorRootedVec], there is a predefined pattern prescribing where `RootT` and `NodeT` types may exist on the stack. However, we may find it necessary in the future to support more than two types, in a more flexible pattern. It seems that a macro to define a bespoke cursor type is the best solutuion.
79
+
In the current design of [`MutCursorRootedVec`], there is a predefined pattern prescribing where `RootT` and `NodeT` types may exist on the stack. However, we may find it necessary in the future to support more than two types, in a more flexible pattern. It seems that a macro to define a bespoke cursor type is the best solutuion.
80
80
81
81
#### Internal enum for multiple-type support at runtime
82
82
83
-
For ultimate flexibility, we would want all the references to be stored by the stack as in an enum over the possible reference types. However, if ther user provided an enum as a type parameter to a cursor type, the result result would be double-indirection. Therefore the enum behavior would need to be internal to the MutCursor. Deriving a MutCursor from a user's enum type feels like a friendly way to define the types a cursor type is capable of storing.
83
+
For ultimate flexibility, we would want all the references to be stored by the stack as in an enum over the possible reference types. However, if the user provided an enum as a type parameter to a cursor type, the result result would be double-indirection. Therefore the enum behavior would need to be internal to the MutCursor. Deriving a MutCursor from a user's enum type feels like a friendly way to define the types a cursor type is capable of storing.
84
84
85
85
## Acknowledgements
86
86
87
-
[Frank Steffahn](https://github.com/steffahn) identified soundness issues and potential improvements in prior versions of this crate.
87
+
[Frank Steffahn](https://github.com/steffahn) identified soundness issues and potential improvements in prior versions of this crate.
0 commit comments