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