OpenDDS  Snapshot(2023/04/28-20:55)
unique_ptr.h
Go to the documentation of this file.
1 #ifndef OPENDDS_DCPS_UNIQUE_PTR_H
2 #define OPENDDS_DCPS_UNIQUE_PTR_H
3 
4 #if !defined (ACE_LACKS_PRAGMA_ONCE)
5 # pragma once
6 #endif /* ACE_LACKS_PRAGMA_ONCE */
7 
8 
10 
11 #include "ace/config-lite.h"
12 
13 #ifdef ACE_HAS_CPP11
14 # define OPENDDS_HAS_STD_UNIQUE_PTR
15 #endif
16 
17 #ifdef OPENDDS_HAS_STD_UNIQUE_PTR
18 # include <memory>
19 #else
20 # include "Atomic.h"
21 # ifdef ACE_HAS_CPP11
22 # include <utility>
23 # else
24 # include <algorithm>
25 # endif
26 #endif
27 
29 
30 namespace OpenDDS {
31 namespace DCPS {
32 
33 #ifdef OPENDDS_HAS_STD_UNIQUE_PTR
34 
35 using std::move;
36 using std::unique_ptr;
37 
38 template <typename T>
39 using container_supported_unique_ptr = std::unique_ptr<T>;
40 
41 template <typename T>
42 struct EnableContainerSupportedUniquePtr {};
43 
44 #else //HAS_STD_UNIQUE_PTR
45 
46 template <typename T>
47 class rv : public T {
48  rv();
49  ~rv();
50  rv(const rv &);
51  void operator=(const rv&);
52 };
53 
54 template <typename T>
56 {
57  void operator()(T* ptr) const
58  {
59  delete ptr;
60  }
61 };
62 
63 template <typename T, typename Deleter = default_deleter<T> >
64 class unique_ptr {
65 public:
66  typedef T element_type;
67  typedef Deleter deleter_type;
68 
69  explicit unique_ptr(T* p = 0) // never throws
70  : ptr_(p)
71  {}
72 
74 
75  unique_ptr(rv_reference other)
76  : ptr_(other.release())
77  {}
78 
79  ~unique_ptr() // never throws
80  {
81  Deleter()(ptr_);
82  }
83 
85  {
86  reset(other.release());
87  return *this;
88  }
89 
90  void reset(T* p = 0) // never throws
91  {
92  Deleter()(ptr_);
93  ptr_ = p;
94  }
95 
96  T* release()
97  {
98  T* p = ptr_;
99  ptr_ = 0;
100  return p;
101  }
102 
103  T& operator*() const // never throws
104  {
105  return *get();
106  }
107 
108  T* operator->() const // never throws
109  {
110  return get();
111  }
112 
113  T* get() const // never throws
114  {
115  return ptr_;
116  }
117 
118  operator bool() const // never throws
119  {
120  return get() != 0;
121  }
122 
123  void swap(unique_ptr& b) // never throws
124  {
125  std::swap(ptr_, b.ptr_);
126  }
127 
128  bool operator<(const unique_ptr& other) const
129  {
130  return ptr_ < other.ptr_;
131  }
132 
133 private:
134  unique_ptr(const unique_ptr&);
135  unique_ptr& operator=(const unique_ptr&);
136 
137  T* ptr_;
138 };
139 
140 template <typename T>
141 typename T::rv_reference move(T& p)
142 {
143  return static_cast<typename T::rv_reference>(p);
144 }
145 
146 
147 template <typename T, typename Deleter>
149 {
150  return a.swap(b);
151 }
152 
153 template <typename T>
155 {
156 public:
157 
159  : ptr_(0)
160  {}
161 
163  : ptr_(p)
164  {
165  }
166 
167  template <typename U>
169  : ptr_(p.release())
170  {
171  }
172 
173  template <typename U>
175  : ptr_(other.get())
176  {
177  bump_up();
178  }
179 
181  : ptr_(b.ptr_)
182  {
183  bump_up();
184  }
185 
187  {
188  bump_down();
189  }
190 
191  template <typename U>
192  void reset(U* p)
193  {
195  swap(tmp);
196  }
197 
198  void reset(T* p=0)
199  {
201  swap(tmp);
202  }
203 
205  {
207  swap(tmp);
208  return *this;
209  }
210 
211  template <class U>
213  {
215  swap(tmp);
216  return *this;
217  }
218 
219  template <typename U>
221  {
223  swap(tmp);
224  return *this;
225  }
226 
228  {
229  T* t = ptr_;
230  ptr_ = rhs.ptr_;
231  rhs.ptr_ = t;
232  }
233 
234  T* operator->() const
235  {
236  return ptr_;
237  }
238 
239  T& operator*() const
240  {
241  return *ptr_;
242  }
243 
244  T* get() const
245  {
246  return ptr_;
247  }
248 
249  T* release()
250  {
251  T* retval = ptr_;
252  ptr_ = 0;
253  return retval;
254  }
255 
256  operator bool() const
257  {
258  return get() != 0;
259  }
260 
262  {
263  return get() == rhs.get();
264  }
265 
267  {
268  return get() != rhs.get();
269  }
270 
272  {
273  return get() < rhs.get();
274  }
275 
276 private:
277 
278  void bump_up()
279  {
280  if (ptr_ != 0) {
281  ptr_->_add_ref();
282  }
283  }
284 
285  void bump_down()
286  {
287  if (ptr_ != 0) {
288  ptr_->_remove_ref();
289  ptr_ = 0;
290  }
291  }
292 
293  /// The actual "unsmart" pointer to the T object.
294  T* ptr_;
295 };
296 
297 template <typename T>
299 {
300  lhs.swap(rhs);
301 }
302 
303 template <typename T>
305 protected:
307  : ref_count_(1)
308  {
309  }
310 
311  template <typename U>
313 
314  template <typename U>
316 
317  void _add_ref() {
318  ++ref_count_;
319  }
320 
321  void _remove_ref(){
322  const long new_count = --ref_count_;
323 
324  if (new_count == 0) {
325  delete static_cast<T*>(this);
326  }
327  }
328  long ref_count() const { return ref_count_; }
329 
330 private:
332 };
333 
334 template <typename T>
336 {
337  OPENDDS_ASSERT(ptr->ref_count() == 1);
338  return reinterpret_cast<typename unique_ptr<T>::rv_reference>(ptr);
339 }
340 
341 #endif
342 } // namespace DCPS
343 } // namespace OpenDDS
344 
346 #endif /* end of include guard: UNIQUE_PTR_H_18C6F30C */
void swap(MessageBlock &lhs, MessageBlock &rhs)
unique_ptr & operator=(rv< unique_ptr > &other)
Definition: unique_ptr.h:84
void release(T x)
void swap(container_supported_unique_ptr< T > &lhs, container_supported_unique_ptr< T > &rhs)
Definition: unique_ptr.h:298
void swap(container_supported_unique_ptr &rhs)
Definition: unique_ptr.h:227
#define OPENDDS_ASSERT(C)
Definition: Definitions.h:72
container_supported_unique_ptr & operator=(const container_supported_unique_ptr< U > &b)
Definition: unique_ptr.h:212
container_supported_unique_ptr & operator=(const container_supported_unique_ptr &b)
Definition: unique_ptr.h:204
bool operator==(const container_supported_unique_ptr &rhs) const
Definition: unique_ptr.h:261
container_supported_unique_ptr(const container_supported_unique_ptr &b)
Definition: unique_ptr.h:180
unique_ptr< T >::rv_reference move(container_supported_unique_ptr< T > &ptr)
Definition: unique_ptr.h:335
bool operator!=(const container_supported_unique_ptr &rhs) const
Definition: unique_ptr.h:266
container_supported_unique_ptr(const container_supported_unique_ptr< U > &other)
Definition: unique_ptr.h:174
unique_ptr(rv_reference other)
Definition: unique_ptr.h:75
container_supported_unique_ptr & operator=(unique_ptr< U > b)
Definition: unique_ptr.h:220
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
T * ptr_
The actual "unsmart" pointer to the T object.
Definition: unique_ptr.h:294
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
friend unique_ptr< U >::rv_reference move(container_supported_unique_ptr< U > &ptr)
rv< unique_ptr > & rv_reference
Definition: unique_ptr.h:73
bool operator<(const GUID_t &lhs, const GUID_t &rhs)
Definition: GuidUtils.h:80
void swap(unique_ptr &b)
Definition: unique_ptr.h:123
void operator()(T *ptr) const
Definition: unique_ptr.h:57
bool operator<(const unique_ptr &other) const
Definition: unique_ptr.h:128