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