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// ---------------------------------------------------------------------------
27namespace android {
28namespace RSC {
29
30class TextOutput;
31TextOutput& printStrongPointer(TextOutput& to, const void* val);
32
33template<typename T> class wp;
34
35// ---------------------------------------------------------------------------
36
37#define COMPARE(_op_)                                           \
38inline bool operator _op_ (const sp<T>& o) const {              \
39    return m_ptr _op_ o.m_ptr;                                  \
40}                                                               \
41inline bool operator _op_ (const T* o) const {                  \
42    return m_ptr _op_ o;                                        \
43}                                                               \
44template<typename U>                                            \
45inline bool operator _op_ (const sp<U>& o) const {              \
46    return m_ptr _op_ o.m_ptr;                                  \
47}                                                               \
48template<typename U>                                            \
49inline bool operator _op_ (const U* o) const {                  \
50    return m_ptr _op_ o;                                        \
51}                                                               \
52inline bool operator _op_ (const wp<T>& o) const {              \
53    return m_ptr _op_ o.m_ptr;                                  \
54}                                                               \
55template<typename U>                                            \
56inline bool operator _op_ (const wp<U>& o) const {              \
57    return m_ptr _op_ o.m_ptr;                                  \
58}
59
60// ---------------------------------------------------------------------------
61
62template <typename T>
63class sp
64{
65public:
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
105private:
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
114template <typename T>
115TextOutput& operator<<(TextOutput& to, const sp<T>& val);
116
117// ---------------------------------------------------------------------------
118// No user serviceable parts below here.
119
120template<typename T>
121sp<T>::sp(T* other)
122: m_ptr(other)
123  {
124    if (other) other->incStrong(this);
125  }
126
127template<typename T>
128sp<T>::sp(const sp<T>& other)
129: m_ptr(other.m_ptr)
130  {
131    if (m_ptr) m_ptr->incStrong(this);
132  }
133
134template<typename T> template<typename U>
135sp<T>::sp(U* other) : m_ptr(other)
136{
137    if (other) ((T*)other)->incStrong(this);
138}
139
140template<typename T> template<typename U>
141sp<T>::sp(const sp<U>& other)
142: m_ptr(other.m_ptr)
143  {
144    if (m_ptr) m_ptr->incStrong(this);
145  }
146
147template<typename T>
148sp<T>::~sp()
149{
150    if (m_ptr) m_ptr->decStrong(this);
151}
152
153template<typename T>
154sp<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
162template<typename T>
163sp<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
171template<typename T> template<typename U>
172sp<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
181template<typename T> template<typename U>
182sp<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
190template<typename T>
191void sp<T>::force_set(T* other)
192{
193    other->forceIncStrong(this);
194    m_ptr = other;
195}
196
197template<typename T>
198void sp<T>::clear()
199{
200    if (m_ptr) {
201        m_ptr->decStrong(this);
202        m_ptr = 0;
203    }
204}
205
206template<typename T>
207void sp<T>::set_pointer(T* ptr) {
208    m_ptr = ptr;
209}
210
211template <typename T>
212inline 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