Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef RS_STRONG_POINTER_H
     18 #define RS_STRONG_POINTER_H
     19 
     20 //#include <cutils/atomic.h>
     21 
     22 #include <stdint.h>
     23 #include <sys/types.h>
     24 #include <stdlib.h>
     25 
     26 // ---------------------------------------------------------------------------
     27 namespace android {
     28 namespace RSC {
     29 
     30 class TextOutput;
     31 TextOutput& printStrongPointer(TextOutput& to, const void* val);
     32 
     33 template<typename T> class wp;
     34 
     35 // ---------------------------------------------------------------------------
     36 
     37 #define COMPARE(_op_)                                           \
     38 inline bool operator _op_ (const sp<T>& o) const {              \
     39     return m_ptr _op_ o.m_ptr;                                  \
     40 }                                                               \
     41 inline bool operator _op_ (const T* o) const {                  \
     42     return m_ptr _op_ o;                                        \
     43 }                                                               \
     44 template<typename U>                                            \
     45 inline bool operator _op_ (const sp<U>& o) const {              \
     46     return m_ptr _op_ o.m_ptr;                                  \
     47 }                                                               \
     48 template<typename U>                                            \
     49 inline bool operator _op_ (const U* o) const {                  \
     50     return m_ptr _op_ o;                                        \
     51 }                                                               \
     52 inline bool operator _op_ (const wp<T>& o) const {              \
     53     return m_ptr _op_ o.m_ptr;                                  \
     54 }                                                               \
     55 template<typename U>                                            \
     56 inline bool operator _op_ (const wp<U>& o) const {              \
     57     return m_ptr _op_ o.m_ptr;                                  \
     58 }
     59 
     60 // ---------------------------------------------------------------------------
     61 
     62 template <typename T>
     63 class sp
     64 {
     65 public:
     66     inline sp() : m_ptr(0) { }
     67 
     68     sp(T* other);  // NOLINT, implicit
     69     sp(const sp<T>& other);
     70     template<typename U> sp(U* other);  // NOLINT, implicit
     71     template<typename U> sp(const sp<U>& other);  // NOLINT, implicit
     72 
     73     ~sp();
     74 
     75     // Assignment
     76 
     77     sp& operator = (T* other);
     78     sp& operator = (const sp<T>& other);
     79 
     80     template<typename U> sp& operator = (const sp<U>& other);
     81     template<typename U> sp& operator = (U* other);
     82 
     83     //! Special optimization for use by ProcessState (and nobody else).
     84     void force_set(T* other);
     85 
     86     // Reset
     87 
     88     void clear();
     89 
     90     // Accessors
     91 
     92     inline  T&      operator* () const  { return *m_ptr; }
     93     inline  T*      operator-> () const { return m_ptr;  }
     94     inline  T*      get() const         { return m_ptr; }
     95 
     96     // Operators
     97 
     98     COMPARE(==)
     99     COMPARE(!=)
    100     COMPARE(>)
    101     COMPARE(<)
    102     COMPARE(<=)
    103     COMPARE(>=)
    104 
    105 private:
    106     template<typename Y> friend class sp;
    107     template<typename Y> friend class wp;
    108     void set_pointer(T* ptr);
    109     T* m_ptr;
    110 };
    111 
    112 #undef COMPARE
    113 
    114 template <typename T>
    115 TextOutput& operator<<(TextOutput& to, const sp<T>& val);
    116 
    117 // ---------------------------------------------------------------------------
    118 // No user serviceable parts below here.
    119 
    120 template<typename T>
    121 sp<T>::sp(T* other)
    122 : m_ptr(other)
    123   {
    124     if (other) other->incStrong(this);
    125   }
    126 
    127 template<typename T>
    128 sp<T>::sp(const sp<T>& other)
    129 : m_ptr(other.m_ptr)
    130   {
    131     if (m_ptr) m_ptr->incStrong(this);
    132   }
    133 
    134 template<typename T> template<typename U>
    135 sp<T>::sp(U* other) : m_ptr(other)
    136 {
    137     if (other) ((T*)other)->incStrong(this);
    138 }
    139 
    140 template<typename T> template<typename U>
    141 sp<T>::sp(const sp<U>& other)
    142 : m_ptr(other.m_ptr)
    143   {
    144     if (m_ptr) m_ptr->incStrong(this);
    145   }
    146 
    147 template<typename T>
    148 sp<T>::~sp()
    149 {
    150     if (m_ptr) m_ptr->decStrong(this);
    151 }
    152 
    153 template<typename T>
    154 sp<T>& sp<T>::operator = (const sp<T>& other) {
    155     T* otherPtr(other.m_ptr);
    156     if (otherPtr) otherPtr->incStrong(this);
    157     if (m_ptr) m_ptr->decStrong(this);
    158     m_ptr = otherPtr;
    159     return *this;
    160 }
    161 
    162 template<typename T>
    163 sp<T>& sp<T>::operator = (T* other)
    164 {
    165     if (other) other->incStrong(this);
    166     if (m_ptr) m_ptr->decStrong(this);
    167     m_ptr = other;
    168     return *this;
    169 }
    170 
    171 template<typename T> template<typename U>
    172 sp<T>& sp<T>::operator = (const sp<U>& other)
    173 {
    174     T* otherPtr(other.m_ptr);
    175     if (otherPtr) otherPtr->incStrong(this);
    176     if (m_ptr) m_ptr->decStrong(this);
    177     m_ptr = otherPtr;
    178     return *this;
    179 }
    180 
    181 template<typename T> template<typename U>
    182 sp<T>& sp<T>::operator = (U* other)
    183 {
    184     if (other) ((T*)other)->incStrong(this);
    185     if (m_ptr) m_ptr->decStrong(this);
    186     m_ptr = other;
    187     return *this;
    188 }
    189 
    190 template<typename T>
    191 void sp<T>::force_set(T* other)
    192 {
    193     other->forceIncStrong(this);
    194     m_ptr = other;
    195 }
    196 
    197 template<typename T>
    198 void sp<T>::clear()
    199 {
    200     if (m_ptr) {
    201         m_ptr->decStrong(this);
    202         m_ptr = 0;
    203     }
    204 }
    205 
    206 template<typename T>
    207 void sp<T>::set_pointer(T* ptr) {
    208     m_ptr = ptr;
    209 }
    210 
    211 template <typename T>
    212 inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
    213 {
    214     return printStrongPointer(to, val.get());
    215 }
    216 
    217 }; // namespace RSC
    218 }; // namespace android
    219 
    220 // ---------------------------------------------------------------------------
    221 
    222 #endif // RS_STRONG_POINTER_H
    223