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