3d4c3e7a81b02d2fa10f24b05692501613ac3e03
[platform/core/uifw/dali-core.git] / dali / internal / common / owner-pointer.h
1 #ifndef DALI_INTERNAL_OWNER_POINTER_H
2 #define DALI_INTERNAL_OWNER_POINTER_H
3
4 /*
5  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/dali-common.h>
23
24 namespace Dali
25 {
26
27 namespace Internal
28 {
29
30 template< typename T >
31 class OwnerPointer
32 {
33 public:
34
35   /**
36    * Default constructor. Creates an OwnerPointer that does not own any object.
37    * @note This does not protect against two different OwnerPointers pointing to the same object.
38    *       Both OwnerPointers will try to release the memory of the same object in that case which
39    *       could lead to a crash.
40    */
41   OwnerPointer()
42   : mObject( nullptr )
43   {
44   }
45
46   /**
47    * Constructor. Creates an OwnerPointer that owns the object.
48    * @param[in] object A pointer to a heap allocated object.
49    */
50   OwnerPointer( T* object )
51   : mObject( object )
52   {
53   }
54
55   /**
56    * Copy constructor. Passes the ownership of a pointer to another.
57    * @param[in] other The pointer that gives away the ownership.
58    */
59   OwnerPointer( const OwnerPointer& other )
60   : OwnerPointer( static_cast< OwnerPointer&& >( const_cast<OwnerPointer&>( other ) ) ) // Remove constness & cast to rvalue to use the move constructor
61   {
62     // other needs to be const for compiler to pick up this as copy constructor;
63     // though we are using this as move as there can only be one owner
64   }
65
66   /**
67    * Move constructor. Passes the ownership of a pointer to another.
68    * @param[in] other The pointer that gives away the ownership.
69    */
70   OwnerPointer( OwnerPointer&& other )
71   : mObject( nullptr )
72   {
73     Swap( other );
74   }
75
76   /**
77    * Assignment operator. Passes the ownership of a pointer to another.
78    * @param[in] other The pointer that gives away the ownership.
79    */
80   OwnerPointer& operator=( OwnerPointer& other )
81   {
82     if( this != &other )    // no self-assignment
83     {
84       delete mObject;
85       mObject = other.mObject;
86       other.mObject = nullptr;
87     }
88
89     // return self
90     return *this;
91   }
92
93   /**
94    * Move assignment operator. Passes the ownership of a pointer to another.
95    * @param[in] other The pointer that gives away the ownership.
96    */
97   OwnerPointer& operator=( OwnerPointer&& other )
98   {
99     // Reuse operator=
100     return operator=( other );
101   }
102
103   /**
104    * Assignment operator. Takes the ownership of the object.
105    * If it owns an object already, it will be deleted.
106    * @param[in] pointer A pointer to a heap allocated object.
107    */
108   OwnerPointer& operator=( T* pointer )
109   {
110     if( mObject != pointer )
111     {
112       Reset();
113       mObject = pointer;
114     }
115
116     return *this;
117   }
118
119   /**
120    * Destructor.
121    */
122   ~OwnerPointer()
123   {
124     Reset();
125   }
126
127   /**
128    * Indirection operator.
129    * @return a reference to the object.
130    */
131   T& operator*()
132   {
133     DALI_ASSERT_DEBUG( mObject );
134
135     return *mObject;
136   }
137
138   /**
139    * Const indirection operator.
140    * @return a reference to the object from const OwnerPointer.
141    */
142   T& operator*() const
143   {
144     DALI_ASSERT_DEBUG( mObject );
145
146     // Pointer semantics: A const pointer does not mean const data.
147     return const_cast< T& >( *mObject );
148   }
149
150   /**
151    * Pointer operator.
152    * @return a pointer to the object.
153    */
154   T* operator->()
155   {
156     return mObject;
157   }
158
159   /**
160    * Const pointer operator.
161    * @return a pointer to the object referenced by a const OwnerPointer.
162    */
163   T* operator->() const
164   {
165     // Pointer semantics: A const pointer does not mean const data.
166     return const_cast< T* >( mObject );
167   }
168
169   /**
170    * Compare with a raw pointer.
171    * @return true if the raw pointer matches the one owned by this object.
172    */
173   bool operator==( const T* pointer )
174   {
175     return ( mObject == pointer );
176   }
177
178   /**
179    * Reset the pointer, deleting any owned object.
180    */
181   void Reset()
182   {
183     delete mObject;
184     mObject = nullptr;
185   }
186
187   /**
188    * Release the ownership, it does not delete the object.
189    * @return a pointer to the object.
190    */
191   T* Release()
192   {
193     T* tmp = mObject;
194     mObject = nullptr;
195     return tmp;
196   }
197
198   /**
199    * Returns a const pointer to the object owned.
200    * @return a const pointer to the object.
201    */
202   const T* Get() const
203   {
204     return mObject;
205   }
206
207   /**
208    * Swap owned objects
209    * @param[in] other The pointer to swap the owned objects with.
210    */
211   void Swap( OwnerPointer& other )
212   {
213     if( this != &other )
214     {
215       T* tmp = mObject;
216       mObject = other.mObject;
217       other.mObject = tmp;
218     }
219   }
220
221   // Handle comparisons - This is a variation of the safe bool idiom
222
223   /**
224    * Pointer-to-member type. Objects can be implicitly converted to this for validity checks.
225    */
226   typedef void (OwnerPointer::*BooleanType)() const;
227
228   /**
229    * Converts an object handle to a BooleanType.
230    * This is useful for checking whether the handle is NULL.
231    */
232   operator BooleanType() const
233   {
234     return ( mObject != nullptr ) ? &OwnerPointer::ThisIsSaferThanReturningVoidStar : nullptr;
235   }
236
237 private:
238
239   /**
240    * Used by the safe bool idiom.
241    */
242   void ThisIsSaferThanReturningVoidStar() const {}
243
244   // data
245   T* mObject; ///< Raw pointer to the object
246 };
247
248 } // namespace Internal
249
250 } // namespace Dali
251
252 #endif // DALI_INTERNAL_OWNER_POINTER_H