/* * Copyright (C) 2005 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_STRONG_POINTER_H #define ANDROID_STRONG_POINTER_H #include #include // for common_type. // --------------------------------------------------------------------------- namespace android { template class wp; // --------------------------------------------------------------------------- template class sp { public: inline sp() : m_ptr(nullptr) { } // The old way of using sp<> was like this. This is bad because it relies // on implicit conversion to sp<>, which we would like to remove (if an // object is being managed some other way, this is double-ownership). We // want to move away from this: // // sp foo = new Foo(...); // DO NOT DO THIS // // Instead, prefer to do this: // // sp foo = sp::make(...); // DO THIS // // Sometimes, in order to use this, when a constructor is marked as private, // you may need to add this to your class: // // friend class sp; template static inline sp make(Args&&... args); // if nullptr, returns nullptr // // if a strong pointer is already available, this will retrieve it, // otherwise, this will abort static inline sp fromExisting(T* other); // for more information about this macro and correct RefBase usage, see // the comment at the top of utils/RefBase.h #if defined(ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION) sp(std::nullptr_t) : sp() {} #else sp(T* other); // NOLINT(implicit) template sp(U* other); // NOLINT(implicit) sp& operator=(T* other); template sp& operator=(U* other); #endif sp(const sp& other); sp(sp&& other) noexcept; template sp(const sp& other); // NOLINT(implicit) template sp(sp&& other); // NOLINT(implicit) // Cast a strong pointer directly from one type to another. Constructors // allow changing types, but only if they are pointer-compatible. This does // a static_cast internally. template static inline sp cast(const sp& other); ~sp(); // Assignment sp& operator = (const sp& other); sp& operator=(sp&& other) noexcept; template sp& operator = (const sp& other); template sp& operator = (sp&& other); //! Special optimization for use by ProcessState (and nobody else). void force_set(T* other); // Reset void clear(); // Accessors inline T& operator* () const { return *m_ptr; } inline T* operator-> () const { return m_ptr; } inline T* get() const { return m_ptr; } inline explicit operator bool () const { return m_ptr != nullptr; } // Punt these to the wp<> implementation. template inline bool operator == (const wp& o) const { return o == *this; } template inline bool operator != (const wp& o) const { return o != *this; } private: template friend class sp; template friend class wp; void set_pointer(T* ptr); T* m_ptr; }; #define COMPARE_STRONG(_op_) \ template \ static inline bool operator _op_(const sp& t, const sp& u) { \ return t.get() _op_ u.get(); \ } \ template \ static inline bool operator _op_(const T* t, const sp& u) { \ return t _op_ u.get(); \ } \ template \ static inline bool operator _op_(const sp& t, const U* u) { \ return t.get() _op_ u; \ } \ template \ static inline bool operator _op_(const sp& t, std::nullptr_t) { \ return t.get() _op_ nullptr; \ } \ template \ static inline bool operator _op_(std::nullptr_t, const sp& t) { \ return nullptr _op_ t.get(); \ } template