27 #ifndef MLN_UTIL_TRACKED_PTR_HH
28 # define MLN_UTIL_TRACKED_PTR_HH
37 # include <mln/core/contract.hh>
61 operator bool()
const;
114 # ifndef MLN_INCLUDE_ONLY
116 template <
typename T>
120 mln_invariant(run_());
124 template <
typename T>
128 mln_invariant(run_());
129 return !
bool(*
this);
132 template <
typename T>
136 mln_invariant(run_());
137 mln_precondition(ptr_ != 0);
141 template <
typename T>
145 mln_invariant(run_());
146 mln_precondition(ptr_ != 0);
150 template <
typename T>
154 mln_invariant(run_());
155 mln_precondition(ptr_ != 0);
159 template <
typename T>
163 mln_invariant(run_());
164 mln_precondition(ptr_ != 0);
168 template <
typename T>
174 mln_invariant(run_());
177 template <
typename T>
179 tracked_ptr<T>::tracked_ptr(
T* ptr) :
186 holders_ =
new holders_t;
187 holders_->insert(
this);
189 mln_invariant(run_());
192 template <
typename T>
194 tracked_ptr<T>::tracked_ptr(
const tracked_ptr<T>& rhs) :
196 holders_(rhs.holders_)
198 mln_invariant(rhs.run_());
200 holders_->insert(
this);
201 mln_invariant(run_());
204 template <
typename T>
206 tracked_ptr<T>& tracked_ptr<T>::operator=(
const tracked_ptr<T>& rhs)
208 mln_invariant(run_());
209 mln_invariant(rhs.run_());
210 if (&rhs ==
this || rhs.ptr_ == ptr_)
215 holders_ = rhs.holders_;
218 holders_->insert(
this);
219 mln_invariant(run_());
223 template <
typename T>
225 tracked_ptr<T>& tracked_ptr<T>::operator=(
T* ptr)
227 mln_invariant(run_());
237 holders_ =
new holders_t;
238 holders_->insert(
this);
240 mln_invariant(run_());
244 template <
typename T>
246 tracked_ptr<T>::~tracked_ptr()
251 template <
typename T>
253 bool tracked_ptr<T>::run_()
const
255 mln_invariant((ptr_ && holders_) || (! ptr_ && ! holders_));
258 mln_invariant(holders_->size() > 0);
259 tracked_ptr<T>* this_ =
const_cast<tracked_ptr<T>*
>(
this);
260 mln_invariant(holders_->find(this_) != holders_->end());
262 typename holders_t::const_iterator i;
263 for (i = holders_->begin(); i != holders_->end(); ++i)
264 mln_invariant((*i)->ptr_ == ptr_);
268 template <
typename T>
270 void tracked_ptr<T>::clean_()
272 mln_invariant(run_());
276 if (holders_->size() == 1)
282 holders_->erase(
this);
285 mln_invariant(run_());
288 template <
typename T>
290 std::ostream& operator<<(std::ostream& ostr, const tracked_ptr<T>& tp)
292 typedef std::set<tracked_ptr<T>*> holders_t;
294 mln_invariant(tp.run_());
295 ostr <<
"tracked_ptr ../../../../doc/ " << (&tp)
296 <<
" { ptr = " << tp.ptr_
298 if (tp.holders_ == 0)
302 typename holders_t::const_iterator i;
303 for (i = tp.holders_->begin(); i != tp.holders_->end(); ++i)
311 # endif // ! MLN_INCLUDE_ONLY
318 #endif // ! MLN_UTIL_TRACKED_PTR_HH