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