webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
shared_ptr.h
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // from google3/util/gtl/shared_ptr.h
32 
33 #ifndef GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
34 #define GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
35 
37 
38 #include <algorithm> // for swap
39 #include <stddef.h>
40 #include <memory>
41 
42 namespace google {
43 namespace protobuf {
44 namespace internal {
45 
46 // Alias to std::shared_ptr for any C++11 platform,
47 // and for any supported MSVC compiler.
48 #if !defined(UTIL_GTL_USE_STD_SHARED_PTR) && \
49  (defined(COMPILER_MSVC) || defined(LANG_CXX11))
50 #define UTIL_GTL_USE_STD_SHARED_PTR 1
51 #endif
52 
53 #if defined(UTIL_GTL_USE_STD_SHARED_PTR) && UTIL_GTL_USE_STD_SHARED_PTR
54 
55 // These are transitional. They will be going away soon.
56 // Please just #include <memory> and just type std::shared_ptr yourself, instead
57 // of relying on this file.
58 //
59 // Migration doc: http://go/std-shared-ptr-lsc
60 using std::enable_shared_from_this;
61 using std::shared_ptr;
63 using std::weak_ptr;
64 
65 #else // below, UTIL_GTL_USE_STD_SHARED_PTR not set or set to 0.
66 
67 // For everything else there is the google3 implementation.
68 inline bool RefCountDec(volatile Atomic32 *ptr) {
69  return Barrier_AtomicIncrement(ptr, -1) != 0;
70 }
71 
72 inline void RefCountInc(volatile Atomic32 *ptr) {
74 }
75 
76 template <typename T> class shared_ptr;
77 template <typename T> class weak_ptr;
78 
79 // This class is an internal implementation detail for shared_ptr. If two
80 // shared_ptrs point to the same object, they also share a control block.
81 // An "empty" shared_pointer refers to NULL and also has a NULL control block.
82 // It contains all of the state that's needed for reference counting or any
83 // other kind of resource management. In this implementation the control block
84 // happens to consist of two atomic words, the reference count (the number
85 // of shared_ptrs that share ownership of the object) and the weak count
86 // (the number of weak_ptrs that observe the object, plus 1 if the
87 // refcount is nonzero).
88 //
89 // The "plus 1" is to prevent a race condition in the shared_ptr and
90 // weak_ptr destructors. We need to make sure the control block is
91 // only deleted once, so we need to make sure that at most one
92 // object sees the weak count decremented from 1 to 0.
94  template <typename T> friend class shared_ptr;
95  template <typename T> friend class weak_ptr;
96  private:
97  SharedPtrControlBlock() : refcount_(1), weak_count_(1) { }
98  Atomic32 refcount_;
99  Atomic32 weak_count_;
100 };
101 
102 // Forward declaration. The class is defined below.
103 template <typename T> class enable_shared_from_this;
104 
105 template <typename T>
106 class shared_ptr {
107  template <typename U> friend class weak_ptr;
108  public:
109  typedef T element_type;
110 
111  shared_ptr() : ptr_(NULL), control_block_(NULL) {}
112 
113  explicit shared_ptr(T* ptr)
114  : ptr_(ptr),
115  control_block_(ptr != NULL ? new SharedPtrControlBlock : NULL) {
116  // If p is non-null and T inherits from enable_shared_from_this, we
117  // set up the data that shared_from_this needs.
118  MaybeSetupWeakThis(ptr);
119  }
120 
121  // Copy constructor: makes this object a copy of ptr, and increments
122  // the reference count.
123  template <typename U>
125  : ptr_(NULL),
126  control_block_(NULL) {
127  Initialize(ptr);
128  }
129  // Need non-templated version to prevent the compiler-generated default
131  : ptr_(NULL),
132  control_block_(NULL) {
133  Initialize(ptr);
134  }
135 
136  // Assignment operator. Replaces the existing shared_ptr with ptr.
137  // Increment ptr's reference count and decrement the one being replaced.
138  template <typename U>
140  if (ptr_ != ptr.ptr_) {
141  shared_ptr<T> me(ptr); // will hold our previous state to be destroyed.
142  swap(me);
143  }
144  return *this;
145  }
146 
147  // Need non-templated version to prevent the compiler-generated default
149  if (ptr_ != ptr.ptr_) {
150  shared_ptr<T> me(ptr); // will hold our previous state to be destroyed.
151  swap(me);
152  }
153  return *this;
154  }
155 
156  // TODO(austern): Consider providing this constructor. The draft C++ standard
157  // (20.8.10.2.1) includes it. However, it says that this constructor throws
158  // a bad_weak_ptr exception when ptr is expired. Is it better to provide this
159  // constructor and make it do something else, like fail with a CHECK, or to
160  // leave this constructor out entirely?
161  //
162  // template <typename U>
163  // shared_ptr(const weak_ptr<U>& ptr);
164 
166  if (ptr_ != NULL) {
167  if (!RefCountDec(&control_block_->refcount_)) {
168  delete ptr_;
169 
170  // weak_count_ is defined as the number of weak_ptrs that observe
171  // ptr_, plus 1 if refcount_ is nonzero.
172  if (!RefCountDec(&control_block_->weak_count_)) {
173  delete control_block_;
174  }
175  }
176  }
177  }
178 
179  // Replaces underlying raw pointer with the one passed in. The reference
180  // count is set to one (or zero if the pointer is NULL) for the pointer
181  // being passed in and decremented for the one being replaced.
182  //
183  // If you have a compilation error with this code, make sure you aren't
184  // passing NULL, nullptr, or 0 to this function. Call reset without an
185  // argument to reset to a null ptr.
186  template <typename Y>
187  void reset(Y* p) {
188  if (p != ptr_) {
189  shared_ptr<T> tmp(p);
190  tmp.swap(*this);
191  }
192  }
193 
194  void reset() {
195  reset(static_cast<T*>(NULL));
196  }
197 
198  // Exchanges the contents of this with the contents of r. This function
199  // supports more efficient swapping since it eliminates the need for a
200  // temporary shared_ptr object.
202  using std::swap; // http://go/using-std-swap
203  swap(ptr_, r.ptr_);
204  swap(control_block_, r.control_block_);
205  }
206 
207  // The following function is useful for gaining access to the underlying
208  // pointer when a shared_ptr remains in scope so the reference-count is
209  // known to be > 0 (e.g. for parameter passing).
210  T* get() const {
211  return ptr_;
212  }
213 
214  T& operator*() const {
215  return *ptr_;
216  }
217 
218  T* operator->() const {
219  return ptr_;
220  }
221 
222  long use_count() const {
223  return control_block_ ? control_block_->refcount_ : 1;
224  }
225 
226  bool unique() const {
227  return use_count() == 1;
228  }
229 
230  private:
231  // If r is non-empty, initialize *this to share ownership with r,
232  // increasing the underlying reference count.
233  // If r is empty, *this remains empty.
234  // Requires: this is empty, namely this->ptr_ == NULL.
235  template <typename U>
236  void Initialize(const shared_ptr<U>& r) {
237  // This performs a static_cast on r.ptr_ to U*, which is a no-op since it
238  // is already a U*. So initialization here requires that r.ptr_ is
239  // implicitly convertible to T*.
240  InitializeWithStaticCast<U>(r);
241  }
242 
243  // Initializes *this as described in Initialize, but additionally performs a
244  // static_cast from r.ptr_ (V*) to U*.
245  // NOTE(gfc): We'd need a more general form to support const_pointer_cast and
246  // dynamic_pointer_cast, but those operations are sufficiently discouraged
247  // that supporting static_pointer_cast is sufficient.
248  template <typename U, typename V>
249  void InitializeWithStaticCast(const shared_ptr<V>& r) {
250  if (r.control_block_ != NULL) {
251  RefCountInc(&r.control_block_->refcount_);
252 
253  ptr_ = static_cast<U*>(r.ptr_);
254  control_block_ = r.control_block_;
255  }
256  }
257 
258  // Helper function for the constructor that takes a raw pointer. If T
259  // doesn't inherit from enable_shared_from_this<T> then we have nothing to
260  // do, so this function is trivial and inline. The other version is declared
261  // out of line, after the class definition of enable_shared_from_this.
262  void MaybeSetupWeakThis(enable_shared_from_this<T>* ptr);
263  void MaybeSetupWeakThis(...) { }
264 
265  T* ptr_;
266  SharedPtrControlBlock* control_block_;
267 
268 #ifndef SWIG
269  template <typename U>
270  friend class shared_ptr;
271 
272  template <typename U, typename V>
274 #endif
275 };
276 
277 // Matches the interface of std::swap as an aid to generic programming.
278 template <typename T> void swap(shared_ptr<T>& r, shared_ptr<T>& s) {
279  r.swap(s);
280 }
281 
282 template <typename T, typename U>
284  shared_ptr<T> lhs;
285  lhs.template InitializeWithStaticCast<T>(rhs);
286  return lhs;
287 }
288 
289 // See comments at the top of the file for a description of why this
290 // class exists, and the draft C++ standard (as of July 2009 the
291 // latest draft is N2914) for the detailed specification.
292 template <typename T>
293 class weak_ptr {
294  template <typename U> friend class weak_ptr;
295  public:
296  typedef T element_type;
297 
298  // Create an empty (i.e. already expired) weak_ptr.
299  weak_ptr() : ptr_(NULL), control_block_(NULL) { }
300 
301  // Create a weak_ptr that observes the same object that ptr points
302  // to. Note that there is no race condition here: we know that the
303  // control block can't disappear while we're looking at it because
304  // it is owned by at least one shared_ptr, ptr.
305  template <typename U> weak_ptr(const shared_ptr<U>& ptr) {
306  CopyFrom(ptr.ptr_, ptr.control_block_);
307  }
308 
309  // Copy a weak_ptr. The object it points to might disappear, but we
310  // don't care: we're only working with the control block, and it can't
311  // disappear while we're looking at because it's owned by at least one
312  // weak_ptr, ptr.
313  template <typename U> weak_ptr(const weak_ptr<U>& ptr) {
314  CopyFrom(ptr.ptr_, ptr.control_block_);
315  }
316 
317  // Need non-templated version to prevent default copy constructor
318  weak_ptr(const weak_ptr& ptr) {
319  CopyFrom(ptr.ptr_, ptr.control_block_);
320  }
321 
322  // Destroy the weak_ptr. If no shared_ptr owns the control block, and if
323  // we are the last weak_ptr to own it, then it can be deleted. Note that
324  // weak_count_ is defined as the number of weak_ptrs sharing this control
325  // block, plus 1 if there are any shared_ptrs. We therefore know that it's
326  // safe to delete the control block when weak_count_ reaches 0, without
327  // having to perform any additional tests.
329  if (control_block_ != NULL &&
330  !RefCountDec(&control_block_->weak_count_)) {
331  delete control_block_;
332  }
333  }
334 
335  weak_ptr& operator=(const weak_ptr& ptr) {
336  if (&ptr != this) {
337  weak_ptr tmp(ptr);
338  tmp.swap(*this);
339  }
340  return *this;
341  }
342  template <typename U> weak_ptr& operator=(const weak_ptr<U>& ptr) {
343  weak_ptr tmp(ptr);
344  tmp.swap(*this);
345  return *this;
346  }
347  template <typename U> weak_ptr& operator=(const shared_ptr<U>& ptr) {
348  weak_ptr tmp(ptr);
349  tmp.swap(*this);
350  return *this;
351  }
352 
353  void swap(weak_ptr& ptr) {
354  using std::swap; // http://go/using-std-swap
355  swap(ptr_, ptr.ptr_);
356  swap(control_block_, ptr.control_block_);
357  }
358 
359  void reset() {
360  weak_ptr tmp;
361  tmp.swap(*this);
362  }
363 
364  // Return the number of shared_ptrs that own the object we are observing.
365  // Note that this number can be 0 (if this pointer has expired).
366  long use_count() const {
367  return control_block_ != NULL ? control_block_->refcount_ : 0;
368  }
369 
370  bool expired() const { return use_count() == 0; }
371 
372  // Return a shared_ptr that owns the object we are observing. If we
373  // have expired, the shared_ptr will be empty. We have to be careful
374  // about concurrency, though, since some other thread might be
375  // destroying the last owning shared_ptr while we're in this
376  // function. We want to increment the refcount only if it's nonzero
377  // and get the new value, and we want that whole operation to be
378  // atomic.
379  shared_ptr<T> lock() const {
381  if (control_block_ != NULL) {
382  Atomic32 old_refcount;
383  do {
384  old_refcount = control_block_->refcount_;
385  if (old_refcount == 0)
386  break;
387  } while (old_refcount !=
389  &control_block_->refcount_, old_refcount,
390  old_refcount + 1));
391  if (old_refcount > 0) {
392  result.ptr_ = ptr_;
393  result.control_block_ = control_block_;
394  }
395  }
396 
397  return result;
398  }
399 
400  private:
401  void CopyFrom(T* ptr, SharedPtrControlBlock* control_block) {
402  ptr_ = ptr;
403  control_block_ = control_block;
404  if (control_block_ != NULL)
405  RefCountInc(&control_block_->weak_count_);
406  }
407 
408  private:
409  element_type* ptr_;
410  SharedPtrControlBlock* control_block_;
411 };
412 
413 template <typename T> void swap(weak_ptr<T>& r, weak_ptr<T>& s) {
414  r.swap(s);
415 }
416 
417 // See comments at the top of the file for a description of why this class
418 // exists, and section 20.8.10.5 of the draft C++ standard (as of July 2009
419 // the latest draft is N2914) for the detailed specification.
420 template <typename T>
422  friend class shared_ptr<T>;
423  public:
424  // Precondition: there must be a shared_ptr that owns *this and that was
425  // created, directly or indirectly, from a raw pointer of type T*. (The
426  // latter part of the condition is technical but not quite redundant; it
427  // rules out some complicated uses involving inheritance hierarchies.)
429  // Behavior is undefined if the precondition isn't satisfied; we choose
430  // to die with a CHECK failure.
431  CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
432  return weak_this_.lock();
433  }
435  CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
436  return weak_this_.lock();
437  }
438 
439  protected:
443  return *this;
444  }
446 
447  private:
448  weak_ptr<T> weak_this_;
449 };
450 
451 // This is a helper function called by shared_ptr's constructor from a raw
452 // pointer. If T inherits from enable_shared_from_this<T>, it sets up
453 // weak_this_ so that shared_from_this works correctly. If T does not inherit
454 // from weak_this we get a different overload, defined inline, which does
455 // nothing.
456 template<typename T>
458  if (ptr) {
459  CHECK(ptr->weak_this_.expired()) << "Object already owned by a shared_ptr";
460  ptr->weak_this_ = *this;
461  }
462 }
463 
464 #endif // UTIL_GTL_USE_STD_SHARED_PTR
465 
466 } // internal
467 } // namespace protobuf
468 } // namespace google
469 
470 #endif // GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
weak_ptr(const weak_ptr< U > &ptr)
Definition: shared_ptr.h:313
weak_ptr(const shared_ptr< U > &ptr)
Definition: shared_ptr.h:305
void RefCountInc(volatile Atomic32 *ptr)
Definition: shared_ptr.h:72
shared_ptr< T > shared_from_this()
Definition: shared_ptr.h:428
DOMString p
Definition: WebCryptoAPI.idl:116
long use_count() const
Definition: shared_ptr.h:222
shared_ptr< T > & operator=(const shared_ptr< T > &ptr)
Definition: shared_ptr.h:148
weak_ptr(const weak_ptr &ptr)
Definition: shared_ptr.h:318
shared_ptr< T > & operator=(const shared_ptr< U > &ptr)
Definition: shared_ptr.h:139
void reset()
Definition: shared_ptr.h:359
shared_ptr(const shared_ptr< U > &ptr)
Definition: shared_ptr.h:124
shared_ptr< T > lock() const
Definition: shared_ptr.h:379
double U(int64_t x, double alpha)
Definition: metric_recorder.cc:414
enable_shared_from_this & operator=(const enable_shared_from_this &other)
Definition: shared_ptr.h:442
Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr, Atomic32 old_value, Atomic32 new_value)
Definition: atomicops_internals_arm64_gcc.h:52
shared_ptr< T > static_pointer_cast(const shared_ptr< U > &rhs)
Definition: shared_ptr.h:283
bool expired() const
Definition: shared_ptr.h:370
shared_ptr(T *ptr)
Definition: shared_ptr.h:113
void swap(weak_ptr &ptr)
Definition: shared_ptr.h:353
void swap(shared_ptr< T > &r)
Definition: shared_ptr.h:201
TestSubObjConstructor T
Definition: TestTypedefs.idl:84
enable_shared_from_this()
Definition: shared_ptr.h:440
void swap(shared_ptr< T > &r, shared_ptr< T > &s)
Definition: shared_ptr.h:278
~shared_ptr()
Definition: shared_ptr.h:165
~weak_ptr()
Definition: shared_ptr.h:328
T & operator*() const
Definition: shared_ptr.h:214
void reset(Y *p)
Definition: shared_ptr.h:187
void reset()
Definition: shared_ptr.h:194
shared_ptr(const shared_ptr< T > &ptr)
Definition: shared_ptr.h:130
Definition: __init__.py:1
T * operator->() const
Definition: shared_ptr.h:218
weak_ptr & operator=(const weak_ptr< U > &ptr)
Definition: shared_ptr.h:342
shared_ptr< const T > shared_from_this() const
Definition: shared_ptr.h:434
~enable_shared_from_this()
Definition: shared_ptr.h:445
shared_ptr()
Definition: shared_ptr.h:111
Definition: document.h:393
result
Definition: target-blank-opener-post-window.php:5
Definition: shared_ptr.h:76
weak_ptr & operator=(const shared_ptr< U > &ptr)
Definition: shared_ptr.h:347
T element_type
Definition: shared_ptr.h:296
#define CHECK(x)
Definition: dynbench.cpp:46
bool RefCountDec(volatile Atomic32 *ptr)
Definition: shared_ptr.h:68
struct A s
long use_count() const
Definition: shared_ptr.h:366
bool unique() const
Definition: shared_ptr.h:226
#define NULL
Definition: common_types.h:41
Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr, Atomic32 increment)
Definition: atomicops_internals_arm64_gcc.h:118
Definition: gflags_completions.h:115
new
Definition: env.py:34
ANGLE_EXPORT EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
Definition: entry_points_egl.cpp:48
Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr, Atomic32 increment)
Definition: atomicops_internals_arm64_gcc.h:97
int32 Atomic32
Definition: atomicops.h:75
weak_ptr & operator=(const weak_ptr &ptr)
Definition: shared_ptr.h:335
enable_shared_from_this(const enable_shared_from_this &other)
Definition: shared_ptr.h:441
weak_ptr()
Definition: shared_ptr.h:299
void swap(optional< T > &x, optional< T > &y) __NOEXCEPT_(__NOEXCEPT_(x.swap(y)))
Definition: Optional.h:1047
T element_type
Definition: shared_ptr.h:109
const AtomicString & reset()
Definition: InputTypeNames.cpp:124
GLboolean r
Definition: gl2ext.h:306
Definition: shared_ptr.h:77