diff options
Diffstat (limited to 'include/EASTL/intrusive_ptr.h')
-rw-r--r-- | include/EASTL/intrusive_ptr.h | 426 |
1 files changed, 0 insertions, 426 deletions
diff --git a/include/EASTL/intrusive_ptr.h b/include/EASTL/intrusive_ptr.h deleted file mode 100644 index af4e686..0000000 --- a/include/EASTL/intrusive_ptr.h +++ /dev/null @@ -1,426 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -/////////////////////////////////////////////////////////////////////////////// - - -#ifndef EASTL_INTRUSIVE_PTR_H -#define EASTL_INTRUSIVE_PTR_H - - -#include <EASTL/internal/config.h> -#include <stddef.h> - -#if defined(EA_PRAGMA_ONCE_SUPPORTED) - #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result. -#endif - - - -namespace eastl -{ - // We provide default implementations of AddRef and Release in the eastl namespace. - // The user can override these on a per-class basis by defining their own specialized - // intrusive_ptr_add_ref and intrusive_ptr_release functions. User-defined specializations - // do not need to exist in the eastl namespace, but should preferably be in the namespace - // of the templated class T. - template <typename T> - void intrusive_ptr_add_ref(T* p) - { - p->AddRef(); - } - - template <typename T> - void intrusive_ptr_release(T* p) - { - p->Release(); - } - - - ////////////////////////////////////////////////////////////////////////////// - /// intrusive_ptr - /// - /// This is a class that acts like the C++ auto_ptr class except that instead - /// of deleting its member data when it goes out of scope, it releases its - /// member data when it goes out of scope. This class thus requires that the - /// templated data type have an AddRef and Release function (or whatever is - /// configured to be the two refcount functions). - /// - /// This class is useful for automatically releasing an object when this - /// class goes out of scope. See below for some usage. - /// You should be careful about putting instances of this class as members of - /// another class. If you do so, then the intrusive_ptr destructor will only - /// be called if the object that owns it is destructed. This creates a potential - /// chicken-and-egg situation. What if the intrusive_ptr member contains a - /// pointer to an object that has a reference on the object that owns the - /// intrusive_ptr member? The answer is that the neither object can ever be - /// destructed. The solution is to: - /// 1) Be very careful about what objects you put into member intrusive_ptr objects. - /// 2) Clear out your intrusive_ptr members in your shutdown function. - /// 3) Simply don't use intrusive_ptr objects as class members. - /// - /// Example usage: - /// intrusive_ptr<IWidget> pWidget = new Widget; - /// pWidget = new Widget; - /// pWidget->Reset(); - /// - template <typename T> - class intrusive_ptr - { - protected: - // Friend declarations. - template <typename U> friend class intrusive_ptr; - typedef intrusive_ptr<T> this_type; - - T* mpObject; - - public: - /// element_type - /// This typedef is present for consistency with the C++ standard library - /// auto_ptr template. It allows users to refer to the templated type via - /// a typedef. This is sometimes useful to be able to do. - /// - /// Example usage: - /// intrusive_ptr<IWidget> ip; - /// void DoSomething(intrusive_ptr<IWidget>::element_type someType); - /// - typedef T element_type; - - /// intrusive_ptr - /// Default constructor. The member object is set to NULL. - intrusive_ptr() - : mpObject(NULL) - { - // Empty - } - - /// intrusive_ptr - /// Provides a constructor which takes ownership of a pointer. - /// The incoming pointer is AddRefd. - /// - /// Example usage: - /// intrusive_ptr<Widget> pWidget(new Widget); - intrusive_ptr(T* p, bool bAddRef = true) - : mpObject(p) - { - if(mpObject && bAddRef) - intrusive_ptr_add_ref(mpObject); // Intentionally do not prefix the call with eastl:: but instead allow namespace lookup to resolve the namespace. - } - - /// intrusive_ptr - /// Construction from self type. - intrusive_ptr(const intrusive_ptr& ip) - : mpObject(ip.mpObject) - { - if(mpObject) - intrusive_ptr_add_ref(mpObject); - } - - - /// intrusive_ptr - /// move constructor - intrusive_ptr(intrusive_ptr&& ip) - : mpObject(nullptr) - { - swap(ip); - } - - /// intrusive_ptr - /// Provides a constructor which copies a pointer from another intrusive_ptr. - /// The incoming pointer is AddRefd. The source intrusive_ptr object maintains - /// its AddRef on the pointer. - /// - /// Example usage: - /// intrusive_ptr<Widget> pWidget1; - /// intrusive_ptr<Widget> pWidget2(pWidget1); - template <typename U> - intrusive_ptr(const intrusive_ptr<U>& ip) - : mpObject(ip.mpObject) - { - if(mpObject) - intrusive_ptr_add_ref(mpObject); - } - - /// intrusive_ptr - /// Releases the owned pointer. - ~intrusive_ptr() - { - if(mpObject) - intrusive_ptr_release(mpObject); - } - - - /// operator= - /// Assignment to self type. - intrusive_ptr& operator=(const intrusive_ptr& ip) - { - return operator=(ip.mpObject); - } - - - /// operator= - /// Move assignment operator - intrusive_ptr& operator=(intrusive_ptr&& ip) - { - swap(ip); - return *this; - } - - - /// operator = - /// Assigns an intrusive_ptr object to this intrusive_ptr object. - /// The incoming pointer is AddRefd. The source intrusive_ptr object - /// maintains its AddRef on the pointer. If there is an existing member - /// pointer, it is Released before the incoming pointer is assigned. - /// If the incoming pointer is equal to the existing pointer, no - /// action is taken. The incoming pointer is AddRefd before any - /// member pointer is Released. - template <typename U> - intrusive_ptr& operator=(const intrusive_ptr<U>& ip) - { - return operator=(ip.mpObject); - } - - /// operator= - /// Assigns an intrusive_ptr object to this intrusive_ptr object. - /// The incoming pointer is AddRefd. If there is an existing member - /// pointer, it is Released before the incoming pointer is assigned. - /// If the incoming pointer is equal to the existing pointer, no - /// action is taken. The incoming pointer is AddRefd before any - /// member pointer is Released. - intrusive_ptr& operator=(T* pObject) - { - if(pObject != mpObject) - { - T* const pTemp = mpObject; // Create temporary to prevent possible problems with re-entrancy. - if(pObject) - intrusive_ptr_add_ref(pObject); - mpObject = pObject; - if(pTemp) - intrusive_ptr_release(pTemp); - } - return *this; - } - - /// operator * - /// Returns a reference to the contained object. - T& operator *() const - { - return *mpObject; - } - - /// operator * - /// Returns a pointer to the contained object, allowing the - /// user to use this container as if it were contained pointer itself. - T* operator ->() const - { - return mpObject; - } - - /// get() - /// Returns a pointer to the contained object. - T* get() const - { - return mpObject; - } - - /// reset - /// Releases the owned object and clears our reference to it. - void reset() - { - T* const pTemp = mpObject; - mpObject = NULL; - if(pTemp) - intrusive_ptr_release(pTemp); - } - - /// swap - /// Exchanges the owned pointer beween two intrusive_ptr objects. - void swap(this_type& ip) - { - T* const pTemp = mpObject; - mpObject = ip.mpObject; - ip.mpObject = pTemp; - } - - /// attach - /// Sets an intrusive_ptr pointer without calling AddRef() on - /// the pointed object. The intrusive_ptr thus eventually only does a - /// Release() on the object. This is useful for assuming a reference - /// that someone else has handed you and making sure it is always - /// released, even if you return in the middle of a function or an - /// exception is thrown. - /// - void attach(T* pObject) - { - T* const pTemp = mpObject; - mpObject = pObject; - if(pTemp) - intrusive_ptr_release(pTemp); - } - - /// detach - /// Surrenders the reference held by an intrusive_ptr pointer -- - /// it returns the current reference and nulls the pointer. If the returned - /// pointer is non-null it must be released. This is useful in functions - /// that must return a reference while possibly being aborted by a return - /// or thrown exception: - /// - /// bool GetFoo(T** pp){ - /// intrusive_ptr<T> p(PrivateGetFoo()); - /// if(p->Method()) - /// return false; - /// *pp = p.detach(); - /// return true; - /// } - T* detach() - { - T* const pTemp = mpObject; - mpObject = NULL; - return pTemp; - } - - /// Implicit operator bool - /// Allows for using a intrusive_ptr as a boolean. - /// Example usage: - /// intrusive_ptr<Widget> ptr = new Widget; - /// if(ptr) - /// ++*ptr; - /// - /// Note that below we do not use operator bool(). The reason for this - /// is that booleans automatically convert up to short, int, float, etc. - /// The result is that this: if(intrusivePtr == 1) would yield true (bad). - typedef T* (this_type::*bool_)() const; - operator bool_() const - { - if(mpObject) - return &this_type::get; - return NULL; - } - - /// operator! - /// This returns the opposite of operator bool; it returns true if - /// the owned pointer is null. Some compilers require this and some don't. - /// intrusive_ptr<Widget> ptr = new Widget; - /// if(!ptr) - /// assert(false); - bool operator!() const - { - return (mpObject == NULL); - } - - }; // class intrusive_ptr - - - /// get_pointer - /// returns intrusive_ptr::get() via the input intrusive_ptr. - template <typename T> - inline T* get_pointer(const intrusive_ptr<T>& intrusivePtr) - { - return intrusivePtr.get(); - } - - /// swap - /// Exchanges the owned pointer beween two intrusive_ptr objects. - /// This non-member version is useful for compatibility of intrusive_ptr - /// objects with the C++ Standard Library and other libraries. - template <typename T> - inline void swap(intrusive_ptr<T>& intrusivePtr1, intrusive_ptr<T>& intrusivePtr2) - { - intrusivePtr1.swap(intrusivePtr2); - } - - - template <typename T, typename U> - bool operator==(intrusive_ptr<T> const& iPtr1, intrusive_ptr<U> const& iPtr2) - { - return (iPtr1.get() == iPtr2.get()); - } - - template <typename T, typename U> - bool operator!=(intrusive_ptr<T> const& iPtr1, intrusive_ptr<U> const& iPtr2) - { - return (iPtr1.get() != iPtr2.get()); - } - - template <typename T> - bool operator==(intrusive_ptr<T> const& iPtr1, T* p) - { - return (iPtr1.get() == p); - } - - template <typename T> - bool operator!=(intrusive_ptr<T> const& iPtr1, T* p) - { - return (iPtr1.get() != p); - } - - template <typename T> - bool operator==(T* p, intrusive_ptr<T> const& iPtr2) - { - return (p == iPtr2.get()); - } - - template <typename T> - bool operator!=(T* p, intrusive_ptr<T> const& iPtr2) - { - return (p != iPtr2.get()); - } - - template <typename T, typename U> - bool operator<(intrusive_ptr<T> const& iPtr1, intrusive_ptr<U> const& iPtr2) - { - return ((uintptr_t)iPtr1.get() < (uintptr_t)iPtr2.get()); - } - - - /// static_pointer_cast - /// Returns an intrusive_ptr<T> static-casted from a intrusive_ptr<U>. - template <class T, class U> - intrusive_ptr<T> static_pointer_cast(const intrusive_ptr<U>& intrusivePtr) - { - return static_cast<T*>(intrusivePtr.get()); - } - - - #if EASTL_RTTI_ENABLED - - /// dynamic_pointer_cast - /// Returns an intrusive_ptr<T> dynamic-casted from a intrusive_ptr<U>. - template <class T, class U> - intrusive_ptr<T> dynamic_pointer_cast(const intrusive_ptr<U>& intrusivePtr) - { - return dynamic_cast<T*>(intrusivePtr.get()); - } - - #endif - - -} // namespace eastl - - -#endif // Header include guard - - - - - - - - - - - - - - - - - - - - - - - - - |