Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright (C) 2005 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 ANDROID_STRONG_POINTER_H
     18 #define ANDROID_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 
     29 class TextOutput;
     30 TextOutput& printStrongPointer(TextOutput& to, const void* val);
     31 
     32 template<typename T> class wp;
     33 
     34 // ---------------------------------------------------------------------------
     35 
     36 #define COMPARE(_op_)                                           \
     37 inline bool operator _op_ (const sp<T>& o) const {              \
     38     return m_ptr _op_ o.m_ptr;                                  \
     39 }                                                               \
     40 inline bool operator _op_ (const T* o) const {                  \
     41     return m_ptr _op_ o;                                        \
     42 }                                                               \
     43 template<typename U>                                            \
     44 inline bool operator _op_ (const sp<U>& o) const {              \
     45     return m_ptr _op_ o.m_ptr;                                  \
     46 }                                                               \
     47 template<typename U>                                            \
     48 inline bool operator _op_ (const U* o) const {                  \
     49     return m_ptr _op_ o;                                        \
     50 }                                                               \
     51 inline bool operator _op_ (const wp<T>& o) const {              \
     52     return m_ptr _op_ o.m_ptr;                                  \
     53 }                                                               \
     54 template<typename U>                                            \
     55 inline bool operator _op_ (const wp<U>& o) const {              \
     56     return m_ptr _op_ o.m_ptr;                                  \
     57 }
     58 
     59 // ---------------------------------------------------------------------------
     60 
     61 template <typename T>
     62 class sp
     63 {
     64 public:
     65     inline sp() : m_ptr(0) { }
     66 
     67     sp(T* other);
     68     sp(const sp<T>& other);
     69     template<typename U> sp(U* other);
     70     template<typename U> sp(const sp<U>& other);
     71 
     72     ~sp();
     73 
     74     // Assignment
     75 
     76     sp& operator = (T* other);
     77     sp& operator = (const sp<T>& other);
     78 
     79     template<typename U> sp& operator = (const sp<U>& other);
     80     template<typename U> sp& operator = (U* other);
     81 
     82     //! Special optimization for use by ProcessState (and nobody else).
     83     void force_set(T* other);
     84 
     85     // Reset
     86 
     87     void clear();
     88 
     89     // Accessors
     90 
     91     inline  T&      operator* () const  { return *m_ptr; }
     92     inline  T*      operator-> () const { return m_ptr;  }
     93     inline  T*      get() const         { return m_ptr; }
     94 
     95     // Operators
     96 
     97     COMPARE(==)
     98     COMPARE(!=)
     99     COMPARE(>)
    100     COMPARE(<)
    101     COMPARE(<=)
    102     COMPARE(>=)
    103 
    104 private:
    105     template<typename Y> friend class sp;
    106     template<typename Y> friend class wp;
    107     void set_pointer(T* ptr);
    108     T* m_ptr;
    109 };
    110 
    111 #undef COMPARE
    112 
    113 template <typename T>
    114 TextOutput& operator<<(TextOutput& to, const sp<T>& val);
    115 
    116 // ---------------------------------------------------------------------------
    117 // No user serviceable parts below here.
    118 
    119 template<typename T>
    120 sp<T>::sp(T* other)
    121 : m_ptr(other)
    122   {
    123     if (other) other->incStrong(this);
    124   }
    125 
    126 template<typename T>
    127 sp<T>::sp(const sp<T>& other)
    128 : m_ptr(other.m_ptr)
    129   {
    130     if (m_ptr) m_ptr->incStrong(this);
    131   }
    132 
    133 template<typename T> template<typename U>
    134 sp<T>::sp(U* other) : m_ptr(other)
    135 {
    136     if (other) ((T*)other)->incStrong(this);
    137 }
    138 
    139 template<typename T> template<typename U>
    140 sp<T>::sp(const sp<U>& other)
    141 : m_ptr(other.m_ptr)
    142   {
    143     if (m_ptr) m_ptr->incStrong(this);
    144   }
    145 
    146 template<typename T>
    147 sp<T>::~sp()
    148 {
    149     if (m_ptr) m_ptr->decStrong(this);
    150 }
    151 
    152 template<typename T>
    153 sp<T>& sp<T>::operator = (const sp<T>& other) {
    154     T* otherPtr(other.m_ptr);
    155     if (otherPtr) otherPtr->incStrong(this);
    156     if (m_ptr) m_ptr->decStrong(this);
    157     m_ptr = otherPtr;
    158     return *this;
    159 }
    160 
    161 template<typename T>
    162 sp<T>& sp<T>::operator = (T* other)
    163 {
    164     if (other) other->incStrong(this);
    165     if (m_ptr) m_ptr->decStrong(this);
    166     m_ptr = other;
    167     return *this;
    168 }
    169 
    170 template<typename T> template<typename U>
    171 sp<T>& sp<T>::operator = (const sp<U>& other)
    172 {
    173     T* otherPtr(other.m_ptr);
    174     if (otherPtr) otherPtr->incStrong(this);
    175     if (m_ptr) m_ptr->decStrong(this);
    176     m_ptr = otherPtr;
    177     return *this;
    178 }
    179 
    180 template<typename T> template<typename U>
    181 sp<T>& sp<T>::operator = (U* other)
    182 {
    183     if (other) ((T*)other)->incStrong(this);
    184     if (m_ptr) m_ptr->decStrong(this);
    185     m_ptr = other;
    186     return *this;
    187 }
    188 
    189 template<typename T>
    190 void sp<T>::force_set(T* other)
    191 {
    192     other->forceIncStrong(this);
    193     m_ptr = other;
    194 }
    195 
    196 template<typename T>
    197 void sp<T>::clear()
    198 {
    199     if (m_ptr) {
    200         m_ptr->decStrong(this);
    201         m_ptr = 0;
    202     }
    203 }
    204 
    205 template<typename T>
    206 void sp<T>::set_pointer(T* ptr) {
    207     m_ptr = ptr;
    208 }
    209 
    210 template <typename T>
    211 inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
    212 {
    213     return printStrongPointer(to, val.get());
    214 }
    215 
    216 }; // namespace android
    217 
    218 // ---------------------------------------------------------------------------
    219 
    220 #endif // ANDROID_STRONG_POINTER_H
    221