3 * Copyright (C) 2004-2005 Novell, Inc
4 * Copyright (C) 2005 David Waite
5 * Copyright (C) 2007-2008 Jürg Billeter
6 * Copyright (C) 2009 Mark Lee, Didier Villevalois
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * Mark Lee <marklee@src.gnome.org>
24 * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
28 * Doubly-linked list implementation of the {@link List} interface.
30 * This implementation is pretty well designed for highly mutable data. When
31 * indexed access is privileged prefer using {@link ArrayList}.
35 public class Gee.LinkedList<G> : AbstractBidirList<G>, Queue<G>, Deque<G> {
36 private int _size = 0;
37 private int _stamp = 0;
38 private Node<G>? _head = null;
39 private weak Node<G>? _tail = null;
42 * The elements' equality testing function.
44 [CCode (notify = false)]
45 public EqualDataFunc<G> equal_func { private set; get; }
48 * Constructs a new, empty linked list.
50 * If not provided, the function parameter is requested to the
51 * {@link Functions} function factory methods.
53 * @param equal_func an optional element equality testing function
55 public LinkedList (owned EqualDataFunc<G>? equal_func = null) {
56 if (equal_func == null) {
57 equal_func = Functions.get_equal_func_for (typeof (G));
59 this.equal_func = equal_func;
69 public override bool foreach(ForallFunc<G> f) {
70 for (weak Node<G>? node = _head; node != null; node = node.next) {
81 public override Gee.Iterator<G> iterator () {
82 return new Iterator<G> (this);
88 public override ListIterator<G> list_iterator () {
89 return new Iterator<G> (this);
95 public override BidirListIterator<G> bidir_list_iterator () {
96 return new Iterator<G> (this);
102 public override int size {
103 get { return this._size; }
109 public override bool read_only {
110 get { return false; }
116 public override bool contains (G item) {
117 return this.index_of (item) != -1;
123 public override bool add (G item) {
124 Node<G> n = new Node<G> (item);
125 if (this._head == null && this._tail == null) {
127 this._head = (owned) n;
130 this._tail.next = (owned) n;
131 this._tail = this._tail.next;
134 // Adding items to the list during iterations is allowed.
144 public override bool remove (G item) { // Should remove only the first occurence (a test should be added)
145 for (weak Node<G> n = this._head; n != null; n = n.next) {
146 if (this.equal_func (item, n.data)) {
147 this._remove_node (n);
157 public override void clear () {
158 while (_head != null) {
159 _remove_node (_head);
171 public override G get (int index) {
173 assert (index < this._size);
175 unowned Node<G>? n = this._get_node_at (index);
183 public override void set (int index, G item) {
185 assert (index < this._size);
187 unowned Node<G>? n = this._get_node_at (index);
188 return_if_fail (n != null);
195 public override int index_of (G item) {
197 for (weak Node<G>? node = _head; node != null; node = node.next, idx++) {
198 if (this.equal_func (item, node.data)) {
208 public override void insert (int index, G item) {
210 assert (index <= this._size);
212 if (index == this._size) {
215 Node<G> n = new Node<G> (item);
217 n.next = (owned) this._head;
219 this._head = (owned)n;
221 weak Node prev = this._head;
222 for (int i = 0; i < index - 1; i++) {
226 n.next = (owned) prev.next;
228 prev.next = (owned) n;
231 // Adding items to the list during iterations is allowed.
241 public override G remove_at (int index) {
243 assert (index < this._size);
245 unowned Node<G>? n = this._get_node_at (index);
248 this._remove_node (n);
255 public override List<G>? slice (int start, int stop) {
256 return_val_if_fail (start <= stop, null);
257 return_val_if_fail (start >= 0, null);
258 return_val_if_fail (stop <= this._size, null);
260 List<G> slice = new LinkedList<G> (this.equal_func);
261 weak Node<G> n = this._get_node_at (start);
262 for (int i = start; i < stop; i++) {
289 public int capacity {
290 get { return UNBOUNDED_CAPACITY; }
296 public int remaining_capacity {
297 get { return UNBOUNDED_CAPACITY; }
303 public bool is_full {
304 get { return false; }
310 public bool offer (G element) {
311 return offer_tail (element);
331 public int drain (Collection<G> recipient, int amount = -1) {
332 return drain_head (recipient, amount);
338 public bool offer_head (G element) {
346 public G? peek_head () {
347 if (this._size == 0) {
356 public G? poll_head () {
357 if (this._size == 0) {
360 return remove_at (0);
366 public int drain_head (Collection<G> recipient, int amount = -1) {
370 for (int i = 0; i < amount; i++) {
371 if (this._size == 0) {
374 recipient.add (remove_at (0));
382 public bool offer_tail (G element) {
383 return add (element);
389 public G? peek_tail () {
390 if (this._size == 0) {
393 return get (_size - 1);
399 public G? poll_tail () {
400 if (this._size == 0) {
403 return remove_at (_size - 1);
409 public int drain_tail (Collection<G> recipient, int amount = -1) {
413 for (int i = 0; i < amount; i++) {
414 if (this._size == 0) {
417 recipient.add (remove_at (this._size - 1));
423 private class Node<G> { // Maybe a compact class should be used?
425 public weak Node<G>? prev = null;
426 public Node<G>? next = null;
427 public Node (owned G data) {
432 private class Iterator<G> : Object, Traversable<G>, Gee.Iterator<G>, BidirIterator<G>, ListIterator<G>, BidirListIterator<G> {
433 private bool started = false;
434 private bool removed = false;
435 private unowned Node<G>? position;
437 private LinkedList<G> _list;
440 public Iterator (LinkedList<G> list) {
442 this.position = null;
444 this._stamp = list._stamp;
447 public bool next () {
448 assert (this._stamp == this._list._stamp);
451 if (this.position != null) {
452 this.removed = false;
457 } else if (!this.started) {
458 if (this._list._head != null) {
460 this.position = this._list._head;
466 } else if (this.position != null) {
467 if (this.position.next != null) {
468 this.position = this.position.next;
478 public bool has_next () {
479 assert (this._stamp == this._list._stamp);
482 return this.position != null;
483 } else if (!this.started) {
484 return this._list._head != null;
485 } else if (this.position != null) {
486 return this.position.next != null;
491 public bool first () {
492 assert (this._stamp == this._list._stamp);
493 if (this._list.size == 0) {
496 this.position = this._list._head;
499 this.removed = false;
500 return this.position != null;
503 public new G get () {
504 assert (this._stamp == this._list._stamp);
505 assert (this.position != null);
507 return this.position.data;
510 public void remove () {
511 assert (this._stamp == this._list._stamp);
512 assert (this.position != null);
514 unowned Node<G>? new_position = this.position.next;
515 if (new_position == null) {
518 _list._remove_node (this.position);
519 this.position = new_position;
521 this._stamp = this._list._stamp;
524 public bool previous () {
525 assert (this._stamp == this._list._stamp);
528 this.position = null;
530 } else if (this.position != null && this.position.prev != null) {
531 this.position = this.position.prev;
538 public bool has_previous () {
539 assert (this._stamp == this._list._stamp);
543 } else if (this.position != null) {
544 return this.position.prev != null;
549 public bool last () {
550 assert (this._stamp == this._list._stamp);
552 if (this._list.size == 0) {
555 this.position = this._list._tail;
557 this._index = this._list._size - 1;
558 return this.position != null;
561 public new void set (G item) {
562 assert (this._stamp == this._list._stamp);
563 assert (this.position != null);
565 this.position.data = item;
568 public void insert (G item) {
569 assert (this._stamp == this._list._stamp);
570 assert (this.position != null);
572 Node<G> n = new Node<G> (item);
573 if (this.position.prev != null) {
574 Node<G> position = (owned) this.position.prev.next;
575 n.prev = position.prev;
577 n.next = (owned) position;
579 _n.prev.next = (owned) n;
581 Node<G> position = (owned) this._list._head;
583 n.next = (owned) position;
584 this._list._head = (owned) n;
588 _stamp = _list._stamp;
591 public void add (G item) {
592 assert (this._stamp == this._list._stamp);
593 assert (this.position != null);
595 Node<G> n = new Node<G> (item);
596 if (this.position.next != null) {
597 this.position.next.prev = n;
598 n.next = (owned) this.position.next;
600 this._list._tail = n;
602 this.position.next = (owned) n;
603 this.position.next.prev = this.position;
604 this.position = this.position.next;
607 _stamp = _list._stamp;
610 public int index () {
611 assert (this._stamp == this._list._stamp);
612 assert (this.position != null);
617 public bool read_only {
625 return !this.removed && this.position != null;
629 public bool foreach (ForallFunc<G> f) {
630 assert (_stamp == _list._stamp);
632 position = _list._head;
633 if (position != null)
637 while (position != null) {
638 if (!f (position.data)) {
641 position = position.next;
643 position = _list._tail;
648 private unowned Node<G>? _get_node_at (int index) {
649 unowned Node<G>? n = null;;
652 } else if (index == this._size - 1) {
654 } else if (index <= this._size / 2) {
656 for (int i = 0; index != i; i++) {
661 for (int i = this._size - 1; index != i; i--) {
668 private void _remove_node (Node<G> _n) {
671 if (_n == this._head) {
672 n = (owned) this._head;
673 next = this._head = (owned) n.next;
675 n = (owned) _n.prev.next;
676 next = n.prev.next = (owned) n.next;
678 if (n == this._tail) {