Use modern construct 'using' instead of typedef.
[platform/core/uifw/dali-core.git] / dali / devel-api / common / owner-container.h
1 #ifndef DALI_OWNER_CONTAINER_H
2 #define DALI_OWNER_CONTAINER_H
3
4 /*
5  * Copyright (c) 2020 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 #include <dali/public-api/common/dali-vector.h>
24
25 namespace Dali
26 {
27
28 /**
29  * OwnerContainer is a vector which own heap-allocated objects.
30  * Unlike vector this will call delete on the stored pointers during destruction.
31  * For example, you can define a vector of heap-allocated Node objects:
32  * @code
33  *   typedef OwnerContainer< Node* > NodeContainer;
34  *
35  *   NodeContainer container;
36  *   container.PushBack( new Node() );
37  *   // container is now responsible for calling delete on Node
38  *
39  * @endcode
40  */
41 template< class T >
42 class OwnerContainer : public Dali::Vector< T >
43 {
44 public:
45   using SizeType      = typename Dali::Vector<T>::SizeType;
46   using Iterator      = typename Vector<T>::Iterator;
47   using ConstIterator = typename Vector<T>::ConstIterator;
48
49   /**
50    * Create a pointer-container.
51    */
52   OwnerContainer()
53   { }
54
55   /**
56    * Non-virtual destructor; OwnerContainer<T> is not suitable as base class.
57    */
58   ~OwnerContainer()
59   {
60     Clear();
61     VectorBase::Release();
62   }
63
64   // Not copyable or movable
65   OwnerContainer( const OwnerContainer& ) = delete; ///< Deleted copy constructor
66   OwnerContainer( OwnerContainer&& ) = delete; ///< Deleted move constructor
67   OwnerContainer& operator=( const OwnerContainer& ) = delete; ///< Deleted copy assignment operator
68   OwnerContainer& operator=( OwnerContainer&& ) = delete; ///< Deleted move assignment operator
69
70   /**
71    * Test whether the container is empty.
72    * @return True if the container is empty
73    */
74   bool IsEmpty() const
75   {
76     return VectorBase::Count() == 0u;
77   }
78
79   /**
80    * Erase an object from the container (delete from heap).
81    * @param[in] position A dereferencable iterator to an element in mContainer.
82    * @return iterator pointing to next element
83    */
84   Iterator Erase( Iterator position )
85   {
86     Delete (*position);
87     return Vector< T >::Erase( position );
88   }
89
90   /**
91    * Erase an object from OwnerContainer
92    * @param object to remove
93    */
94   inline void EraseObject( T object )
95   {
96     DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
97
98     Iterator iter = Vector< T >::Begin();
99     const ConstIterator endIter = Vector< T >::End();
100     for ( ; iter != endIter; ++iter )
101     {
102       if ( *iter == object )
103       {
104         Erase( iter );
105         return;
106       }
107     }
108   }
109
110   /**
111    * Release the ownership of an object, without deleting it.
112    * @param[in] position A dereferencable iterator to an element in mContainer.
113    * @post iterators are invalidated by this method.
114    * @return pointer to the released item
115    */
116   T Release( Iterator position )
117   {
118     T pointer = *position;
119     Vector< T >::Erase( position );
120     return pointer;
121   }
122
123   /**
124    * Destroy all of the elements in the container.
125    */
126   void Clear()
127   {
128     ConstIterator end = Vector< T >::End();
129     for( Iterator iter = Vector< T >::Begin(); iter != end; ++iter )
130     {
131       Delete (*iter);
132     }
133     Vector< T >::Clear();
134   }
135
136   /**
137    * Resizes the container to hold specific amount of elements
138    * @param size to resize to
139    */
140   void Resize( SizeType size )
141   {
142     if( size < VectorBase::Count() )
143     {
144       // OwnerContainer owns these heap-allocated objects
145       ConstIterator end = Vector< T >::End();
146       for( Iterator iter = Vector< T >::Begin() + size; iter != end; ++iter )
147       {
148         Delete (*iter);
149       }
150     }
151     Vector< T >::Resize( size );
152   }
153
154   /**
155    * Move the ownership of objects from another OwnerContainer to this one
156    * without deleting them. It will keep the original items here as well.
157    * @param[in] source where to move elements from to this OwnerContainer
158    */
159   void MoveFrom( OwnerContainer& source )
160   {
161     typename Vector< T >::SizeType sourceCount = source.Count();
162     // if source is empty, nothing to move
163     if( sourceCount > 0u )
164     {
165       // Optimisation for the case that this is empty
166       if( IsEmpty() )
167       {
168         VectorBase::Swap( source );
169       }
170       else
171       {
172         // make space for new items
173         Vector< T >::Reserve( VectorBase::Count() + sourceCount );
174         Iterator iter = source.Begin();
175         ConstIterator end = source.End();
176         for( ; iter != end; ++iter )
177         {
178           T pointer = *iter;
179           Vector< T >::PushBack( pointer );
180         }
181         // cannot call Clear on OwnerContainer as that deletes the elements
182         source.Vector< T >::Clear();
183       }
184     }
185   }
186
187 private:
188
189   /**
190    * @brief delete the contents of the pointer
191    * Function provided to allow classes to provide a custom destructor through template specialisation
192    * @param pointer to the object
193    */
194   void Delete( T pointer )
195   {
196     delete pointer;
197   }
198
199
200 };
201
202 } // namespace Dali
203
204 #endif //DALI_OWNER_CONTAINER_H