2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
14 #include <boost/weak_ptr.hpp>
20 #endif // WEAK_SET_DEBUG
23 * @brief An implementation of a set of weak references.
25 * weak_set is a set of weak_pointers which are automatically collected
26 * and removed when the pointed object is destroyed.
30 typedef std::list
<boost::weak_ptr
<T
> > inner_set
;
31 typedef typename
inner_set::iterator inner_iterator
;
32 friend class iterator
;
33 mutable inner_set m_set
;
36 friend class weak_set
<T
>;
37 mutable inner_iterator m_it
;
38 boost::shared_ptr
<T
> obj
; // this prevents the stored object from being collected
39 weak_set
<T
>& m_parent
;
41 iterator(const inner_iterator
& it
, weak_set
<T
>& parent
)
49 cout
<< "skipping garbage" << endl
;
51 #endif // WEAK_SET_DEBUG
53 if (m_it
== m_parent
.m_set
.end()) break;
54 boost::weak_ptr
<T
> wp
= *m_it
;
55 if (obj
= wp
.lock()) break;
57 // while (m_it != m_parent.m_set.end() && !(obj = (*m_it).lock())) {
59 cout
<< "iteration " << c
++ << endl
;
60 #endif // WEAK_SET_DEBUG
62 // the current reference is dangling:
63 // remove it from the list and get the next one
65 cout
<< "dangling reference! removing it" << endl
;
66 #endif // WEAK_SET_DEBUG
67 m_it
= m_parent
.m_set
.erase(m_it
);
69 // at this point either
70 // m_it < m_parent.m_set.end() _and_ obj is a valid shared_ptr
72 // m_it == m_parent.m_set.end()
75 cout
<< "no iteration done: uses = " << obj
.use_count() << ", obj = " << *obj
<< endl
;
77 cout
<< "we're at the end" << endl
;
78 #endif // WEAK_SET_DEBUG
82 * Check two iterators for equality.
84 bool operator==(const iterator
& other
) { return m_it
== other
.m_it
; }
87 * Equivalent to !operator==.
89 bool operator!=(const iterator
& other
) { return !operator==(other
); }
92 * Pre-increment operator. Modifity the iterator so
93 * that it points to the next valid object.
94 * @return The incremented iterator.
96 iterator
& operator++() {
98 cout
<< "incrementing" << endl
;
99 #endif // WEAK_SET_DEBUG
103 #ifdef WEAK_SET_DEBUG
104 cout
<< "done incrementing" << endl
;
105 #endif // WEAK_SET_DEBUG
110 * Post-increment operator. Modifity the iterator so
111 * that it points to the next valid object.
112 * @return The iterator before being incremented.
114 // iterator operator++(int) { return iterator(m_it++, m_parent); }
117 * @return a pointer to the stored object.
118 * @note This function is guaranteed to return a valid
119 * non-null pointer if the iterator is valid
120 * and less than the past-the-end iterator.
122 T
* get() { return obj
.get(); }
125 * @return a pointer to the stored object.
128 T
* operator->() { return get(); }
131 * @return a reference to the stored object.
134 T
& operator*() { return *get(); }
138 * Add an object to the container.
139 * @return an iterator referring to the newly inserted object.
140 * @note No iterator is invalidated by an insert operation.
142 iterator
insert(const boost::shared_ptr
<T
>& x
) {
143 return iterator(m_set
.insert(m_set
.end(), x
), *this);
147 * @return an iterator pointing to the first element of
148 * the container, which can be used for iterating.
151 return iterator(m_set
.begin(), *this);
155 * @return a past-the-end iterator.
158 return iterator(m_set
.end(), *this);