@@ -61,21 +61,21 @@ list many times. With the cursor interface, one can do the following:
61
61
62
62
``` rust
63
63
fn remove_replace <T , P , F >(list : & mut LinkedList <T >, p : P , f : F )
64
- where P : Fn (& T ) -> bool , F : Fn (T ) -> T
64
+ where P : Fn (& T ) -> bool , F : Fn (T ) -> T
65
65
{
66
- let mut cursor = list . cursor_mut ();
67
- // move to the first element, if it exists
68
- loop {
69
- let should_replace = match cursor . peek () {
70
- Some (element ) => p (element ),
71
- None => break ,
72
- };
73
- if should_replace {
74
- let old_element = cursor . pop (). unwrap ();
75
- cursor . insert (f (old_element ));
76
- }
77
- cursor . move_next ();
78
- }
66
+ let mut cursor = list . cursor_front_mut ();
67
+ // move to the first element, if it exists
68
+ loop {
69
+ let should_replace = match cursor . peek_next () {
70
+ Some (element ) => p (element ),
71
+ None => break ,
72
+ };
73
+ if should_replace {
74
+ let old_element = cursor . remove_current (). unwrap ();
75
+ cursor . insert_after (f (old_element ));
76
+ }
77
+ cursor . move_next ();
78
+ }
79
79
}
80
80
```
81
81
@@ -84,31 +84,31 @@ iterator, perform operations on it and collect. This is easier, however it still
84
84
requires much needless allocation.
85
85
86
86
For another example, consider code that was previously using ` IterMut `
87
- extensions.
87
+ extensions.
88
88
``` rust
89
89
fn main () {
90
- let mut list : LinkedList <_ > = (0 .. 10 ). collect ();
91
- let mut iter = list . iter_mut ();
92
- while let Some (x ) = iter . next () {
93
- if x >= 5 {
94
- break ;
95
- }
96
- }
97
- iter . insert_next (12 );
90
+ let mut list : LinkedList <_ > = (0 .. 10 ). collect ();
91
+ let mut iter = list . iter_mut ();
92
+ while let Some (x ) = iter . next () {
93
+ if x >= 5 {
94
+ break ;
95
+ }
96
+ }
97
+ iter . insert_next (12 );
98
98
}
99
99
```
100
100
This can be changed almost verbatim to ` CursorMut ` :
101
101
``` rust
102
102
fn main () {
103
- let mut list : LinkedList <_ > = (0 .. 10 ). collect ();
104
- let mut cursor = list . cursor_mut () {
105
- while let Some (x ) = cursor . peek_next () {
106
- if x >= 5 {
107
- break ;
108
- }
109
- cursor . move_next ();
110
- }
111
- cursor . insert (12 );
103
+ let mut list : LinkedList <_ > = (0 .. 10 ). collect ();
104
+ let mut cursor = list . cursor_front_mut () {
105
+ while let Some (x ) = cursor . peek_next () {
106
+ if x >= 5 {
107
+ break ;
108
+ }
109
+ cursor . move_next ();
110
+ }
111
+ cursor . insert_after (12 );
112
112
}
113
113
```
114
114
In general, the cursor interface is not the easiest way to do something.
@@ -122,90 +122,99 @@ One gets a cursor the exact same way as one would get an iterator. The
122
122
returned cursor would point to the "empty" element, i.e. if you got an element
123
123
and called ` current ` you would receive ` None ` .
124
124
``` rust
125
- // Provides a cursor to the first element of the list
126
- pub fn cursor (& self ) -> Cursor <T >;
125
+ /// Provides a cursor to the first element of the list.
126
+ pub fn cursor_front (& self ) -> Cursor <T >;
127
127
128
- /// Provides a cursor with mutable references and access to the list
129
- pub fn cursor_mut (& mut self ) -> CursorMut <T >;
128
+ /// Provides a mutable cursor to the first element of the list.
129
+ pub fn cursor_front_mut (& mut self ) -> CursorMut <T >;
130
+
131
+ /// Provides a cursor to the last element of the list.
132
+ pub fn cursor_back (& self ) -> Cursor <T >;
133
+
134
+ /// Provides a mutable cursor to the last element of the list.
135
+ pub fn cursor_back_mut (& mut self ) -> CursorMut <T >;
130
136
```
131
137
132
138
These would provide the following interface:
133
139
134
140
``` rust
135
141
impl <'list , T > Cursor <'list , T > {
136
- /// Move to the subsequent element of the list if it exists or the empty
137
- /// element
138
- pub fn move_next (& mut self );
139
- /// Move to the previous element of the list
140
- pub fn move_prev (& mut self );
141
-
142
- /// Get the current element
143
- pub fn current (& self ) -> Option <& 'list T >;
144
- /// Get the following element
145
- pub fn peek (& self ) -> Option <& 'list T >;
146
- /// Get the previous element
147
- pub fn peek_before (& self ) -> Option <& 'list T >;
142
+ /// Returns the cursor position index within the `LinkedList`.
143
+ pub fn index (& self ) -> Option <usize >;
144
+
145
+ /// Move to the subsequent element of the list if it exists or the empty
146
+ /// element
147
+ pub fn move_next (& mut self );
148
+ /// Move to the previous element of the list
149
+ pub fn move_prev (& mut self );
150
+
151
+ /// Get the current element
152
+ pub fn current (& self ) -> Option <& 'list T >;
153
+ /// Get the following element
154
+ pub fn peek_next (& self ) -> Option <& 'list T >;
155
+ /// Get the previous element
156
+ pub fn peek_prev (& self ) -> Option <& 'list T >;
148
157
}
149
158
150
159
impl <'list T > CursorMut <'list , T > {
151
- /// Move to the subsequent element of the list if it exists or the empty
152
- /// element
153
- pub fn move_next ( & mut self );
154
- /// Move to the previous element of the list
155
- pub fn move_prev ( & mut self );
156
-
157
- /// Get the current element
158
- pub fn current (& mut self ) -> Option < & mut T > ;
159
- /// Get the next element
160
- pub fn peek ( & mut self ) -> Option < & mut T >;
161
- /// Get the previous element
162
- pub fn peek_before ( & mut self ) -> Option < & mut T >;
163
-
164
- /// Get an immutable cursor at the current element
165
- pub fn as_cursor <' cm >( & ' cm self ) -> Cursor <' cm , T >;
166
-
167
- // Now the list editing operations
168
-
169
- /// Insert `item` after the cursor
170
- pub fn insert ( & mut self , item : T );
171
- /// Insert `item` before the cursor
172
- pub fn insert_before ( & mut self , item : T );
173
-
174
- /// Remove and return the item following the cursor
175
- pub fn pop (& mut self ) -> Option < T > ;
176
- /// Remove and return the item before the cursor
177
- pub fn pop_before ( & mut self ) -> Option < T >;
178
-
179
- /// Insert `list` between the current element and the next
180
- pub fn insert_list ( & mut self , list : LinkedList < T >);
181
- /// Insert `list` between the previous element and current
182
- pub fn insert_list_before (& mut self , list : LinkedList <T >);
183
-
184
- /// Split the list in two after the current element
185
- /// The returned list consists of all elements following the current one.
186
- // note: consuming the cursor is not necessary here, but it makes sense
187
- // given the interface
188
- pub fn split ( self ) -> LinkedList <T >;
189
- /// Split the list in two before the current element
190
- pub fn split_before (self ) -> LinkedList <T >;
160
+ /// Returns the cursor position index within the `LinkedList`.
161
+ pub fn index ( & self ) -> Option < usize >;
162
+
163
+ /// Move to the subsequent element of the list if it exists or the empty
164
+ /// element
165
+ pub fn move_next ( & mut self );
166
+ /// Move to the previous element of the list
167
+ pub fn move_prev (& mut self );
168
+
169
+ /// Get the current element
170
+ pub fn current ( & mut self ) -> Option < & mut T >;
171
+ /// Get the next element
172
+ pub fn peek_next ( & mut self ) -> Option < & mut T >;
173
+ /// Get the previous element
174
+ pub fn peek_prev ( & mut self ) -> Option < & mut T >;
175
+
176
+ /// Get an immutable cursor at the current element
177
+ pub fn as_cursor <' cm >( & ' cm self ) -> Cursor <' cm , T >;
178
+
179
+ // Now the list editing operations
180
+
181
+ /// Insert ` item` after the cursor
182
+ pub fn insert_after ( & mut self , item : T );
183
+ /// Insert ` item` before the cursor
184
+ pub fn insert_before (& mut self , item : T ) ;
185
+
186
+ /// Remove the current item. The new current item is the item following the
187
+ /// removed one.
188
+ pub fn remove_current ( & mut self ) -> Option < T >;
189
+
190
+ /// Insert `list` between the current element and the next
191
+ pub fn splice_after (& mut self , list : LinkedList <T >);
192
+ /// Insert `list` between the previous element and current
193
+ pub fn splice_before ( & mut self , list : LinkedList < T >);
194
+
195
+ /// Split the list in two after the current element
196
+ /// The returned list consists of all elements following the current one.
197
+ pub fn split_after ( & mut self ) -> LinkedList <T >;
198
+ /// Split the list in two before the current element
199
+ pub fn split_before (& mut self ) -> LinkedList <T >;
191
200
}
192
201
```
193
202
One should closely consider the lifetimes in this interface. Both ` Cursor ` and
194
203
` CursorMut ` operate on data in their ` LinkedList ` . This is why, they both hold
195
204
the annotation of ` 'list ` .
196
205
197
206
The lifetime elision for their constructors is correct as
198
- ```
199
- pub fn cursor (&self) -> Cursor<T>
207
+ ``` rust
208
+ pub fn cursor_front (& self ) -> Cursor <T >
200
209
```
201
210
becomes
202
- ```
203
- pub fn cursor <'list>(&'list self) -> Cursor<'list, T>
211
+ ```rust
212
+ pub fn cursor_front <'list >(& 'list self ) -> Cursor <'list , T >
204
213
```
205
214
which is what we would expect . (the same goes for `CursorMut `).
206
215
207
- Since ` Cursor ` cannot mutate its list, ` current ` , ` peek ` and ` peek_before ` all
208
- live as long as ` 'list ` . However, in ` CursorMut ` we must be careful to make
216
+ Since `Cursor ` cannot mutate its list , `current `, `peek_next ` and `peek_prev `
217
+ all live as long as `'list `. However , in `CursorMut ` we must be careful to make
209
218
these methods borrow . Otherwise , one could produce multiple mutable references
210
219
to the same element .
211
220
0 commit comments