FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fei_SharedPtr.hpp
1 /*--------------------------------------------------------------------*/
2 /* Copyright 2005 Sandia Corporation. */
3 /* Under the terms of Contract DE-AC04-94AL85000, there is a */
4 /* non-exclusive license for use of this work by or on behalf */
5 /* of the U.S. Government. Export of this program may require */
6 /* a license from the United States Government. */
7 /*--------------------------------------------------------------------*/
8 
9 #ifndef _fei_SharedPtr_hpp_
10 #define _fei_SharedPtr_hpp_
11 
12 #include <fei_macros.hpp>
13 //
14 //fei::SharedPtr is a copy of the Sierra system's SharedPtr class, which
15 //was added by Kevin Copps. This class is a close copy of the boost shared_ptr.
16 //
17 //NOTE: In this copy, I've removed the member function 'swap', and the
18 //std::less specialization.
19 //
20 //boost::shared_ptr now allows a second template parameter which specifies
21 //a deleter object. Instead of adopting that, I'm taking a lazy approach and
22 //simply adding a default bool argument to a constructor which specifies
23 //whether the SharedPtr should delete the pointer or not.
24 //
25 
26 // #ifdef SIERRA_NO_MEMBER_TEMPLATES
27 // #define FEI_NO_MEMBER_TEMPLATES
28 // #endif
29 
30 namespace fei {
31 
65 template<typename T> class SharedPtr {
66 
67  public:
68 
72  typedef T element_type;
73 
84  explicit SharedPtr(T* p)
85  : pointer(p)
86  {
87  try { // prevent leak if new throws
88  count = new long(1);
89  } catch (...) {
90  delete p;
91  throw;
92  }
93  }
94 
95  SharedPtr(void)
96  : pointer(0) {
97  count = new long(1);
98  }
99 
100 
109  ~SharedPtr() { dispose(); }
110 
111 #if !defined( FEI_NO_MEMBER_TEMPLATES )
112 
121  template<typename Y>
122  SharedPtr(const SharedPtr<Y>& x)
123  : pointer(x.pointer)
124  {
125  ++*(count = x.count);
126  }
127 
144  template<typename Y>
145  SharedPtr& operator=(const SharedPtr<Y>& x) {
146  share(x.pointer,x.count);
147  return *this;
148  }
149 #endif // FEI_NO_MEMBER_TEMPLATES
150 
160  SharedPtr(const SharedPtr& x)
161  : pointer(x.pointer)
162  {
163  ++*(count = x.count);
164  }
165 
181  SharedPtr& operator=(const SharedPtr& x) {
182  share(x.pointer, x.count);
183  return *this;
184  }
185 
203  void reset(T* p=0) {
204  if ( pointer == p ) return;
205  if (--*count == 0) {
206  delete pointer;
207  }
208  else { // allocate new reference counter
209  try {
210  count = new long;
211  }
212  catch (...) {
213  ++*count;
214  delete p;
215  throw;
216  }
217  }
218  *count = 1;
219  pointer = p;
220  }
221 
228  T& operator*() const { return *pointer; }
229 
235  T* operator->() const { return pointer; }
236 
242  T* get() const { return pointer; }
243 
250  long use_count() const { return *count; }
251 
258  bool unique() const { return *count == 1; }
259 
261  void share(T* xpointer, long* xcount) {
262  if (count != xcount) {
263  ++*xcount;
264  dispose();
265  pointer = xpointer;
266  count = xcount;
267  }
268  }
269 
271  void dispose() {
272  if (--*count == 0) {
273  delete pointer;
274  delete count;
275  }
276  }
277 
278  // Making all members public allows member templates
279  // to work in the absence of member template friends.
280 #if defined( FEI_NO_MEMBER_TEMPLATES ) || !defined( FEI_NO_MEMBER_TEMPLATES )
281  private:
282 #endif
283 
284  T* pointer; // contained pointer
285  long* count; // ptr to reference counter
286 
287 #if !defined( FEI_NO_MEMBER_TEMPLATES ) && !defined( FEI_NO_MEMBER_TEMPLATES )
288  template<typename Y> friend class SharedPtr;
289 #endif
290 
291 }; // end class SharedPtr
292 
296 template<typename T, typename U>
297  inline bool operator==(const SharedPtr<T>& a, const SharedPtr<U>& b)
298  { return a.get() == b.get(); }
299 
303 template<typename T, typename U>
304  inline bool operator!=(const SharedPtr<T>& a, const SharedPtr<U>& b)
305  { return a.get() != b.get(); }
306 
307 } // namespace fei
308 
309 #endif // _fei_SharedPtr_hpp_
310 
T & operator*() const
void reset(T *p=0)
long use_count() const
T * operator->() const
void share(T *xpointer, long *xcount)
bool operator==(const SharedPtr< T > &a, const SharedPtr< U > &b)
SharedPtr & operator=(const SharedPtr< Y > &x)
bool operator!=(const SharedPtr< T > &a, const SharedPtr< U > &b)
bool unique() const