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