@@ -61,21 +61,21 @@ list many times. With the cursor interface, one can do the following:
6161
6262``` rust
6363fn 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
6565{
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+ }
7979}
8080```
8181
@@ -84,31 +84,31 @@ iterator, perform operations on it and collect. This is easier, however it still
8484requires much needless allocation.
8585
8686For another example, consider code that was previously using ` IterMut `
87- extensions.
87+ extensions.
8888``` rust
8989fn 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 );
9898}
9999```
100100This can be changed almost verbatim to ` CursorMut ` :
101101``` rust
102102fn 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 );
112112}
113113```
114114In 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
122122returned cursor would point to the "empty" element, i.e. if you got an element
123123and called ` current ` you would receive ` None ` .
124124``` 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 >;
127127
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 >;
130136```
131137
132138These would provide the following interface:
133139
134140``` rust
135141impl <'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 >;
148157}
149158
150159impl <'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 >;
191200}
192201```
193202One should closely consider the lifetimes in this interface. Both ` Cursor ` and
194203` CursorMut ` operate on data in their ` LinkedList ` . This is why, they both hold
195204the annotation of ` 'list ` .
196205
197206The 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 >
200209```
201210becomes
202- ```
203- pub fn cursor <'list>(&'list self) -> Cursor<'list, T>
211+ ```rust
212+ pub fn cursor_front <'list >(& 'list self ) -> Cursor <'list , T >
204213```
205214which is what we would expect . (the same goes for `CursorMut `).
206215
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
209218these methods borrow . Otherwise , one could produce multiple mutable references
210219to the same element .
211220
0 commit comments