[dali_2.3.25] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / public-api / common / dali-vector.h
1 #ifndef DALI_VECTOR_H
2 #define DALI_VECTOR_H
3
4 /*
5  * Copyright (c) 2024 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 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <cstddef>
24 #include <cstdint> // uint32_t
25
26 // INTERNAL INCLUDES
27 #include <dali/public-api/common/dali-common.h>
28 #include <dali/public-api/common/type-traits.h>
29 #include <dali/public-api/math/math-utils.h>
30
31 /**
32  * @brief For DALi internal use, asserts are enabled in debug builds.
33  *
34  * For Application use, asserts can be enabled manually.
35  * @SINCE_2_1.23
36  */
37 #if defined(DEBUG_ENABLED)
38 #define ENABLE_VECTOR_ASSERTS
39 #endif
40
41 #if defined(ENABLE_VECTOR_ASSERTS)
42 #define DALI_ASSERT_VECTOR(cond) DALI_ASSERT_ALWAYS(cond)
43 #else
44 #define DALI_ASSERT_VECTOR(cond)
45 #endif
46
47 namespace Dali
48 {
49 /**
50  * @addtogroup dali_core_common
51  * @{
52  */
53
54 /**
55  * @brief Base class to handle the memory of simple vector.
56  *
57  * Memory layout is such that it has two std::size_t to hold the count
58  * and capacity of the vector. VectorBase::mData is adjusted so that it points to the
59  * beginning of the first real item so that iterating the items is quick.
60  * @SINCE_1_0.0
61  */
62 class DALI_CORE_API VectorBase
63 {
64 public: // Typedefs
65   using SizeType = std::size_t;
66
67   constexpr static uint32_t SHRINK_REQUIRED_RATIO = 4; ///< The ratio of auto shrink to fit calling. @SINCE_2_3.22
68
69 protected: // Construction
70   /**
71    * @brief Default constructor. Does not allocate space.
72    * @SINCE_1_0.0
73    */
74   VectorBase();
75
76   /**
77    * @brief Destructor.
78    *
79    * Does not release the space. Derived class needs to call Release.
80    * Not virtual as this should not be called directly and we do not want
81    * a vtable for this class as it would unnecessarily increase size.
82    * @SINCE_1_0.0
83    */
84   ~VectorBase();
85
86 public: // API
87   /**
88    * @brief This method is inlined as it's needed frequently for Vector::End() iterator.
89    *
90    * @SINCE_1_0.0
91    * @return The count of elements in this vector
92    */
93   SizeType Count() const
94   {
95     SizeType items = 0u;
96     if(mData)
97     {
98       SizeType* metadata = reinterpret_cast<SizeType*>(mData);
99       items              = *(metadata - 1u);
100     }
101     return items;
102   }
103
104   /**
105    * @brief Gets the count of elements in this vector.
106    * @SINCE_1_0.0
107    * @return The count of elements in this vector
108    */
109   SizeType Size() const
110   {
111     return Count();
112   }
113
114   /**
115    * @brief @ return if the vector is empty.
116    * @SINCE_1_0.0
117    * @return True if the count of elements is empty
118    */
119   bool Empty() const
120   {
121     return Count() == 0u;
122   }
123
124   /**
125    * @brief Gets the capacity of this vector.
126    * @SINCE_1_0.0
127    * @return The capacity of this vector
128    */
129   SizeType Capacity() const;
130
131   /**
132    * @brief Releases the data.
133    *
134    * Does not call destructors on objects held.
135    * @SINCE_1_0.0
136    */
137   void Release();
138
139 protected: // for Derived classes
140   /**
141    * @brief Helper to set the count.
142    *
143    * @SINCE_1_0.0
144    * @param[in] count Number of elements in the vector
145    */
146   void SetCount(SizeType count);
147
148   /**
149    * @brief Reserves space in the vector.
150    *
151    * @SINCE_1_0.0
152    * @param[in] count Count of elements to reserve
153    * @param[in] elementSize Size of a single element
154    */
155   void Reserve(SizeType count, SizeType elementSize);
156
157   /**
158    * @brief Copy a vector.
159    *
160    * @SINCE_1_0.0
161    * @param[in] vector Vector to copy from
162    * @param[in] elementSize Size of a single element
163    */
164   void Copy(const VectorBase& vector, SizeType elementSize);
165
166   /**
167    * @brief Swaps the contents of two vectors.
168    *
169    * @SINCE_1_0.0
170    * @param[in] vector Vector to swap with
171    */
172   void Swap(VectorBase& vector);
173
174   /**
175    * @brief Erases an element.
176    *
177    * Does not change capacity.
178    * @SINCE_1_0.0
179    * @param[in] address Address to erase from
180    * @param[in] elementSize Size to erase
181    * @pre Last element cannot be erased as there is nothing to move.
182    */
183   void Erase(char* address, SizeType elementSize);
184
185   /**
186    * @brief Erases a range of elements.
187    *
188    * Does not change capacity.
189    * @SINCE_1_0.0
190    * @param[in] first Address to the first element to be erased
191    * @param[in] last Address to the last element to be erased
192    * @param[in] elementSize Size of one of the elements to be erased
193    * @return Address pointing to the next element of the last one
194    */
195   char* Erase(char* first, char* last, SizeType elementSize);
196
197   /**
198    * @brief Copies a number of bytes from \e source to \e destination.
199    *
200    * \e source and \e destination must not overlap.
201    *
202    * @SINCE_1_0.0
203    * @param[in] destination Pointer to the destination address
204    * @param[in] source Pointer to the source address
205    * @param[in] numberOfBytes The number of bytes to be copied
206    */
207   void CopyMemory(char* destination, const char* source, size_t numberOfBytes);
208
209   /**
210    * @brief Replace the data as new data address.
211    * After replace, release the old data.
212    *
213    * It will be used when we want to keep the mData integrity.
214    *
215    * Does not call destructors on objects held.
216    * @param[in] newData new data address to be replaced
217    */
218   void Replace(void* newData) noexcept;
219
220   /**
221    * @brief Fit the capacity of vector as item counts.
222    * It will be used when we want to remove unused memory.
223    *
224    * @SINCE_2_3.22
225    * @param[in] elementSize Size of a single element
226    */
227   void ShrinkToFit(SizeType elementSize);
228
229 private:
230   // not copyable as it does not know the size of elements
231   VectorBase(const VectorBase&) = delete;            ///< Deleted copy constructor. @SINCE_1_0.0
232   VectorBase& operator=(const VectorBase&) = delete; ///< Deleted copy assignment operator. @SINCE_1_0.0
233
234   // not movable as this is handled by deriving classes
235   VectorBase(VectorBase&&) = delete;            ///< Deleted move constructor. @SINCE_1_9.25
236   VectorBase& operator=(VectorBase&&) = delete; ///< Deleted copy assignment operator. @SINCE_1_9.25
237
238 protected:     // Data
239   void* mData; ///< Pointer to the data.
240 };
241
242 /// @cond internal
243 /**
244  * @brief Vector algorithm variant for trivial types.
245  *
246  * Trivial types do not need destructor or copy constructor called.
247  * @SINCE_1_0.0
248  */
249 template<bool IsTrivial>
250 class VectorAlgorithms : public VectorBase
251 {
252 protected: // API for deriving classes
253   using SizeType = VectorBase::SizeType;
254
255   /**
256    * @brief Empty constructor.
257    * @SINCE_1_0.0
258    */
259   VectorAlgorithms() = default;
260
261   /**
262    * @brief Empty destructor.
263    * @SINCE_1_0.0
264    */
265   ~VectorAlgorithms() = default;
266
267   /**
268    * @brief Copy vector contents.
269    *
270    * @SINCE_1_0.0
271    * @param[in] rhs VectorBase object to copy from
272    * @param[in] elementSize Size of the content
273    */
274   void Copy(const VectorBase& rhs, SizeType elementSize)
275   {
276     if(rhs.Capacity() > 0u)
277     {
278       VectorBase::Copy(rhs, elementSize);
279     }
280     else
281     {
282       VectorBase::Release();
283     }
284   }
285
286   /**
287    * @brief Reserves space in the vector.
288    *
289    * @SINCE_1_0.0
290    * @param[in] count Count of elements to reserve
291    * @param[in] elementSize Size of a single element
292    */
293   void Reserve(SizeType count, SizeType elementSize)
294   {
295     VectorBase::Reserve(count, elementSize);
296   }
297
298   /**
299    * @brief Resizes the vector. Does not change capacity.
300    *
301    * @SINCE_1_0.0
302    * @param[in] count Count to resize to
303    * @param[in] elementSize Size of a single element
304    */
305   void Resize(SizeType count, SizeType elementSize)
306   {
307     // reserve will copy old elements as well
308     Reserve(count, elementSize);
309   }
310
311   /**
312    * @brief Clears the contents.
313    *
314    * For simple types, nothing to do.
315    * @SINCE_1_0.0
316    */
317   void Clear()
318   {
319     if(mData)
320     {
321       VectorBase::SetCount(0u);
322     }
323   }
324
325   /**
326    * @brief Releases the vector.
327    * @SINCE_1_0.0
328    */
329   void Release()
330   {
331     VectorBase::Release();
332   }
333
334   /**
335    * @brief Erases an element. Does not change capacity.
336    *
337    * @SINCE_1_0.0
338    * @param[in] address Address to erase from
339    * @param[in] elementSize Size to erase
340    */
341   void Erase(uint8_t* address, SizeType elementSize)
342   {
343     VectorBase::Erase(reinterpret_cast<char*>(address), elementSize);
344   }
345
346   /**
347    * @brief Erases a range of elements. Does not change capacity.
348    *
349    * @SINCE_1_0.0
350    * @param[in] first Address to the first element to be erased
351    * @param[in] last Address to the last element to be erased
352    * @param[in] elementSize Size of one of the elements to be erased
353    * @return Address pointing to the next element of the last one
354    */
355   uint8_t* Erase(uint8_t* first, uint8_t* last, SizeType elementSize)
356   {
357     return reinterpret_cast<uint8_t*>(VectorBase::Erase(reinterpret_cast<char*>(first), reinterpret_cast<char*>(last), elementSize));
358   }
359
360   /**
361    * @brief Inserts the given elements into the vector.
362    *
363    * @SINCE_1_0.0
364    * @param[in] at Address where to insert the elements into the vector
365    * @param[in] from Address to the first element to be inserted
366    * @param[in] to Address to the last element to be inserted
367    * @param[in] elementSize Size of one of the elements to be inserted
368    */
369   void Insert(uint8_t* at, uint8_t* from, uint8_t* to, SizeType elementSize)
370   {
371     const SizeType size     = to - from;
372     const SizeType count    = Count();
373     const SizeType newCount = count + size / elementSize;
374
375     if(newCount > Capacity())
376     {
377       // Calculate the at offset as the pointer is invalid after the Reserve() call.
378       std::size_t offset = at - reinterpret_cast<uint8_t*>(mData);
379
380       // need more space
381       Reserve(NextPowerOfTwo(static_cast<uint32_t>(newCount)), elementSize); // reserve enough space to store at least the next power of two elements of the new required size.
382
383       // Set the new at pointer.
384       at = reinterpret_cast<uint8_t*>(mData) + offset;
385     }
386     // set new count first as otherwise the debug assert will hit us
387     SetCount(newCount);
388
389     // Move current items to a new position inside the vector.
390     CopyMemory(reinterpret_cast<char*>(at + size),
391                reinterpret_cast<const char*>(at),
392                (reinterpret_cast<uint8_t*>(mData) + count * elementSize) - at);
393
394     // Copy the given items.
395     CopyMemory(reinterpret_cast<char*>(at), reinterpret_cast<const char*>(from), size);
396   }
397 };
398 /// @endcond
399
400 /// @cond internal
401 /**
402  * @brief Vector algorithm variant for complex types.
403  *
404  * Not yet supported so will lead to compile error
405  * as constructor and destructor are private.
406  * TODO add support for this variant.
407  * @SINCE_1_0.0
408  */
409 template<>
410 class VectorAlgorithms<false> : public VectorBase
411 {
412 private:
413   VectorAlgorithms()  = default;
414   ~VectorAlgorithms() = default;
415 };
416 /// @endcond
417
418 /**
419  * @brief Vector class with minimum space allocation when it's empty.
420  *
421  * @SINCE_1_0.0
422  * @param type The type of the data that the vector holds
423  */
424 template<class T, bool IsTrivialType = TypeTraits<T>::IS_TRIVIAL_TYPE == true>
425 class Vector : public VectorAlgorithms<IsTrivialType>
426 {
427 public: // API
428   /**
429    * @brief Type definitions.
430    * @SINCE_1_0.0
431    */
432   using SizeType      = VectorBase::SizeType; ///< Size type @SINCE_1_0.0
433   using Iterator      = T*;                   ///< Most simple Iterator is a pointer @SINCE_1_0.0
434   using ConstIterator = const T*;             ///< Const iterator @SINCE_1_0.0
435   using ItemType      = T;                    ///< Item type @SINCE_1_0.0
436
437   /**
438    * @brief Enumeration for BaseType.
439    * @SINCE_1_0.0
440    */
441   enum
442   {
443     BaseType = IsTrivialType ///< @SINCE_1_0.0
444   };
445
446   /**
447    * @brief Default constructor. Does not allocate any space.
448    * @SINCE_1_0.0
449    */
450   Vector() = default;
451
452   /**
453    * @brief Create vector with count, without initialize value.
454    *
455    * @SINCE_2_3.22
456    * @param[in] count The count of vector.
457    */
458   Vector(SizeType count)
459   {
460     ResizeUninitialized(count);
461   }
462
463   /**
464    * @brief Destructor. Releases the allocated space.
465    * @SINCE_1_0.0
466    */
467   ~Vector()
468   {
469     Release();
470   }
471
472   /**
473    * @brief Copy constructor.
474    *
475    * @SINCE_1_0.0
476    * @param[in] vector Vector to copy from
477    */
478   Vector(const Vector& vector)
479   {
480     // reuse copy assignment
481     operator=(vector);
482   }
483
484   /**
485    * @brief Default move constructor.
486    *
487    * @SINCE_1_9.25
488    * @param[in] vector Vector to move
489    */
490   Vector(Vector&& vector) noexcept
491   {
492     // reuse move assignment
493     operator=(std::move(vector));
494   }
495
496   /**
497    * @brief Assignment operator.
498    *
499    * @SINCE_1_0.0
500    * @param[in] vector Vector to assign from
501    * @return Reference to self for chaining
502    */
503   Vector& operator=(const Vector& vector)
504   {
505     if(this != &vector)
506     {
507       VectorAlgorithms<BaseType>::Copy(vector, sizeof(ItemType));
508     }
509     return *this;
510   }
511
512   /**
513    * @brief Default move assignment operator.
514    *
515    * @SINCE_1_9.25
516    * @param[in] vector Vector to move
517    */
518   Vector& operator=(Vector&& vector) noexcept
519   {
520     if(this != &vector)
521     {
522       VectorAlgorithms<BaseType>::Replace(vector.mData);
523       vector.mData = nullptr;
524     }
525     return *this;
526   }
527
528   /**
529    * @brief Iterator to the beginning of the data.
530    * @SINCE_1_0.0
531    * @return Iterator to the beginning of the data
532    */
533   Iterator Begin() const
534   {
535     ItemType* address = reinterpret_cast<ItemType*>(VectorBase::mData);
536     return address;
537   }
538
539   /**
540    * @brief Iterator to the end of the data (one past last element).
541    * @SINCE_1_0.0
542    * @return Iterator to the end of the data (one past last element)
543    */
544   Iterator End() const
545   {
546     ItemType* address = reinterpret_cast<ItemType*>(VectorBase::mData);
547     address += VectorBase::Count();
548     return address;
549   }
550
551   /**
552    * Support for C++11 Range-based for loop: for( item : container ).
553    * @SINCE_1_2.60
554    * @return The start iterator
555    */
556   Iterator begin() const
557   {
558     return Begin();
559   }
560
561   /**
562    * Support for C++11 Range-based for loop: for( item : container ).
563    * @SINCE_1_2.60
564    * @return The end iterator
565    */
566   Iterator end() const
567   {
568     return End();
569   }
570
571   /**
572    * @brief Subscript operator.
573    * @SINCE_1_0.0
574    * @param[in] index Index of the element
575    * @return Reference to the element for given index
576    * @pre Index must be in the vector's range.
577    */
578   ItemType& operator[](SizeType index)
579   {
580     // reuse the const version
581     return const_cast<ItemType&>(const_cast<const Vector<ItemType>&>(*this)[index]);
582   }
583
584   /**
585    * @brief Subscript operator.
586    * @SINCE_1_0.0
587    * @param[in] index Index of the element
588    * @return Reference to the element for given index
589    * @pre Index must be in the vector's range.
590    */
591   const ItemType& operator[](SizeType index) const
592   {
593     DALI_ASSERT_VECTOR(VectorBase::mData && "Vector is empty");
594     DALI_ASSERT_VECTOR(index < VectorBase::Count() && "Index out of bounds");
595     ItemType* address = reinterpret_cast<ItemType*>(VectorBase::mData);
596     address += index;
597     return *address;
598   }
599
600   /**
601    * @brief Pushes back an element to the vector.
602    *
603    * The underlying storage may be reallocated to provide space.
604    * If this occurs, all pre-existing pointers into the vector will
605    * become invalid.
606    *
607    * @SINCE_1_0.0
608    * @param[in] element Element to be added
609    */
610   void PushBack(const ItemType& element)
611   {
612     const SizeType count    = VectorBase::Count();
613     const SizeType newCount = count + 1u;
614     const SizeType capacity = VectorBase::Capacity();
615     if(newCount > capacity)
616     {
617       // need more space
618       Reserve(newCount << 1u); // reserve double the current count
619     }
620     // set new count first as otherwise the debug assert will hit us
621     VectorBase::SetCount(newCount);
622     operator[](count) = element;
623   }
624
625   /**
626    * @brief Inserts an element to the vector.
627    *
628    * Elements after \e at are moved one position to the right.
629    *
630    * The underlying storage may be reallocated to provide space.
631    * If this occurs, all pre-existing pointers into the vector will
632    * become invalid.
633    *
634    * @SINCE_1_0.0
635    * @param[in] at Iterator where to insert the elements into the vector
636    * @param[in] element An element to be added
637    * @pre Iterator at must be in the vector's range ( Vector::Begin(), Vector::End() ).
638    */
639   void Insert(Iterator at, const ItemType& element)
640   {
641     DALI_ASSERT_VECTOR((at <= End()) && (at >= Begin()) && "Iterator not inside vector");
642     const SizeType size    = sizeof(ItemType);
643     uint8_t*       address = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&element));
644     VectorAlgorithms<BaseType>::Insert(reinterpret_cast<uint8_t*>(at),
645                                        address,
646                                        address + size,
647                                        size);
648   }
649
650   /**
651    * @brief Inserts the given elements into the vector.
652    *
653    * Elements after \e at are moved the number of given elements positions to the right.
654    *
655    * The underlying storage may be reallocated to provide space.
656    * If this occurs, all pre-existing pointers into the vector will
657    * become invalid.
658    *
659    * @SINCE_1_0.0
660    * @param[in] at Iterator where to insert the elements into the vector
661    * @param[in] from Iterator to the first element to be inserted
662    * @param[in] to Iterator to the last element to be inserted
663    * @pre Iterator \e at must be in the vector's range ( Vector::Begin(), Vector::End() ).
664    * @pre Iterators \e from and \e to must be valid iterators.
665    * @pre Iterator \e from must not be grater than Iterator \e to.
666    *
667    */
668   void Insert(Iterator at, Iterator from, Iterator to)
669   {
670     DALI_ASSERT_VECTOR((at <= End()) && (at >= Begin()) && "Iterator not inside vector");
671     DALI_ASSERT_VECTOR((from <= to) && "from address can't be greater than to");
672
673     if(from == to)
674     {
675       // nothing to copy.
676       return;
677     }
678
679     VectorAlgorithms<BaseType>::Insert(reinterpret_cast<uint8_t*>(at),
680                                        reinterpret_cast<uint8_t*>(from),
681                                        reinterpret_cast<uint8_t*>(to),
682                                        sizeof(ItemType));
683   }
684
685   /**
686    * @brief Reserves space in the vector.
687    *
688    * Reserving less than current Capacity is a no-op.
689    * @SINCE_1_0.0
690    * @param[in] count Count of elements to reserve
691    */
692   void Reserve(SizeType count)
693   {
694     VectorAlgorithms<BaseType>::Reserve(count, sizeof(ItemType));
695   }
696
697   /**
698    * @brief Resizes the vector. Does not change capacity.
699    *
700    * @SINCE_1_0.0
701    * @param[in] count Count to resize to
702    */
703   void Resize(SizeType count)
704   {
705     ItemType item = ItemType();
706     Resize(count, item);
707   }
708
709   /**
710    * @brief Resizes the vector without initializing the data.
711    *
712    * Can be used as a data container for reading whole file content.
713    * @SINCE_1_9.27
714    * @param[in] count Count to resize to
715    */
716   void ResizeUninitialized(SizeType count)
717   {
718     Reserve(count);
719     VectorBase::SetCount(count);
720   }
721
722   /**
723    * @brief Resizes the vector. Does not change capacity.
724    *
725    * @SINCE_1_0.0
726    * @param[in] count Count to resize to
727    * @param[in] item An item to insert to the new indices
728    */
729   void Resize(SizeType count, const ItemType& item)
730   {
731     const SizeType oldCount = VectorBase::Count();
732     if(count <= oldCount)
733     {
734       // getting smaller so just set count
735       VectorBase::SetCount(count);
736     }
737     else
738     {
739       // remember how many new items get added
740       SizeType newItems = count - oldCount;
741       Reserve(count);
742       for(; newItems > 0u; --newItems)
743       {
744         PushBack(item);
745       }
746     }
747   }
748
749   /**
750    * @brief Erases an element.
751    *
752    * Does not change capacity. Other elements get moved.
753    *
754    * @SINCE_1_0.0
755    * @param[in] iterator Iterator pointing to the item to remove
756    * @return Iterator pointing to next element
757    * @pre Iterator \e iterator must be within the vector's range ( Vector::Begin(), Vector::End() - 1 ).
758    *
759    */
760   Iterator Erase(Iterator iterator)
761   {
762     DALI_ASSERT_VECTOR((iterator < End()) && (iterator >= Begin()) && "Iterator not inside vector");
763     if(iterator < (End() - 1u))
764     {
765       VectorAlgorithms<BaseType>::Erase(reinterpret_cast<uint8_t*>(iterator), sizeof(ItemType));
766     }
767     else
768     {
769       // just remove the element
770       Remove(iterator);
771     }
772     return iterator;
773   }
774
775   /**
776    * @brief Erases a range of elements.
777    *
778    * Does not change capacity. Other elements get moved.
779    *
780    * @SINCE_1_0.0
781    * @param[in] first Iterator to the first element to be erased
782    * @param[in] last Iterator to the last element to be erased
783    *
784    * @return Iterator pointing to the next element of the last one
785    * @pre Iterator \e first must be in the vector's range ( Vector::Begin(), Vector::End() ).
786    * @pre Iterator \e last must be in the vector's range ( Vector::Begin(), Vector::End() ).
787    * @pre Iterator \e first must not be grater than Iterator \e last.
788    *
789    */
790   Iterator Erase(Iterator first, Iterator last)
791   {
792     DALI_ASSERT_VECTOR((first <= End()) && (first >= Begin()) && "Iterator not inside vector");
793     DALI_ASSERT_VECTOR((last <= End()) && (last >= Begin()) && "Iterator not inside vector");
794     DALI_ASSERT_VECTOR((first <= last) && "first iterator greater than last");
795
796     Iterator nextElement;
797
798     if(last == End())
799     {
800       // Erase up to the end.
801       VectorBase::SetCount(VectorBase::Count() - (last - first));
802       nextElement = End();
803     }
804     else
805     {
806       nextElement = reinterpret_cast<Iterator>(VectorAlgorithms<BaseType>::Erase(reinterpret_cast<uint8_t*>(first),
807                                                                                  reinterpret_cast<uint8_t*>(last),
808                                                                                  sizeof(ItemType)));
809     }
810
811     return nextElement;
812   }
813
814   /**
815    * @brief Removes an element.
816    *
817    * Does not maintain order. Swaps the element with end and
818    * decreases size by one.  This is much faster than Erase so use
819    * this in case order does not matter. Does not change capacity.
820    *
821    * @SINCE_1_0.0
822    * @param[in] iterator Iterator pointing to the item to remove
823    * @pre Iterator \e iterator must be in the vector's range ( Vector::Begin(), Vector::End() - 1 ).
824    *
825    */
826   void Remove(Iterator iterator)
827   {
828     DALI_ASSERT_VECTOR((iterator < End()) && (iterator >= Begin()) && "Iterator not inside vector");
829
830     Iterator last = End() - 1u;
831     if(last > iterator)
832     {
833       std::swap(*iterator, *last);
834     }
835     VectorBase::SetCount(VectorBase::Count() - 1u);
836   }
837
838   /**
839    * @brief Swaps the contents of two vectors.
840    *
841    * @SINCE_1_0.0
842    * @param[in] vector Vector to swap with
843    */
844   void Swap(Vector& vector)
845   {
846     VectorBase::Swap(vector);
847   }
848
849   /**
850    * @brief Clears the contents of the vector. Keeps its capacity.
851    * @SINCE_1_0.0
852    */
853   void Clear()
854   {
855     VectorAlgorithms<BaseType>::Clear();
856   }
857
858   /**
859    * @brief Releases the memory that the vector holds.
860    * @SINCE_1_0.0
861    */
862   void Release()
863   {
864     VectorAlgorithms<BaseType>::Release();
865   }
866
867   /**
868    * @brief Fit the capacity of vector as item counts.
869    *
870    * @SINCE_2_3.22
871    */
872   void ShrinkToFit()
873   {
874     VectorBase::ShrinkToFit(sizeof(ItemType));
875   }
876
877   /**
878    * @brief Fit the capacity of vector as item counts
879    * only if low spec memory management enabled, and the count is much smaller than capacity.
880    * It will be used when we want to remove unused memory.
881    *
882    * @SINCE_2_3.22
883    */
884   void ShrinkToFitIfNeeded()
885   {
886     // Run ShrinkToFit only if VectorBase::Capacity() is bigger than the smallest malloc block size.
887     if(DALI_UNLIKELY(VectorBase::Count() * VectorBase::SHRINK_REQUIRED_RATIO < VectorBase::Capacity()))
888     {
889       VectorBase::ShrinkToFit(sizeof(ItemType));
890     }
891   }
892 };
893
894 /**
895  * @brief Erases all elements that compare equal to value from the vector.
896  *
897  * @SINCE_1_9.33
898  * @param[in] vector The vector
899  * @param[in] value The value to be removed.
900  */
901 template<class T, class U>
902 inline void Erase(Dali::Vector<T>& vector, const U& value)
903 {
904   auto begin = vector.Begin();
905   auto end   = vector.End();
906
907   vector.Erase(std::remove(begin, end, value), end);
908 }
909
910 /**
911  * @brief Erases all elements that satisfy the predicate from the vector.
912  *
913  * @SINCE_1_9.33
914  * @param[in] vector The vector
915  * @param[in] predicate The predicate
916  */
917 template<class T, class Predicate>
918 inline void EraseIf(Dali::Vector<T>& vector, Predicate predicate)
919 {
920   auto begin = vector.Begin();
921   auto end   = vector.End();
922
923   vector.Erase(std::remove_if(begin, end, predicate), end);
924 }
925
926 /**
927  * @}
928  */
929 } // namespace Dali
930
931 #endif // DALI_VECTOR_H