IBR-DTNSuite  0.10
refcnt_ptr.h
Go to the documentation of this file.
1 /*
2  * refcnt_ptr.h
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #ifndef IBRCOMMON_refcnt_ptr_h
23 #define IBRCOMMON_refcnt_ptr_h 1
24 
25 #include "ibrcommon/thread/Mutex.h"
27 
28 template <class T> class refcnt_ptr
29 {
30  protected:
31  // a helper class that holds the pointer to the managed object
32  // and its reference count
33  class Holder
34  {
35  public:
36  Holder( T* ptr) : ptr_(ptr), count_(1) {};
37  virtual ~Holder() { delete ptr_;};
38 
39  T* ptr_;
40  unsigned count_;
42  };
43 
44  Holder* h_;
45 
46  private:
47  void down()
48  {
49  try {
51  if (--h_->count_ == 0) throw true;
52  } catch (const bool&) {
53  delete h_;
54  }
55  }
56 
57  public:
58  // ctor of refcnt_ptr (p must not be NULL)
59  explicit refcnt_ptr(T* p) : h_(new Holder(p))
60  {
61  }
62 
63  // dtor of refcnt_ptr
65  {
66  down();
67  }
68 
69  // copy and assignment of refcnt_ptr
70  refcnt_ptr (const refcnt_ptr<T>& right) : h_(right.h_)
71  {
73  ++h_->count_;
74  }
75 
77  {
78  // ignore assignment to myself
79  if (h_ == right.h_) return *this;
80 
81  ibrcommon::MutexLock l(right.h_->lock);
82  ++right.h_->count_;
83 
84  down();
85 
86  h_ = right.h_;
87 
88  return *this;
89  }
90 
91  // access to the managed object
92  T* operator-> () { return h_->ptr_; }
93  T& operator* () { return *h_->ptr_; }
94  T* getPointer() { return h_->ptr_; }
95 
96  const T* operator-> () const { return h_->ptr_; }
97  const T& operator* () const { return *h_->ptr_; }
98  const T* getPointer() const { return h_->ptr_; }
99 };
100 #endif