1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
5 # This file is free software, which comes along with NIT. This software is
6 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 # is kept unaltered, and a notification of the changes is added.
10 # You are allowed to redistribute it and sell it, alone or is a part of
13 # This module handle double linked lists
16 import abstract_collection
18 # Double linked lists.
24 redef fun [](index
) do return get_node
(index
).as(not null).item
26 redef fun []=(index
, item
) do get_node
(index
).as(not null).item
= item
29 redef fun first
do return _head
.as(not null).item
32 redef fun first
=(e
) do _head
.as(not null).item
= e
35 redef fun last
do return _tail
.as(not null).item
38 redef fun last
=(e
) do _tail
.as(not null).item
= e
43 redef fun is_empty
do return _head
== null
49 redef fun has
(e
) do return search_node_after
(e
, _head
) != null
55 if node
.item
!= e
then return false
66 if node
.item
!= e
then nb
+= 1
72 # Return a list of elements between 'from' and 'to'.
73 fun slice
(from
: Int, to
: Int): List[E
] do
74 assert from
>= 0 and from
< length
75 assert to
>= 0 and to
< length
and from
<= to
76 var list
= new List[E
]
89 var node
= new ListNode[E
](e
)
104 var node
= new ListNode[E
](e
)
117 redef fun insert
(e
, i
)
119 var node
= get_node
(i
)
124 insert_before
(e
, node
)
127 # Append `l` to `self` but clear `l`.
135 else if l
._head
!= null then
137 tail
.next
.as(not null).prev
= tail
149 var node
= _tail
.as(not null)
152 if _tail
== null then
155 _tail
.as(not null).next
= null
164 var node
= _head
.as(not null)
167 if _head
== null then
170 _head
.as(not null).prev
= null
178 var node
= search_node_after
(e
, _head
)
179 if node
!= null then remove_node
(node
)
182 redef fun remove_at
(i
)
184 var node
= get_node
(i
)
185 if node
!= null then remove_node
(node
)
196 redef fun iterator
: ListIterator[E
] do return new ListIterator[E
](self)
197 redef fun reverse_iterator
: ListIterator[E
] do return new ListReverseIterator[E
](self)
199 # Build an empty list.
202 # Build a list filled with the items of `coll`.
203 init from
(coll
: Collection[E
]) do append
(coll
)
205 # The first node of the list
206 private var head
: nullable ListNode[E
] = null
208 # The last node of the list
209 private var tail
: nullable ListNode[E
] = null
211 # Get the `i`th node. get `null` otherwise.
212 private fun get_node
(i
: Int): nullable ListNode[E
]
218 while n
!= null and i
> 0 do
225 # get the first node that contains `e` after 'after', null otherwise
226 private fun search_node_after
(e
: E
, after
: nullable ListNode[E
]): nullable ListNode[E
]
229 while n
!= null and n
.item
!= e
do n
= n
.next
233 # Remove the node (ie. atach prev and next)
234 private fun remove_node
(node
: ListNode[E
])
237 if node
.prev
== null then
239 if node
.next
== null then
242 node
.next
.as(not null).prev
= null
244 else if node
.next
== null then
246 node
.prev
.as(not null).next
= null
248 node
.prev
.as(not null).next
= node
.next
249 node
.next
.as(not null).prev
= node
.prev
253 private fun insert_before
(element
: E
, node
: ListNode[E
])
256 var nnode
= new ListNode[E
](element
)
269 # This is the iterator class of List
270 class ListIterator[E
]
271 super IndexedIterator[E
]
272 redef fun item
do return _node
.as(not null).item
274 # Set item `e` at self `index`.
275 fun item
=(e
: E
) do _node
.as(not null).item
= e
277 redef fun is_ok
do return not _node
== null
281 _node
= _node
.as(not null).next
285 # Build a new iterator for `list`.
292 private var list
: List[E
]
294 # The current node of the list
295 private var node
: nullable ListNode[E
] = null
297 # The index of the current node
300 # Remove the current item
303 _list
.remove_node
(_node
.as(not null))
306 # Insert before the current item
307 fun insert_before
(element
: E
)
309 _list
.insert_before
(element
, _node
.as(not null))
313 private class ListReverseIterator[E
]
314 super ListIterator[E
]
318 _node
= _node
.as(not null).prev
330 # Linked nodes that constitute a linked list.
331 private class ListNode[E
]
335 var next
: nullable ListNode[E
] = null
338 var prev
: nullable ListNode[E
] = null