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:
sp()52     inline sp() : m_ptr(0) { }
53 
54     sp(T* other);  // NOLINT, implicit
55     sp(const sp<T>& other);
56     template<typename U> sp(U* other);  // NOLINT, implicit
57     template<typename U> sp(const sp<U>& other);  // NOLINT, implicit
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;  }
get()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>
sp(T * other)97 sp<T>::sp(T* other)
98     : m_ptr(other)
99 {
100     if (other) other->incStrong(this);
101 }
102 
103 template<typename T>
sp(const sp<T> & other)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>
sp(U * other)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>
sp(const sp<U> & other)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>
~sp()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>
clear()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