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