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