diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-07-08 19:17:12 +0300 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-08 19:17:12 +0300 | 
| commit | 94a66b558401c77953c990a992a91c7b32493f82 (patch) | |
| tree | c5b2ec7ed2839ba3538232b3630b7c354bec2267 /indra/llcommon | |
| parent | 22782a0c68e0d310f65c80cca47daec9b7b23f2b (diff) | |
| parent | 38fdee7673a2067733d69244de54312c3ae200db (diff) | |
Merge pull request #1941 from RyeMutt/llpointer-move
Introduce move assignment and construction to LLPointer
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/llpointer.h | 111 | 
1 files changed, 94 insertions, 17 deletions
| diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h index f5916f9d58..6edff9fa5e 100644 --- a/indra/llcommon/llpointer.h +++ b/indra/llcommon/llpointer.h @@ -46,8 +46,11 @@  template <class Type> class LLPointer  {  public: +    template<typename Subclass> +    friend class LLPointer; +      LLPointer() : -        mPointer(NULL) +        mPointer(nullptr)      {      } @@ -63,6 +66,12 @@ public:          ref();      } +    LLPointer(LLPointer<Type>&& ptr) noexcept +    { +        mPointer = ptr.mPointer; +        ptr.mPointer = nullptr; +    } +      // Support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.      template<typename Subclass>      LLPointer(const LLPointer<Subclass>& ptr) : @@ -71,6 +80,13 @@ public:          ref();      } +    template<typename Subclass> +    LLPointer(LLPointer<Subclass>&& ptr) noexcept : +        mPointer(ptr.get()) +    { +        ptr.mPointer = nullptr; +    } +      ~LLPointer()      {          unref(); @@ -82,11 +98,11 @@ public:      const Type& operator*() const               { return *mPointer; }      Type&   operator*()                         { return *mPointer; } -    operator BOOL() const                       { return (mPointer != NULL); } -    operator bool() const                       { return (mPointer != NULL); } -    bool operator!() const                      { return (mPointer == NULL); } -    bool isNull() const                         { return (mPointer == NULL); } -    bool notNull() const                        { return (mPointer != NULL); } +    operator BOOL() const                       { return (mPointer != nullptr); } +    operator bool() const                       { return (mPointer != nullptr); } +    bool operator!() const                      { return (mPointer == nullptr); } +    bool isNull() const                         { return (mPointer == nullptr); } +    bool notNull() const                        { return (mPointer != nullptr); }      operator Type*() const                      { return mPointer; }      bool operator !=(Type* ptr) const           { return (mPointer != ptr); } @@ -107,6 +123,17 @@ public:          return *this;      } +    LLPointer<Type>& operator =(LLPointer<Type>&& ptr) +    { +        if (mPointer != ptr.mPointer) +        { +            unref(); +            mPointer = ptr.mPointer; +            ptr.mPointer = nullptr; +        } +        return *this; +    } +      // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.      template<typename Subclass>      LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr) @@ -115,6 +142,18 @@ public:          return *this;      } +    template<typename Subclass> +    LLPointer<Type>& operator =(LLPointer<Subclass>&& ptr) +    { +        if (mPointer != ptr.mPointer) +        { +            unref(); +            mPointer = ptr.mPointer; +            ptr.mPointer = nullptr; +        } +        return *this; +    } +      // Just exchange the pointers, which will not change the reference counts.      static void swap(LLPointer<Type>& a, LLPointer<Type>& b)      { @@ -141,9 +180,9 @@ protected:          if (mPointer)          {              Type *temp = mPointer; -            mPointer = NULL; +            mPointer = nullptr;              temp->unref(); -            if (mPointer != NULL) +            if (mPointer != nullptr)              {                  LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;                  unref(); @@ -168,9 +207,11 @@ protected:  template <class Type> class LLConstPointer  { +    template<typename Subclass> +    friend class LLConstPointer;  public:      LLConstPointer() : -        mPointer(NULL) +        mPointer(nullptr)      {      } @@ -186,6 +227,12 @@ public:          ref();      } +    LLConstPointer(LLConstPointer<Type>&& ptr) noexcept +    { +        mPointer = ptr.mPointer; +        ptr.mPointer = nullptr; +    } +      // support conversion up the type hierarchy.  See Item 45 in Effective C++, 3rd Ed.      template<typename Subclass>      LLConstPointer(const LLConstPointer<Subclass>& ptr) : @@ -194,6 +241,13 @@ public:          ref();      } +    template<typename Subclass> +    LLConstPointer(LLConstPointer<Subclass>&& ptr) noexcept : +        mPointer(ptr.get()) +    { +        ptr.mPointer = nullptr; +    } +      ~LLConstPointer()      {          unref(); @@ -203,11 +257,11 @@ public:      const Type* operator->() const              { return mPointer; }      const Type& operator*() const               { return *mPointer; } -    operator BOOL() const                       { return (mPointer != NULL); } -    operator bool() const                       { return (mPointer != NULL); } -    bool operator!() const                      { return (mPointer == NULL); } -    bool isNull() const                         { return (mPointer == NULL); } -    bool notNull() const                        { return (mPointer != NULL); } +    operator BOOL() const                       { return (mPointer != nullptr); } +    operator bool() const                       { return (mPointer != nullptr); } +    bool operator!() const                      { return (mPointer == nullptr); } +    bool isNull() const                         { return (mPointer == nullptr); } +    bool notNull() const                        { return (mPointer != nullptr); }      operator const Type*() const                { return mPointer; }      bool operator !=(const Type* ptr) const     { return (mPointer != ptr); } @@ -239,6 +293,17 @@ public:          return *this;      } +    LLConstPointer<Type>& operator =(LLConstPointer<Type>&& ptr) +    { +        if (mPointer != ptr.mPointer) +        { +            unref(); +            mPointer = ptr.mPointer; +            ptr.mPointer = nullptr; +        } +        return *this; +    } +      // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.      template<typename Subclass>      LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr) @@ -252,6 +317,18 @@ public:          return *this;      } +    template<typename Subclass> +    LLConstPointer<Type>& operator =(LLConstPointer<Subclass>&& ptr) +    { +        if (mPointer != ptr.mPointer) +        { +            unref(); +            mPointer = ptr.mPointer; +            ptr.mPointer = nullptr; +        } +        return *this; +    } +      // Just exchange the pointers, which will not change the reference counts.      static void swap(LLConstPointer<Type>& a, LLConstPointer<Type>& b)      { @@ -278,9 +355,9 @@ protected:          if (mPointer)          {              const Type *temp = mPointer; -            mPointer = NULL; +            mPointer = nullptr;              temp->unref(); -            if (mPointer != NULL) +            if (mPointer != nullptr)              {                  LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;                  unref(); @@ -313,7 +390,7 @@ public:      :   LLPointer<Type>(ptr),          mStayUnique(false)      { -        if (ptr.mForceUnique) +        if (ptr.mStayUnique)          {              makeUnique();          } | 
