Home | History | Annotate | Download | only in tinyutils
      1 /*
      2  * Copyright 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_PIXELFLINGER_SMART_POINTER_H
     18 #define ANDROID_PIXELFLINGER_SMART_POINTER_H
     19 
     20 #include <stdint.h>
     21 #include <sys/types.h>
     22 #include <stdlib.h>
     23 
     24 // ---------------------------------------------------------------------------
     25 namespace android {
     26 namespace tinyutils {
     27 
     28 // ---------------------------------------------------------------------------
     29 
     30 #define COMPARE(_op_)                                           \
     31 inline bool operator _op_ (const sp<T>& o) const {              \
     32     return m_ptr _op_ o.m_ptr;                                  \
     33 }                                                               \
     34 inline bool operator _op_ (const T* o) const {                  \
     35     return m_ptr _op_ o;                                        \
     36 }                                                               \
     37 template<typename U>                                            \
     38 inline bool operator _op_ (const sp<U>& o) const {              \
     39     return m_ptr _op_ o.m_ptr;                                  \
     40 }                                                               \
     41 template<typename U>                                            \
     42 inline bool operator _op_ (const U* o) const {                  \
     43     return m_ptr _op_ o;                                        \
     44 }
     45 
     46 // ---------------------------------------------------------------------------
     47 
     48 template <typename T>
     49 class sp
     50 {
     51 public:
     52     inline sp() : m_ptr(0) { }
     53 
     54     sp(T* other);
     55     sp(const sp<T>& other);
     56     template<typename U> sp(U* other);
     57     template<typename U> sp(const sp<U>& other);
     58 
     59     ~sp();
     60 
     61     // Assignment
     62 
     63     sp& operator = (T* other);
     64     sp& operator = (const sp<T>& other);
     65 
     66     template<typename U> sp& operator = (const sp<U>& other);
     67     template<typename U> sp& operator = (U* other);
     68 
     69     // Reset
     70     void clear();
     71 
     72     // Accessors
     73 
     74     inline  T&      operator* () const  { return *m_ptr; }
     75     inline  T*      operator-> () const { return m_ptr;  }
     76     inline  T*      get() const         { return m_ptr; }
     77 
     78     // Operators
     79 
     80     COMPARE(==)
     81     COMPARE(!=)
     82     COMPARE(>)
     83     COMPARE(<)
     84     COMPARE(<=)
     85     COMPARE(>=)
     86 
     87 private:
     88     template<typename Y> friend class sp;
     89 
     90     T*              m_ptr;
     91 };
     92 
     93 // ---------------------------------------------------------------------------
     94 // No user serviceable parts below here.
     95 
     96 template<typename T>
     97 sp<T>::sp(T* other)
     98     : m_ptr(other)
     99 {
    100     if (other) other->incStrong(this);
    101 }
    102 
    103 template<typename T>
    104 sp<T>::sp(const sp<T>& other)
    105     : m_ptr(other.m_ptr)
    106 {
    107     if (m_ptr) m_ptr->incStrong(this);
    108 }
    109 
    110 template<typename T> template<typename U>
    111 sp<T>::sp(U* other) : m_ptr(other)
    112 {
    113     if (other) other->incStrong(this);
    114 }
    115 
    116 template<typename T> template<typename U>
    117 sp<T>::sp(const sp<U>& other)
    118     : m_ptr(other.m_ptr)
    119 {
    120     if (m_ptr) m_ptr->incStrong(this);
    121 }
    122 
    123 template<typename T>
    124 sp<T>::~sp()
    125 {
    126     if (m_ptr) m_ptr->decStrong(this);
    127 }
    128 
    129 template<typename T>
    130 sp<T>& sp<T>::operator = (const sp<T>& other) {
    131     if (other.m_ptr) other.m_ptr->incStrong(this);
    132     if (m_ptr) m_ptr->decStrong(this);
    133     m_ptr = other.m_ptr;
    134     return *this;
    135 }
    136 
    137 template<typename T>
    138 sp<T>& sp<T>::operator = (T* other)
    139 {
    140     if (other) other->incStrong(this);
    141     if (m_ptr) m_ptr->decStrong(this);
    142     m_ptr = other;
    143     return *this;
    144 }
    145 
    146 template<typename T> template<typename U>
    147 sp<T>& sp<T>::operator = (const sp<U>& other)
    148 {
    149     if (other.m_ptr) other.m_ptr->incStrong(this);
    150     if (m_ptr) m_ptr->decStrong(this);
    151     m_ptr = other.m_ptr;
    152     return *this;
    153 }
    154 
    155 template<typename T> template<typename U>
    156 sp<T>& sp<T>::operator = (U* other)
    157 {
    158     if (other) other->incStrong(this);
    159     if (m_ptr) m_ptr->decStrong(this);
    160     m_ptr = other;
    161     return *this;
    162 }
    163 
    164 template<typename T>
    165 void sp<T>::clear()
    166 {
    167     if (m_ptr) {
    168         m_ptr->decStrong(this);
    169         m_ptr = 0;
    170     }
    171 }
    172 
    173 // ---------------------------------------------------------------------------
    174 
    175 } // namespace tinyutils
    176 } // namespace android
    177 
    178 // ---------------------------------------------------------------------------
    179 
    180 #endif // ANDROID_PIXELFLINGER_SMART_POINTER_H
    181