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