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