1 /* abstractmultiset.vala
3 * Copyright (C) 2009 Ali Sabil
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Ali Sabil <ali.sabil@gmail.com>
21 * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
25 * Skeletal implementation of the {@link MultiSet} interface.
30 public abstract class Gee.AbstractMultiSet<G> : AbstractCollection<G>, MultiSet<G> {
31 public override int size {
32 get { return _nitems; }
35 public override bool read_only {
39 protected Map<G, int> _storage_map;
40 private int _nitems = 0;
43 * Constructs a new, empty abstract multi set.
45 public AbstractMultiSet (Map<G, int> storage_map) {
46 this._storage_map = storage_map;
49 public int count (G item) {
51 if (_storage_map.has_key (item)) {
52 result = _storage_map.get (item);
57 public override bool contains (G item) {
58 return _storage_map.has_key (item);
61 public override Gee.Iterator<G> iterator () {
62 return new Iterator<G> (this);
65 public override bool add (G item) {
66 if (_storage_map.has_key (item)) {
67 int current_count = _storage_map.get (item);
68 _storage_map.set (item, current_count + 1);
70 _storage_map.set (item, 1);
76 public override bool remove (G item) {
77 if (_nitems > 0 && _storage_map.has_key (item)) {
78 int current_count = _storage_map.get (item);
79 if (current_count <= 1) {
80 _storage_map.unset (item);
82 _storage_map.set (item, current_count - 1);
90 public override void clear () {
91 _storage_map.clear ();
96 internal new virtual void reserved0() {}
97 internal new virtual void reserved1() {}
98 internal new virtual void reserved2() {}
99 internal new virtual void reserved3() {}
100 internal new virtual void reserved4() {}
101 internal new virtual void reserved5() {}
102 internal new virtual void reserved6() {}
103 internal new virtual void reserved7() {}
104 internal new virtual void reserved8() {}
105 internal new virtual void reserved9() {}
107 private class Iterator<G> : Object, Traversable<G>, Gee.Iterator<G> {
108 private AbstractMultiSet<G> _set;
110 private MapIterator<G, int> _iter;
111 private int _pending = 0;
112 private bool _removed = false;
114 public Iterator (AbstractMultiSet<G> set) {
116 _iter = _set._storage_map.map_iterator ();
119 public bool next () {
123 _pending = _iter.get_value () - 1;
133 public bool has_next () {
134 return _pending > 0 || _iter.has_next ();
137 public new G get () {
139 return _iter.get_key ();
142 public void remove () {
144 _iter.set_value (_pending = _iter.get_value () - 1);
152 public bool read_only {
160 return ! _removed && _iter.valid;
164 public bool foreach (ForallFunc<G> f) {
167 if (!f(_iter.get_key())) {
171 for(int i = _pending - 1; i >= 0; --i) {
172 if (!f(_iter.get_key())) {
178 while(_iter.next()) {
179 for(int i = _iter.get_value() - 1; i >= 0; --i) {
180 if (!f(_iter.get_key())) {