vbl_shared_pointer.h
Go to the documentation of this file.
1 // This is core/vbl/vbl_shared_pointer.h
2 #ifndef vbl_shared_pointer_h_
3 #define vbl_shared_pointer_h_
4 //:
5 // \file
6 // \brief Non-intrusive smart pointers
7 // \author fsm
8 //
9 // \verbatim
10 // Modifications
11 // 10 Sep. 2004 Peter Vanroose Inlined all 1-line methods in class decl
12 // 13 Feb. 2007 Amitha Perera Change implementation to allow base class conversions.
13 // \endverbatim
14 
15 #ifdef _MSC_VER
16 # include <vcl_msvc_warnings.h>
17 #endif
18 
19 #define vbl_shared_pointer_zero(var) (var) = 0
20 
21 
23 {
24  int use_count; //!< number of shared_pointers using object.
26 };
27 
28 //: Non-intrusive smart pointers
29 //
30 // If your compiler supports member templates, these pointers will
31 // also work with base classes and derived classes, so that they work
32 // very much like raw pointers. If you do this, make sure your
33 // destructors are virtual (as you'd need to do for raw pointers
34 // anyway).
35 template <class T>
37 {
38  public:
39  typedef T element_type;
40  typedef vbl_shared_pointer<T> self;
41 
43 
44  vbl_shared_pointer() : pointer(nullptr), count_data(nullptr) { }
45 
46  explicit
48  if (p) {
49  pointer = p;
50  count_data = new data_t(1);
51  } else {
52  pointer = nullptr;
53  count_data = nullptr;
54  }
55  }
56 
57  vbl_shared_pointer(self const &that)
58  : pointer( that.pointer ),
59  count_data( that.count_data )
60  {
61  up_ref();
62  }
63 
64  template<class U> friend class vbl_shared_pointer;
65 
66  //: Construct using smart pointer to derived class.
67  template <class U>
69  : pointer( that.pointer ),
70  count_data( that.count_data )
71  {
72  up_ref();
73  }
74 
75  template <class U>
76  self &operator=( vbl_shared_pointer<U> const &that) {
77  that.up_ref();
78  down_ref();
79  pointer = that.pointer;
80  count_data = that.count_data;
81  return *this;
82  }
83 
84 
85 #if 0
86  // Remove these convenience methods because they conflict with the
87  // base class conversion of the raw pointer. That is, we should be
88  // able to do
89  // vbl_shared_pointer<base> p = new derived;
90  // but these overloads prevent that.
91  // if T has a constructor T::T(3, "foo") then it's nice
92  // to be able to say
93  // vbl_shared_pointer<T> sp(3, "foo");
94  // instead of
95  // vbl_shared_pointer<T> sp = new T(3, "foo");
96  template </*typename*/ class V1>
97  explicit vbl_shared_pointer(V1 const &v1)
98  : data(new data_t(new T(v1), 1)) { }
99 
100  template <class V1, class V2>
101  explicit vbl_shared_pointer(V1 const &v1, V2 const &v2)
102  : data(new data_t(new T(v1, v2), 1)) { }
103 
104  template <class V1, class V2, class V3>
105  explicit vbl_shared_pointer(V1 const &v1, V2 const &v2, V3 const &v3)
106  : data(new data_t(new T(v1, v2, v3), 1)) { }
107 
108  template <class V1, class V2, class V3, class V4>
109  explicit vbl_shared_pointer(V1 const &v1, V2 const &v2, V3 const &v3, V4 const &v4)
110  : data(new data_t(new T(v1, v2, v3, v4), 1)) { }
111 #endif
112 
113  self &operator=(self const &that) {
114  that.up_ref();
115  down_ref();
116  pointer = that.pointer;
117  count_data = that.count_data;
118  return *this;
119  }
120 
122  down_ref();
123  }
124 
125  private:
126 
127  public:
128  // conversion to bool
129  explicit operator bool () const
130  { return (pointer != 0)? true : false; }
131 
132  // inverse conversion to bool
133  bool operator!() const
134  { return (pointer != 0)? false : true; }
135 
136  // conversion to pointer
137 #if !defined VBL_SHARED_POINTER_OF_NON_COMPOUND // Get rid of warning with vbl_shared_pointer<int>
138  T const *operator->() const { return as_pointer(); }
139  T *operator->() { return as_pointer(); }
140 #endif
141 
142  // conversion to T
143  T const &operator*() const { return *as_pointer(); }
144  T &operator*() { return *as_pointer(); }
145 
146  // relational
147  bool operator!=(self const &that) const { return pointer != that.pointer; }
148  bool operator==(self const &that) const { return pointer == that.pointer; }
149  bool operator< (self const &that) const { return pointer < that.pointer; }
150 
151  // use these if you like, but at your own risk.
152  T *as_pointer() const {
153  return pointer;
154  }
155  void up_ref() const {
156  if (count_data)
157  ++ count_data->use_count;
158  }
159  void down_ref() const {
160  if (count_data && (-- count_data->use_count == 0)) {
161  delete pointer;
162  delete count_data;
163  }
164  }
165  private:
166  T *pointer; //!< pointer to object.
168 };
169 
170 #define VBL_SHARED_POINTER_INSTANTIATE(T) // template class vbl_shared_pointer<T >
171 
172 #endif // vbl_shared_pointer_h_
self & operator=(self const &that)
T * pointer
pointer to object.
vbl_shared_pointer(vbl_shared_pointer< U > const &that)
Construct using smart pointer to derived class.
self & operator=(vbl_shared_pointer< U > const &that)
bool operator!=(self const &that) const
Non-intrusive smart pointers.
Definition: vbl_fwd.h:20
vbl_shared_pointer(self const &that)
bool operator<(self const &that) const
T const & operator *() const
int use_count
number of shared_pointers using object.
T const * operator->() const
vbl_shared_pointer_data data_t
bool operator==(self const &that) const