Merge "Update Events' public header comments" 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) 2015 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 <cstddef>
23 #include <algorithm>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/type-traits.h>
28 #include <dali/public-api/math/math-utils.h>
29
30 /**
31  * @brief For DALi internal use asserts are enabled in debug builds.
32  *
33  * For Application use asserts can be enabled manually.
34  * @SINCE_1_0.0
35  */
36 #if defined( DEBUG_ENABLED )
37 #define ENABLE_VECTOR_ASSERTS
38 #endif
39
40 #if defined( ENABLE_VECTOR_ASSERTS )
41 #define DALI_ASSERT_VECTOR(cond) DALI_ASSERT_ALWAYS(cond)
42 #else
43 #define DALI_ASSERT_VECTOR(cond)
44 #endif
45
46 namespace Dali
47 {
48 /**
49  * @addtogroup dali_core_common
50  * @{
51  */
52
53 /**
54  * @brief Base class to handle the memory of simple vector.
55  *
56  * Memory layout is such that it has two std::size_t to hold the count
57  * and capacity of the vector. VectorBase::mData is adjusted so that it points to the
58  * beginning of the first real item so that iterating the items is quick.
59  * @SINCE_1_0.0
60  */
61 class DALI_IMPORT_API VectorBase
62 {
63 public: // Typedefs
64
65   typedef std::size_t SizeType;
66
67 protected: // Construction
68
69   /**
70    * @brief Default constructor. Does not allocate space.
71    * @SINCE_1_0.0
72    */
73   VectorBase();
74
75   /**
76    * @brief Destructor.
77    *
78    * Does not release the space. Derived class needs to call Release.
79    * Not virtual as should not be called directly and we do not want
80    * a vtable for this class as it would unnecessarily increase size.
81    * @SINCE_1_0.0
82    */
83   ~VectorBase();
84
85 public: // API
86
87   /**
88    * @brief This method is inlined as its 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    */
118   bool Empty() const
119   {
120     return Count() == 0u;
121   }
122
123   /**
124    * @brief Gets the capacity of this vector.
125    * @SINCE_1_0.0
126    * @return The capacity of this vector.
127    */
128   SizeType Capacity() const;
129
130   /**
131    * @brief Release the data.
132    *
133    * Does not call destructors on objects held.
134    * @SINCE_1_0.0
135    */
136   void Release();
137
138 protected: // for Derived classes
139
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 Reserve 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 Swap 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 Erase an element.
176    *
177    * Does not change capacity.
178    * @SINCE_1_0.0
179    * @param[in] address Adress 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 Erase 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 private:
210
211   // not copiable as it does not know the size of elements
212   VectorBase( const VectorBase& ); ///< Undefined @SINCE_1_0.0
213   VectorBase& operator=( const VectorBase& ); ///< Undefined @SINCE_1_0.0
214
215 protected: // Data
216
217   void* mData; ///< Pointer to the data.
218
219 };
220
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
232   typedef VectorBase::SizeType SizeType;
233
234   /**
235    * @brief Empty constructor.
236    * @SINCE_1_0.0
237    */
238   VectorAlgorithms()
239   { }
240
241   /**
242    * @brief Empty destructor.
243    * @SINCE_1_0.0
244    */
245   ~VectorAlgorithms()
246   { }
247
248   /**
249    * @brief Copy vector contents.
250    *
251    * @SINCE_1_0.0
252    * @param[in] rhs VectorBase object to copy from.
253    * @param[in] elementSize Size of the content.
254    */
255   void Copy( const VectorBase& rhs, SizeType elementSize )
256   {
257     if( rhs.Capacity() > 0u )
258     {
259       VectorBase::Copy( rhs, elementSize );
260     }
261     else
262     {
263       VectorBase::Release();
264     }
265   }
266
267   /**
268    * @brief Reserve space in the vector.
269    *
270    * @SINCE_1_0.0
271    * @param[in] count Count of elements to reserve.
272    * @param[in] elementSize Size of a single element.
273    */
274   void Reserve( SizeType count, SizeType elementSize )
275   {
276     VectorBase::Reserve( count, elementSize );
277   }
278
279   /**
280    * @brief Resize the vector. Does not change capacity.
281    *
282    * @SINCE_1_0.0
283    * @param[in] count Count to resize to.
284    * @param[in] elementSize Size of a single element.
285    */
286   void Resize( SizeType count, SizeType elementSize )
287   {
288     // reserve will copy old elements as well
289     Reserve( count, elementSize );
290   }
291
292   /**
293    * @brief Clear the contents.
294    *
295    * For simple types nothing to do.
296    * @SINCE_1_0.0
297    */
298   void Clear()
299   {
300     if( mData )
301     {
302       VectorBase::SetCount( 0u );
303     }
304   }
305
306   /**
307    * @brief Release the vector.
308    * @SINCE_1_0.0
309    */
310   void Release()
311   {
312     VectorBase::Release();
313   }
314
315   /**
316    * @brief Erase an element. Does not change capacity.
317    *
318    * @SINCE_1_0.0
319    * @param[in] address Address to erase from.
320    * @param[in] elementSize Size to erase.
321    */
322   void Erase( char* address, SizeType elementSize )
323   {
324     VectorBase::Erase( address, elementSize );
325   }
326
327   /**
328    * @brief Erase a range of elements. Does not change capacity.
329    *
330    * @SINCE_1_0.0
331    * @param[in] first Address to the first element to be erased.
332    * @param[in] last Address to the last element to be erased.
333    * @param[in] elementSize Size of one of the elements to be erased.
334    * @return Address pointing to the next element of the last one.
335    */
336   char* Erase( char* first, char* last, SizeType elementSize )
337   {
338     return VectorBase::Erase( first, last, elementSize );
339   }
340
341   /**
342    * @brief Inserts the given elements into the vector.
343    *
344    * @SINCE_1_0.0
345    * @param[in] at Address where to insert the elements into the vector.
346    * @param[in] from Address to the first element to be inserted.
347    * @param[in] to Address to the last element to be inserted.
348    * @param[in] elementSize Size of one of the elements to be inserted.
349    */
350   void Insert( char* at, char* from, char* to, SizeType elementSize )
351   {
352     const SizeType size = to - from;
353     const SizeType count = Count();
354     const SizeType newCount = count + size / elementSize;
355
356     if( newCount > Capacity() )
357     {
358       // Calculate the at offset as the pointer is invalid after the Reserve() call.
359       std::size_t offset = at - reinterpret_cast<char*>( mData );
360
361       // need more space
362       Reserve( NextPowerOfTwo( newCount ), elementSize ); // reserve enough space to store at least the next power of two elements of the new required size.
363
364       // Set the new at pointer.
365       at = reinterpret_cast<char*>( mData ) + offset;
366     }
367     // set new count first as otherwise the debug assert will hit us
368     SetCount( newCount );
369
370     // Move current items to a new position inside the vector.
371     CopyMemory( at + size,
372                 at,
373                 ( reinterpret_cast<char*>( mData ) + count * elementSize ) - at );
374
375     // Copy the given items.
376     CopyMemory( at, from, size );
377   }
378 };
379
380 /**
381  * @brief Vector algorithm variant for complex types.
382  *
383  * Not yet supported so will lead to compile error
384  * as constructor and destructor are private.
385  * TODO add support for this variant.
386  * @SINCE_1_0.0
387  */
388 template<>
389 class VectorAlgorithms< false > : public VectorBase
390 {
391 private:
392   VectorAlgorithms()
393   { }
394   ~VectorAlgorithms()
395   { }
396 };
397
398 /**
399  * @brief Vector class with minimum space allocation when its empty.
400  *
401  * @SINCE_1_0.0
402  * @param type of the data that the vector holds.
403  */
404 template< class T, bool IsTrivialType = TypeTraits<T>::IS_TRIVIAL_TYPE == true >
405 class Vector : public VectorAlgorithms< IsTrivialType >
406 {
407 public: // API
408
409   /**
410    * @brief Type definitions.
411    * @SINCE_1_0.0
412    */
413   typedef VectorBase::SizeType SizeType; ///< Size type @SINCE_1_0.0
414   typedef T* Iterator;  ///< Most simple Iterator is a pointer @SINCE_1_0.0
415   typedef const T* ConstIterator; ///< Const iterator @SINCE_1_0.0
416   typedef T  ItemType; ///< Item type @SINCE_1_0.0
417
418   enum
419   {
420     BaseType = IsTrivialType
421   };
422
423   /**
424    * @brief Default constructor. Does not allocate any space.
425    * @SINCE_1_0.0
426    */
427   Vector()
428   { }
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 assignment
448     operator=( vector );
449   }
450
451   /**
452    * @brief Assignment operator.
453    *
454    * @SINCE_1_0.0
455    * @param[in]  vector Vector to assign from.
456    * @return Reference to self for chaining.
457    */
458   Vector& operator=( const Vector& vector )
459   {
460     if( this != &vector )
461     {
462       VectorAlgorithms<BaseType>::Copy( vector, sizeof( ItemType ) );
463     }
464     return *this;
465   }
466
467   /**
468    * @brief Iterator to the beginning of the data.
469    * @SINCE_1_0.0
470    * @return Iterator to the beginning of the data.
471    */
472   Iterator Begin() const
473   {
474     ItemType* address = reinterpret_cast<ItemType*>( VectorBase::mData );
475     return address;
476   }
477
478   /**
479    * @brief Iterator to the end of the data (one past last element).
480    * @SINCE_1_0.0
481    * @return Iterator to the end of the data (one past last element).
482    */
483   Iterator End() const
484   {
485     ItemType* address = reinterpret_cast<ItemType*>( VectorBase::mData );
486     address += VectorBase::Count();
487     return address;
488   }
489
490   /**
491    * @brief Subscript operator.
492    * @SINCE_1_0.0
493    * @param[in]  index Index of the element.
494    * @return Reference to the element for given index.
495    * @pre Index must be in the vector's range.
496    */
497   ItemType& operator[]( SizeType index )
498   {
499     // reuse the const version
500     return const_cast< ItemType& >( const_cast< const Vector< ItemType >& >( *this )[ index ] );
501   }
502
503   /**
504    * @brief Subscript operator.
505    * @SINCE_1_0.0
506    * @param[in]  index of the element.
507    * @return reference to the element for given index.
508    * @pre index must be in the vector's range.
509    */
510   const ItemType& operator[]( SizeType index ) const
511   {
512     DALI_ASSERT_VECTOR( VectorBase::mData && "Vector is empty" );
513     DALI_ASSERT_VECTOR( index < VectorBase::Count() && "Index out of bounds" );
514     ItemType* address = reinterpret_cast<ItemType*>( VectorBase::mData );
515     address += index;
516     return *address;
517   }
518
519   /**
520    * @brief Push back an element to the vector.
521    *
522    * The underlying storage may be reallocated to provide space.
523    * If this occurs, all pre-existing pointers into the vector will
524    * become invalid.
525    *
526    * @SINCE_1_0.0
527    * @param[in] element Element to be added.
528    */
529   void PushBack( const ItemType& element )
530   {
531     const SizeType count = VectorBase::Count();
532     const SizeType newCount = count + 1u;
533     const SizeType capacity = VectorBase::Capacity();
534     if( newCount > capacity )
535     {
536       // need more space
537       Reserve( newCount << 1u ); // reserve double the current count
538     }
539     // set new count first as otherwise the debug assert will hit us
540     VectorBase::SetCount( newCount );
541     operator[]( count ) = element;
542   }
543
544   /**
545    *@brief Insert an element to the vector.
546    *
547    * Elements after \e at are moved one position to the right.
548    *
549    * The underlying storage may be reallocated to provide space.
550    * If this occurs, all pre-existing pointers into the vector will
551    * become invalid.
552    *
553    * @pre Iterator at must be in the vector's range ( Vector::Begin(), Vector::End() ).
554    *
555    * @param[in] at Iterator where to insert the elements into the vector.
556    * @param[in] element An element to be added.
557    *@SINCE_1_0.0
558    */
559   void Insert( Iterator at, const ItemType& element )
560   {
561     DALI_ASSERT_VECTOR( ( at <= End() ) && ( at >= Begin() ) && "Iterator not inside vector" );
562     const SizeType size = sizeof( ItemType );
563     char* address = const_cast<char*>( reinterpret_cast<const char*>( &element ) );
564     VectorAlgorithms<BaseType>::Insert( reinterpret_cast< char* >( at ),
565                                         address,
566                                         address + size,
567                                         size );
568   }
569
570   /**
571    * @brief Inserts the given elements into the vector.
572    *
573    * Elements after \e at are moved the number of given elements positions to the right.
574    *
575    * The underlying storage may be reallocated to provide space.
576    * If this occurs, all pre-existing pointers into the vector will
577    * become invalid.
578    *
579    * @SINCE_1_0.0
580    * @param[in] at Iterator where to insert the elements into the vector.
581    * @param[in] from Iterator to the first element to be inserted.
582    * @param[in] to Iterator to the last element to be inserted.
583    * @pre Iterator \e at must be in the vector's range ( Vector::Begin(), Vector::End() ).
584    * @pre Iterators \e from and \e to must be valid iterators.
585    * @pre Iterator \e from must not be grater than Iterator \e to.
586    *
587    */
588   void Insert( Iterator at, Iterator from, Iterator to )
589   {
590     DALI_ASSERT_VECTOR( ( at <= End() ) && ( at >= Begin() ) && "Iterator not inside vector" );
591     DALI_ASSERT_VECTOR( ( from <= to ) && "from address can't be greater than to" );
592
593     if( from == to )
594     {
595       // nothing to copy.
596       return;
597     }
598
599     VectorAlgorithms<BaseType>::Insert( reinterpret_cast< char* >( at ),
600                                         reinterpret_cast< char* >( from ),
601                                         reinterpret_cast< char* >( to ),
602                                         sizeof( ItemType ) );
603   }
604
605   /**
606    * @brief Reserve space in the vector.
607    *
608    * Reserving less than current Capacity is a no-op.
609    * @SINCE_1_0.0
610    * @param[in] count Count of elements to reserve.
611    */
612   void Reserve( SizeType count )
613   {
614     VectorAlgorithms<BaseType>::Reserve( count, sizeof( ItemType ) );
615   }
616
617   /**
618    * @brief Resize the vector. Does not change capacity.
619    *
620    * @SINCE_1_0.0
621    * @param[in] count Count to resize to.
622    */
623   void Resize( SizeType count )
624   {
625     ItemType item = ItemType();
626     Resize(count, item);
627   }
628
629   /**
630    * @brief Resize the vector. Does not change capacity.
631    *
632    * @SINCE_1_0.0
633    * @param[in] count Count to resize to.
634    * @param[in] item An item to insert to the new indices.
635    */
636   void Resize( SizeType count, const ItemType& item )
637   {
638     const SizeType oldCount = VectorBase::Count();
639     if( count <= oldCount )
640     {
641       // getting smaller so just set count
642       VectorBase::SetCount( count );
643     }
644     else
645     {
646       // remember how many new items get added
647       SizeType newItems = count - oldCount;
648       Reserve( count );
649       for( ; newItems > 0u; --newItems )
650       {
651         PushBack( item );
652       }
653     }
654   }
655
656   /**
657    * @brief Erase an element.
658    *
659    * Does not change capacity. Other elements get moved.
660    *
661    * @SINCE_1_0.0
662    * @param[in] iterator Iterator pointing to item to remove.
663    * @return Iterator pointing to next element.
664    * @pre Iterator \e iterator must be within the vector's range ( Vector::Begin(), Vector::End() - 1 ).
665    *
666    */
667   Iterator Erase( Iterator iterator )
668   {
669     DALI_ASSERT_VECTOR( (iterator < End()) && (iterator >= Begin()) && "Iterator not inside vector" );
670     if( iterator < ( End() - 1u ) )
671     {
672       VectorAlgorithms<BaseType>::Erase( reinterpret_cast< char* >( iterator ), sizeof( ItemType ) );
673     }
674     else
675     {
676       // just remove the element
677       Remove( iterator );
678     }
679     return iterator;
680   }
681
682   /**
683    * @brief Erase a range of elements.
684    *
685    * Does not change capacity. Other elements get moved.
686    *
687    * @SINCE_1_0.0
688    * @param[in] first Iterator to the first element to be erased.
689    * @param[in] last Iterator to the last element to be erased.
690    *
691    * @return Iterator pointing to the next element of the last one.
692    * @pre Iterator \e first must be in the vector's range ( Vector::Begin(), Vector::End() ).
693    * @pre Iterator \e last must be in the vector's range ( Vector::Begin(), Vector::End() ).
694    * @pre Iterator \e first must not be grater than Iterator \e last.
695    *
696    */
697   Iterator Erase( Iterator first, Iterator last )
698   {
699     DALI_ASSERT_VECTOR( ( first <= End() ) && ( first >= Begin() ) && "Iterator not inside vector" );
700     DALI_ASSERT_VECTOR( ( last <= End() ) && ( last >= Begin() ) && "Iterator not inside vector" );
701     DALI_ASSERT_VECTOR( ( first <= last ) && "first iterator greater than last" );
702
703     Iterator nextElement;
704
705     if( last == End() )
706     {
707       // Erase up to the end.
708       VectorBase::SetCount( VectorBase::Count() - ( last - first ) );
709       nextElement = End();
710     }
711     else
712     {
713       nextElement = reinterpret_cast<Iterator>( VectorAlgorithms<BaseType>::Erase( reinterpret_cast< char* >( first ),
714                                                                                    reinterpret_cast< char* >( last ),
715                                                                                    sizeof( ItemType ) ) );
716     }
717
718     return nextElement;
719   }
720
721   /**
722    * @brief Removes an element.
723    *
724    * Does not maintain order.  Swaps the element with end and
725    * decreases size by one.  This is much faster than Erase so use
726    * this in case order does not matter. Does not change capacity.
727    *
728    * @SINCE_1_0.0
729    * @param[in] iterator Iterator pointing to item to remove.
730    * @pre Iterator \e iterator must be in the vector's range ( Vector::Begin(), Vector::End() - 1 ).
731    *
732    */
733   void Remove( Iterator iterator )
734   {
735     DALI_ASSERT_VECTOR( (iterator < End()) && (iterator >= Begin()) && "Iterator not inside vector" );
736
737     Iterator last = End() - 1u;
738     if( last > iterator )
739     {
740       std::swap( *iterator, *last );
741     }
742     VectorBase::SetCount( VectorBase::Count() - 1u );
743   }
744
745   /**
746    * @brief Swap the contents of two vectors.
747    *
748    * @SINCE_1_0.0
749    * @param[in] vector Vector to swap with.
750    */
751   void Swap( Vector& vector )
752   {
753     VectorBase::Swap( vector );
754   }
755
756   /**
757    * @brief Clear the contents of the vector. Keeps its capacity.
758    * @SINCE_1_0.0
759    */
760   void Clear()
761   {
762     VectorAlgorithms<BaseType>::Clear();
763   }
764
765   /**
766    * @brief Release the memory that the vector holds.
767    * @SINCE_1_0.0
768    */
769   void Release()
770   {
771     VectorAlgorithms<BaseType>::Release();
772   }
773 };
774
775 /**
776  * @}
777  */
778 } // namespace Dali
779
780 #endif /* __DALI_VECTOR_H__ */