1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 // from google3/util/gtl/shared_ptr.h
33 #ifndef GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
34 #define GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
36 #include <google/protobuf/stubs/atomicops.h>
38 #include <algorithm> // for swap
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
53 #if defined(UTIL_GTL_USE_STD_SHARED_PTR) && UTIL_GTL_USE_STD_SHARED_PTR
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.
59 // Migration doc: http://go/std-shared-ptr-lsc
60 using std::enable_shared_from_this;
61 using std::shared_ptr;
62 using std::static_pointer_cast;
65 #else // below, UTIL_GTL_USE_STD_SHARED_PTR not set or set to 0.
67 // For everything else there is the google3 implementation.
68 inline bool RefCountDec(volatile Atomic32 *ptr) {
69 return Barrier_AtomicIncrement(ptr, -1) != 0;
72 inline void RefCountInc(volatile Atomic32 *ptr) {
73 NoBarrier_AtomicIncrement(ptr, 1);
76 template <typename T> class shared_ptr;
77 template <typename T> class weak_ptr;
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).
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.
93 class SharedPtrControlBlock {
94 template <typename T> friend class shared_ptr;
95 template <typename T> friend class weak_ptr;
97 SharedPtrControlBlock() : refcount_(1), weak_count_(1) { }
102 // Forward declaration. The class is defined below.
103 template <typename T> class enable_shared_from_this;
105 template <typename T>
107 template <typename U> friend class weak_ptr;
109 typedef T element_type;
111 shared_ptr() : ptr_(NULL), control_block_(NULL) {}
113 explicit shared_ptr(T* 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);
121 // Copy constructor: makes this object a copy of ptr, and increments
122 // the reference count.
123 template <typename U>
124 shared_ptr(const shared_ptr<U>& ptr)
126 control_block_(NULL) {
129 // Need non-templated version to prevent the compiler-generated default
130 shared_ptr(const shared_ptr<T>& ptr)
132 control_block_(NULL) {
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>
139 shared_ptr<T>& operator=(const shared_ptr<U>& ptr) {
140 if (ptr_ != ptr.ptr_) {
141 shared_ptr<T> me(ptr); // will hold our previous state to be destroyed.
147 // Need non-templated version to prevent the compiler-generated default
148 shared_ptr<T>& operator=(const shared_ptr<T>& ptr) {
149 if (ptr_ != ptr.ptr_) {
150 shared_ptr<T> me(ptr); // will hold our previous state to be destroyed.
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?
162 // template <typename U>
163 // shared_ptr(const weak_ptr<U>& ptr);
167 if (!RefCountDec(&control_block_->refcount_)) {
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_;
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.
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>
189 shared_ptr<T> tmp(p);
195 reset(static_cast<T*>(NULL));
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.
201 void swap(shared_ptr<T>& r) {
202 using std::swap; // http://go/using-std-swap
204 swap(control_block_, r.control_block_);
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).
214 T& operator*() const {
218 T* operator->() const {
222 long use_count() const {
223 return control_block_ ? control_block_->refcount_ : 1;
226 bool unique() const {
227 return use_count() == 1;
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);
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_);
253 ptr_ = static_cast<U*>(r.ptr_);
254 control_block_ = r.control_block_;
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(...) { }
266 SharedPtrControlBlock* control_block_;
269 template <typename U>
270 friend class shared_ptr;
272 template <typename U, typename V>
273 friend shared_ptr<U> static_pointer_cast(const shared_ptr<V>& rhs);
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) {
282 template <typename T, typename U>
283 shared_ptr<T> static_pointer_cast(const shared_ptr<U>& rhs) {
285 lhs.template InitializeWithStaticCast<T>(rhs);
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>
294 template <typename U> friend class weak_ptr;
296 typedef T element_type;
298 // Create an empty (i.e. already expired) weak_ptr.
299 weak_ptr() : ptr_(NULL), control_block_(NULL) { }
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_);
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
313 template <typename U> weak_ptr(const weak_ptr<U>& ptr) {
314 CopyFrom(ptr.ptr_, ptr.control_block_);
317 // Need non-templated version to prevent default copy constructor
318 weak_ptr(const weak_ptr& ptr) {
319 CopyFrom(ptr.ptr_, ptr.control_block_);
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_;
335 weak_ptr& operator=(const weak_ptr& ptr) {
342 template <typename U> weak_ptr& operator=(const weak_ptr<U>& ptr) {
347 template <typename U> weak_ptr& operator=(const shared_ptr<U>& ptr) {
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_);
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;
370 bool expired() const { return use_count() == 0; }
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
379 shared_ptr<T> lock() const {
380 shared_ptr<T> result;
381 if (control_block_ != NULL) {
382 Atomic32 old_refcount;
384 old_refcount = control_block_->refcount_;
385 if (old_refcount == 0)
387 } while (old_refcount !=
388 NoBarrier_CompareAndSwap(
389 &control_block_->refcount_, old_refcount,
391 if (old_refcount > 0) {
393 result.control_block_ = control_block_;
401 void CopyFrom(T* ptr, SharedPtrControlBlock* control_block) {
403 control_block_ = control_block;
404 if (control_block_ != NULL)
405 RefCountInc(&control_block_->weak_count_);
410 SharedPtrControlBlock* control_block_;
413 template <typename T> void swap(weak_ptr<T>& r, weak_ptr<T>& s) {
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>
421 class enable_shared_from_this {
422 friend class shared_ptr<T>;
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.)
428 shared_ptr<T> shared_from_this() {
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();
434 shared_ptr<const T> shared_from_this() const {
435 CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
436 return weak_this_.lock();
440 enable_shared_from_this() { }
441 enable_shared_from_this(const enable_shared_from_this& other) { }
442 enable_shared_from_this& operator=(const enable_shared_from_this& other) {
445 ~enable_shared_from_this() { }
448 weak_ptr<T> weak_this_;
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
457 void shared_ptr<T>::MaybeSetupWeakThis(enable_shared_from_this<T>* ptr) {
459 CHECK(ptr->weak_this_.expired()) << "Object already owned by a shared_ptr";
460 ptr->weak_this_ = *this;
464 #endif // UTIL_GTL_USE_STD_SHARED_PTR
467 } // namespace protobuf
468 } // namespace google
470 #endif // GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__