73efdd64a3dc02bb61fe36bf56299dfe04e013b7
[iec.git] / src / type3_AndroidCloud / anbox-master / external / android-emugl / shared / emugl / common / smart_ptr.h
1 // Copyright (C) 2014 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #ifndef EMUGL_SMART_PTR_H
15 #define EMUGL_SMART_PTR_H
16
17 #include <stddef.h>
18
19 namespace emugl {
20
21 // Hidden atomic ref-counting implementation.
22 class RefCount;
23
24 // Base class for all templated SmartPtr<> instances. Reduces
25 // template expansion and code. Consider this to be an implementation
26 // detail of SmartPtr<>, so don't rely on anything here.
27 class SmartPtrBase {
28 public:
29     // Defrault constructor.
30     SmartPtrBase() : mPtr(NULL), mRefCount(NULL) {}
31
32     // Normal constructor. This takes ownership of |ptr|, though only
33     // template instances are capable of destroying the object.
34     explicit SmartPtrBase(void* ptr);
35
36     // Copy-constructor, this increments the reference count.
37     SmartPtrBase(const SmartPtrBase& other);
38
39     // Assignment operator, also increments the reference count.
40     SmartPtrBase& operator=(const SmartPtrBase& other);
41
42     // Nothing happens in this destructor, the real work must be performed
43     // in subclasses.
44     ~SmartPtrBase() {}
45
46
47     // Used to enable 'if (smart_ptr) { ... }' properly.
48     operator void*() const {
49         return mPtr;
50     }
51
52     // Return internal reference count value, only use for unit testing.
53     int getRefCount() const;
54
55 protected:
56     // Used internally to increment the reference count.
57     void addRef();
58
59     // Copy the |other| into this instance, returns the old pointer value
60     // if it needs to be destroyed by the caller, or NULL otherwise.
61     void* copyFrom(const SmartPtrBase& other);
62
63     // Used internally to decrement the reference count, if it reaches 0,
64     // returns the pointer to be destroyed, NULL otherwise.
65     void* release();
66
67     void* mPtr;
68     RefCount* mRefCount;
69 };
70
71
72 // The real template class to be used for smart pointers.
73 // Typical uses:
74 //
75 //     SmartPtr<Foo>  ptr(new Foo());   // takes ownership.
76 //     SmartPtr<Foo>  ptr2;             // empty pointer.
77 //     ptr2 = ptr;                      // copies pointer + increment reference count.
78 //     Foo* obj = ptr.Ptr();            // access pointed object.
79 //     ptr->DoStuff();                  // operate directly on pointed object.
80 //     (*ptr)->DoStuff();               // same here.
81 //
82 // On scope exit, the internal reference count is decremented and the
83 // object is deleted automatically when it reaches 0, indicating that
84 // there are no more owners.
85 //
86 // IMPORTANT: You need to be sure that only one 'chain' of smart pointers
87 // own a given object. I.e. the following is incorrect:
88 //
89 //     Foo* foo = new Foo();      // create new instance.
90 //     SmartPtr<Foo>  ptr(foo);   // |ptr| takes ownership of |foo|.
91 //     SmartPtr<Foo>  ptr2(foo);  // |ptr2| takes also ownership of |foo|.
92 //
93 // The problem is that |ptr| and |ptr2| don't know anything about each
94 // other, and will not share the same reference count. Once a smart pointer
95 // owns an object, only use other smart pointers that are copy-constructed
96 // or assigned with the initial one to keep everything consistent.
97 template <class T>
98 class SmartPtr : public emugl::SmartPtrBase {
99 public:
100     // Default constructor. The instance holds a NULL pointer.
101     SmartPtr() : SmartPtrBase() {}
102
103     // Regular constructor, takes ownership of |ptr|.
104     explicit SmartPtr(T* ptr) : SmartPtrBase(ptr) {}
105
106     // Copy-constructor, |this| and |other| will share the same internal
107     // reference count, which is incremented by 1.
108     SmartPtr(const SmartPtr& other)
109             : SmartPtrBase(reinterpret_cast<const SmartPtrBase&>(other)) {}
110
111     // Assignment operator, same semantics as copy-constructor.
112     SmartPtr& operator=(const SmartPtr& other) {
113       void* old_ptr = copyFrom(static_cast<const SmartPtrBase&>(other));
114       if (old_ptr)
115         delete reinterpret_cast<T*>(old_ptr);
116       return *this;
117     }
118
119     // Destructor, decrements reference count and destroys the object
120     // if it reaches 0 (indicating this was the last owning smart pointer).
121     ~SmartPtr() {
122         void* ptr = release();
123         if (ptr)
124           delete reinterpret_cast<T*>(ptr);
125     }
126
127     // Return owned object instance, or NULL.
128     T* Ptr() const {
129         return reinterpret_cast<T*>(mPtr);
130     }
131
132     // Return owned object instance, or NULL
133     const T* constPtr() const {
134         return reinterpret_cast<const T*>(mPtr);
135     }
136
137     // Operate directly on owned object.
138     T* operator->() const {
139         return Ptr();
140     }
141
142     // Return reference to owned object.
143     T& operator*() const {
144         return *Ptr();
145     }
146 };
147
148 }  // namespace emugl
149
150 #endif // EMUGL_SMART_PTR_H