pva2pva  1.4.1
 All Classes Functions Variables Pages
Classes | Public Types | Public Member Functions | List of all members
weak_set< T > Class Template Reference

a std::set-ish container where entries are removed when ref. counts fall to zero More...

#include <weakset.h>

Classes

struct  XIterator
 an iterator-ish object which also locks the set during iteration More...
 

Public Types

typedef T value_type
 
typedef std::tr1::shared_ptr< T > value_pointer
 
typedef std::tr1::weak_ptr< T > value_weak_pointer
 
typedef std::set< value_pointer > set_type
 
typedef std::vector
< value_pointer > 
vector_type
 
typedef epicsMutex mutex_type
 
typedef epicsGuard< epicsMutex > guard_type
 
typedef epicsGuardRelease
< epicsMutex > 
release_type
 
typedef XIterator iterator
 

Public Member Functions

 weak_set ()
 Construct a new empty set.
 
void swap (weak_set &O)
 
void clear ()
 
bool empty () const
 
size_t size () const
 
void insert (value_pointer &)
 
size_t erase (value_pointer &v)
 
set_type lock_set () const
 
vector_type lock_vector () const
 
void lock_vector (vector_type &) const
 
epicsMutex & mutex () const
 

Detailed Description

template<typename T>
class weak_set< T >

a std::set-ish container where entries are removed when ref. counts fall to zero

A container of ref. counted (by shared_ptr) entries where an entry may be present zero or one times in the set.

Meant to be used in situations where an object must hold some weak references of entries which it can iterate.

Note that the insert() method replaces the reference pass to it with a "wrapped" reference which removes from the set then releases the original ref. The reference passed in must be unique() or std::invalid_argument is thrown. While this can't be enforced, no weak_ptr to this object should exist.

A reference loop will exist if the object owning the weak_set also holds strong references to entries in this set.

Note
With the exception of swap() all methods are thread-safe
Warning
Use caution when storing types deriving from enabled_shared_from_this<> As the implict weak reference they contain will not be wrapped.
struct Owner;
struct Entry {
shared_ptr<Owner> O;
};
struct Owner {
};
shared_ptr<Entry> build(const shared_ptr<Owner>& own) {
shared_ptr<Owner> N(new Entry);
N.O = own;
own.S.insert(N); // modifies 'N'
return N;
}
void example()
{
shared_ptr<Owner> O(new Owner);
shared_ptr<Entry> E(build(O));
assert(!O.S.empty());
E.reset(); // Entry is removed from the set and free'd
assert(O.S.empty());
}

Definition at line 57 of file weakset.h.

Member Function Documentation

template<typename T>
void weak_set< T >::clear ( )
inline

Remove all (weak) entries from the set

Note
Thread safe

Definition at line 151 of file weakset.h.

151  {
152  guard_type G(_data->mutex);
153  return _data->store.clear();
154  }
template<typename T>
bool weak_set< T >::empty ( ) const
inline

Test if set is empty

Note
Thread safe
Warning
see size()

Definition at line 159 of file weakset.h.

159  {
160  guard_type G(_data->mutex);
161  return _data->store.empty();
162  }
template<typename T>
size_t weak_set< T >::erase ( value_pointer &  v)
inline

Remove any (weak) ref to this object from the set

Returns
the number of objects removed (0 or 1)

Definition at line 180 of file weakset.h.

180  {
181  guard_type G(_data->mutex);
182  return _data->store.erase(v);
183  }
template<typename T >
void weak_set< T >::insert ( value_pointer &  v)

Insert a new entry into the set The callers shared_ptr must be unique() and is (transparently) replaced with another

Definition at line 227 of file weakset.h.

228 {
229  if(!v.unique())
230  throw std::invalid_argument("Only unique() references may be inserted");
231 
232  guard_type G(_data->mutex);
233  typename store_t::const_iterator it = _data->store.find(v);
234  if(it==_data->store.end()) { // new object
235 
236  // wrapped strong ref. which removes from our map
237  value_pointer chainptr(v.get(), dtor(_data, v));
238 
239  _data->store.insert(chainptr);
240 
241  v.swap(chainptr); // we only keep the chained pointer
242  } else {
243  // already stored, no-op
244 
245  // paranoia, if already inserted then this should be a wrapped ref.
246  // but not sure how to check this so update arg. with known wrapped ref.
247  v = value_pointer(*it); // could throw bad_weak_ptr, but really never should
248  }
249 }
template<typename T >
weak_set< T >::set_type weak_set< T >::lock_set ( ) const

Return a set of strong references to all entries

Note
that this allocates a new std::set and copies all entries

Definition at line 253 of file weakset.h.

254 {
255  set_type ret;
256  guard_type G(_data->mutex);
257  for(typename store_t::const_iterator it=_data->store.begin(),
258  end=_data->store.end(); it!=end; ++it)
259  {
260  value_pointer P(it->lock());
261  if(P) ret.insert(P);
262  }
263  return ret;
264 }
template<typename T >
weak_set< T >::vector_type weak_set< T >::lock_vector ( ) const

Return a vector of strong references to all entries Useful for iteration

Note
that this allocates a new std::set and copies all entries

Definition at line 268 of file weakset.h.

269 {
270  vector_type ret;
271  lock_vector(ret);
272  return ret;
273 }
vector_type lock_vector() const
Definition: weakset.h:268
template<typename T>
epicsMutex& weak_set< T >::mutex ( ) const
inline

Access to the weak_set internal lock for use with batch operations.

Warning
Use caution when swap()ing while holding this lock!

Definition at line 199 of file weakset.h.

199  {
200  return _data->mutex;
201  }
template<typename T>
size_t weak_set< T >::size ( ) const
inline

number of entries in the set at this moment

Note
Thread safe
Warning
May be momentarily inaccurate (larger) due to dead refs. which have not yet been removed.

Definition at line 168 of file weakset.h.

168  {
169  guard_type G(_data->mutex);
170  return _data->store.size();
171  }
template<typename T>
void weak_set< T >::swap ( weak_set< T > &  O)
inline

exchange the two sets.

Warning
Not thread safe (exchanges mutexes as well)

Definition at line 145 of file weakset.h.

145  {
146  _data.swap(O._data);
147  }

The documentation for this class was generated from the following file: