[Tizen] Not execute the remove callback
[platform/core/uifw/dali-core.git] / dali / internal / common / indexed-map-base.h
1 #ifndef DALI_INDEXED_MAP_BASE_H
2 #define DALI_INDEXED_MAP_BASE_H
3
4 /*
5  * Copyright (c) 2022 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 // EXTERNAL INCLUDES
21 #include <algorithm>
22 #include <string>
23 #include <vector>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/common/dali-common.h>
27
28 namespace Dali
29 {
30 namespace Internal
31 {
32 /**
33  * @brief Specific key-element container which can access by index.
34  * Register element by key. and Get element by key or index.
35  *
36  * This basical member API that indexed map container needs.
37  * Indexed map container can only Register and not allow Unregister in current implement spec.
38  *
39  * This container hold std::pair<KeyType, ElementType>.
40  * Iterator will iterate this pair container.
41  *
42  * For example,
43  * @code
44  * TrieContainerBase<KeyType, SearchKeyType, KeyIndexConverterType, ElementType> container;
45  * for(auto && elements : container)
46  * {
47  *   elements.first == KeyType();
48  *   elements.second == ElementType();
49  * }
50  * @endcode
51  *
52  * Contain elements in registered order.
53  * You can access that data by this order as 'index'
54  *
55  * For example,
56  * @code
57  * container.Register(10001, 111);
58  * container.Register(20002, 222);
59  * container[10001] == 111;
60  * container[20002] == 222;
61  * container.GetElementByIndex(0) == 111;
62  * container.GetKeyByIndex(0) == 10001;
63  * container.GetKeyElementPairByIndex(1) == KeyElementPairType(20002, 222);
64  * @endcode
65  *
66  * Get API return iterator of container.
67  *
68  * For example,
69  * @code
70  * container.Register(10001, 111);
71  * const auto& iter = container.Get(10001);
72  * iter->first == 10001;
73  * iter->second == 111;
74  * container.Get(30003) == container.End();
75  * @endcode
76  *
77  * @tparam KeyType The type of the key that the container holds.
78  * @tparam SearchKeyType The type of the key when the container register or get.
79  * @tparam ElementType The type of the data that the container holds.
80  */
81 template<typename KeyType, typename SearchKeyType, typename ElementType>
82 class IndexedMapBase
83 {
84 public:
85   /**
86    * @brief Type definitions.
87    */
88   using KeyElementPairType = std::pair<KeyType, ElementType>;
89   using iterator           = typename std::vector<KeyElementPairType>::iterator;
90   using const_iterator     = typename std::vector<KeyElementPairType>::const_iterator;
91
92 public: // Virtual API
93   /**
94    * @brief Register element by the key.
95    *
96    * @param[in] key The key that this container will hold. Duplicated key doesn't allow.
97    * @param[in] element The element pairwise with key.
98    * @return True if Register success. Otherwise, return false.
99    */
100   virtual bool Register(const SearchKeyType& key, const ElementType& element) = 0;
101
102   /**
103    * @brief Get element by the key.
104    *
105    * @param[in] key The key that this container will hold.
106    * @return If exist, iterator of container. Otherwise, return End().
107    */
108   virtual iterator Get(const SearchKeyType& key) = 0;
109
110   /**
111    * @brief Get element by the key.
112    *
113    * @param[in] key The key that this container will hold.
114    * @return If exist, iterator of container. Otherwise, return End().
115    */
116   virtual const_iterator Get(const SearchKeyType& key) const = 0;
117
118 public:
119   /**
120    * @brief Constructor.
121    */
122   IndexedMapBase()
123   {
124     Clear();
125   }
126
127   /**
128    * @brief Destructor.
129    */
130   virtual ~IndexedMapBase()
131   {
132     mKeyElementPool.clear();
133   }
134
135   /**
136    * @brief Clear this container.
137    */
138   virtual void Clear()
139   {
140     mKeyElementPool.clear();
141   }
142
143   /**
144    * @brief Get the number of elements that this container hold.
145    *
146    * @return The number of elements that this container hold.
147    */
148   std::size_t Count() const
149   {
150     return mKeyElementPool.size();
151   }
152
153   /**
154    * @brief Check whether container is empty or not.
155    *
156    * @return Whether elemnt is empty or not.
157    */
158   bool Empty() const
159   {
160     return mKeyElementPool.empty();
161   }
162
163   /**
164    * @brief Reserve KeyElementPool container size.
165    * Reserve only if current container size is smaller than input size.
166    *
167    * @param[in] size Reserve size.
168    */
169   void Reserve(const std::size_t& size)
170   {
171     if(mKeyElementPool.size() < size)
172     {
173       mKeyElementPool.reserve(size);
174     }
175   }
176
177   /**
178    * @brief Get Element by the key.
179    * @note Assert throw when try to use unregistered key.
180    *
181    * @param[in] key The key what we want to get.
182    * @return registered element.
183    */
184   const ElementType& operator[](const SearchKeyType& key) const
185   {
186     const_iterator iter = Get(key);
187     DALI_ASSERT_ALWAYS(iter != End() && "const operator[] doesn't allow non-exist key access");
188     return iter->second;
189   }
190
191   /**
192    * @brief Get Element by the key.
193    * @note Assert throw when try to use unregistered key.
194    *
195    * @param[in] key The key what we want to get.
196    * @return registered element.
197    */
198   ElementType& operator[](const SearchKeyType& key)
199   {
200     iterator iter = Get(key);
201     DALI_ASSERT_ALWAYS(iter != End() && "operator[] doesn't allow non-exist key access");
202     return iter->second;
203   }
204
205   /**
206    * @brief Get Element by the index.
207    *
208    * @param[in] index The index what we want to get.
209    * @return index'th registered element.
210    * @note mTrieKeyElementPool emplace_back the elements ordered by Register function called.
211    */
212   const ElementType& GetElementByIndex(const std::uint32_t& index) const
213   {
214     DALI_ASSERT_ALWAYS((index < mKeyElementPool.size()) && "operator[] index >= Count()");
215     return mKeyElementPool[index].second;
216   }
217
218   /**
219    * @brief Get Key by the index.
220    *
221    * @param[in] index The index what we want to get.
222    * @return index'th registered key.
223    * @note mTrieKeyElementPool emplace_back the elements ordered by Register function called.
224    */
225   const KeyType& GetKeyByIndex(const std::uint32_t& index) const
226   {
227     DALI_ASSERT_ALWAYS((index < mKeyElementPool.size()) && "operator[] index >= Count()");
228     return mKeyElementPool[index].first;
229   }
230
231   /**
232    * @brief Get Key and Element by the index.
233    *
234    * @param[in] index The index what we want to get.
235    * @return index'th registered key element pair.
236    * @note mTrieKeyElementPool emplace_back the elements ordered by Register function called.
237    */
238   const KeyElementPairType& GetKeyElementPairByIndex(const std::uint32_t& index) const
239   {
240     DALI_ASSERT_ALWAYS((index < mKeyElementPool.size()) && "operator[] index >= Count()");
241     return mKeyElementPool[index];
242   }
243
244   /**
245    * @brief Iterator to the beginning of the data.
246    * @return Iterator to the beginning of the data
247    */
248   iterator Begin()
249   {
250     return mKeyElementPool.begin();
251   }
252   /**
253    * @brief Const Iterator to the beginning of the data.
254    * @return Const Iterator to the beginning of the data
255    */
256   const_iterator CBegin() const
257   {
258     return mKeyElementPool.cbegin();
259   }
260   /**
261    * @brief Const Iterator to the beginning of the data.
262    * @return Const Iterator to the beginning of the data
263    */
264   const_iterator Begin() const
265   {
266     return mKeyElementPool.begin();
267   }
268
269   /**
270    * @brief Iterator to the end of the data (one past last element).
271    * @return Iterator to the end of the data (one past last element)
272    */
273   iterator End()
274   {
275     return mKeyElementPool.end();
276   }
277   /**
278    * @brief Const iterator to the end of the data (one past last element).
279    * @return Const iterator to the end of the data (one past last element)
280    */
281   const_iterator CEnd() const
282   {
283     return mKeyElementPool.cend();
284   }
285   /**
286    * @brief Const iterator to the end of the data (one past last element).
287    * @return Const iterator to the end of the data (one past last element)
288    */
289   const_iterator End() const
290   {
291     return mKeyElementPool.end();
292   }
293
294 public: // API for C++11 std style functions.
295   /**
296    * Support for C++11 std style function call.
297    * @see Clear()
298    */
299   void clear()
300   {
301     Clear();
302   }
303
304   /**
305    * Support for C++11 std style function call.
306    *
307    * @return The number of elements that this container hold.
308    * @see Count()
309    */
310   std::size_t size() const
311   {
312     return Count();
313   }
314
315   /**
316    * Support for C++11 std style function call.
317    *
318    * @return Whether elemnt is empty or not.
319    * @see Empty()
320    */
321   bool empty() const
322   {
323     return Empty();
324   }
325
326   /**
327    * Support for C++11 std style function call.
328    *
329    * @param[in] size Reserve size.
330    * @see Reserve()
331    */
332   void reserve(const std::size_t size)
333   {
334     Reserve(size);
335   }
336
337   /**
338    * Support for C++11 Range-based for loop: for( item : container ).
339    * @return The start iterator
340    */
341   iterator begin()
342   {
343     return Begin();
344   }
345   /**
346    * Support for C++11 Range-based for loop: for( item : container ).
347    * @return The start const iterator
348    */
349   const_iterator cbegin() const
350   {
351     return CBegin();
352   }
353
354   /**
355    * Support for C++11 Range-based for loop: for( item : container ).
356    * @return The start const iterator
357    */
358   const_iterator begin() const
359   {
360     return Begin();
361   }
362
363   /**
364    * Support for C++11 Range-based for loop: for( item : container ).
365    * @return The end iterator
366    */
367   iterator end()
368   {
369     return End();
370   }
371
372   /**
373    * Support for C++11 Range-based for loop: for( item : container ).
374    * @return The end const iterator
375    */
376   const_iterator cend() const
377   {
378     return CEnd();
379   }
380
381   /**
382    * Support for C++11 Range-based for loop: for( item : container ).
383    * @return The end const iterator
384    */
385   const_iterator end() const
386   {
387     return End();
388   }
389
390 protected:
391   std::vector<KeyElementPairType> mKeyElementPool;
392 };
393
394 } // namespace Internal
395
396 } // namespace Dali
397
398 #endif //  DALI_INDEXED_MAP_BASE_H