SmallVector.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_UTIL_SMALLVECTOR_H_
36 #define _BLAZE_UTIL_SMALLVECTOR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <memory>
50 #include <blaze/util/Assert.h>
53 #include <blaze/util/Exception.h>
55 #include <blaze/util/Types.h>
59 
60 
61 namespace blaze {
62 
63 //=================================================================================================
64 //
65 // CLASS DEFINITION
66 //
67 //=================================================================================================
68 
69 //*************************************************************************************************
77 template< typename T // Data type of the elements
78  , size_t N // Number of preallocated elements
79  , typename A = std::allocator<T> > // Type of the allocator
81  : private A
82 {
83  public:
84  //**Type definitions****************************************************************************
85  using ElementType = T;
86  using Pointer = T*;
87  using ConstPointer = const T*;
88  using Reference = T&;
89  using ConstReference = const T&;
90  using Iterator = T*;
91  using ConstIterator = const T*;
92  //**********************************************************************************************
93 
94  //**Constructors********************************************************************************
97  explicit inline SmallVector( const A& alloc = A() );
98  explicit inline SmallVector( size_t n, const A& alloc = A() );
99  explicit inline SmallVector( size_t n, const T& init, const A& alloc = A() );
100 
101  template< typename InputIt >
102  explicit inline SmallVector( InputIt first, InputIt last, const A& alloc = A() );
103 
104  template< typename U >
105  explicit inline SmallVector( initializer_list<U> list, const A& alloc = A() );
106 
107  inline SmallVector( const SmallVector& sv );
108  inline SmallVector( SmallVector&& sv );
110  //**********************************************************************************************
111 
112  //**Destructor**********************************************************************************
115  inline ~SmallVector();
117  //**********************************************************************************************
118 
119  //**Data access functions***********************************************************************
122  inline Reference operator[]( size_t index ) noexcept;
123  inline ConstReference operator[]( size_t index ) const noexcept;
124  inline Reference at( size_t index );
125  inline ConstReference at( size_t index ) const;
126  inline Pointer data() noexcept;
127  inline ConstPointer data() const noexcept;
128  inline Iterator begin () noexcept;
129  inline ConstIterator begin () const noexcept;
130  inline ConstIterator cbegin() const noexcept;
131  inline Iterator end () noexcept;
132  inline ConstIterator end () const noexcept;
133  inline ConstIterator cend () const noexcept;
135  //**********************************************************************************************
136 
137  //**Assignment operators************************************************************************
140  template< typename U >
141  inline SmallVector& operator=( initializer_list<U> list );
142 
143  inline SmallVector& operator=( const SmallVector& rhs );
144  inline SmallVector& operator=( SmallVector&& rhs );
146  //**********************************************************************************************
147 
148  //**Utility functions***************************************************************************
151  inline bool empty() const noexcept;
152  inline size_t size() const noexcept;
153  inline size_t capacity() const noexcept;
154 
155  inline void clear();
156  void resize( size_t n );
157  void resize( size_t n, const T& value );
158  void reserve( size_t n );
159  void shrinkToFit();
160  void pushBack( const T& value );
161  void pushBack( T&& value );
162  Iterator insert( Iterator pos, const T& value );
163  Iterator insert( Iterator pos, T&& value );
164  Iterator erase( Iterator pos );
165  Iterator erase( Iterator first, Iterator last );
166  void swap( SmallVector& sv ) noexcept( IsNothrowMoveConstructible<T>::value );
168  //**********************************************************************************************
169 
170  private:
171  //**Uninitialized struct definition*************************************************************
174  struct Uninitialized {};
175  //**********************************************************************************************
176 
177  //**Constructors********************************************************************************
180  explicit inline SmallVector( size_t n, const A& alloc, Uninitialized );
182  //**********************************************************************************************
183 
184  //**Utility functions***************************************************************************
187  using A::allocate;
188  using A::deallocate;
189 
190  inline bool isDynamic() const noexcept;
192  //**********************************************************************************************
193 
194  //**********************************************************************************************
196  enum : size_t { NN = N > 0UL ? N*sizeof(T) : 1UL };
197  //**********************************************************************************************
198 
199  //**Member variables****************************************************************************
202  alignas( AlignmentOf<T>::value ) byte_t v_[NN];
203 
204  T* begin_;
205  T* end_;
206  T* final_;
207 
208  //**********************************************************************************************
209 
210  //**Compile time checks*************************************************************************
215  //**********************************************************************************************
216 };
217 //*************************************************************************************************
218 
219 
220 
221 
222 //=================================================================================================
223 //
224 // CONSTRUCTORS
225 //
226 //=================================================================================================
227 
228 //*************************************************************************************************
233 template< typename T // Data type of the elements
234  , size_t N // Number of preallocated elements
235  , typename A > // Type of the allocator
236 inline SmallVector<T,N,A>::SmallVector( const A& alloc )
237  : SmallVector( 0UL, alloc, Uninitialized() )
238 {}
239 //*************************************************************************************************
240 
241 
242 //*************************************************************************************************
248 template< typename T // Data type of the elements
249  , size_t N // Number of preallocated elements
250  , typename A > // Type of the allocator
251 inline SmallVector<T,N,A>::SmallVector( size_t n, const A& alloc )
252  : SmallVector( n, alloc, Uninitialized() )
253 {
254  std::uninitialized_fill( begin_, end_, T() );
255 }
256 //*************************************************************************************************
257 
258 
259 //*************************************************************************************************
268 template< typename T // Data type of the elements
269  , size_t N // Number of preallocated elements
270  , typename A > // Type of the allocator
271 inline SmallVector<T,N,A>::SmallVector( size_t n, const T& init, const A& alloc )
272  : SmallVector( n, alloc, Uninitialized() )
273 {
274  std::uninitialized_fill( begin_, end_, init );
275 }
276 //*************************************************************************************************
277 
278 
279 //*************************************************************************************************
286 template< typename T // Data type of the elements
287  , size_t N // Number of preallocated elements
288  , typename A > // Type of the allocator
289 template< typename InputIt > // Type of the iterators
290 inline SmallVector<T,N,A>::SmallVector( InputIt first, InputIt last, const A& alloc )
291  : SmallVector( std::distance( first, last ), alloc, Uninitialized() )
292 {
293  std::uninitialized_copy( first, last, begin_ );
294 }
295 //*************************************************************************************************
296 
297 
298 //*************************************************************************************************
314 template< typename T // Data type of the elements
315  , size_t N // Number of preallocated elements
316  , typename A > // Type of the allocator
317 template< typename U > // Type of the initializer list elements
319  : SmallVector( list.size(), alloc, Uninitialized() )
320 {
321  std::uninitialized_copy( list.begin(), list.end(), begin_ );
322 }
323 //*************************************************************************************************
324 
325 
326 //*************************************************************************************************
331 template< typename T // Data type of the elements
332  , size_t N // Number of preallocated elements
333  , typename A > // Type of the allocator
335  : SmallVector( sv.size(), A(), Uninitialized() )
336 {
337  std::uninitialized_copy( sv.begin(), sv.end(), begin_ );
338 }
339 //*************************************************************************************************
340 
341 
342 //*************************************************************************************************
347 template< typename T // Data type of the elements
348  , size_t N // Number of preallocated elements
349  , typename A > // Type of the allocator
351  // arr_ is intentionally not initialized
352  : A () // Base class initialization
353  , begin_( sv.begin_ ) // Pointer to the beginning of the currently used storage
354  , end_ ( sv.end_ ) // Pointer to the end of the currently used storage
355  , final_( sv.final_ ) // Pointer to the very end of the currently used storage
356 {
357  if( !sv.isDynamic() ) {
358  begin_ = reinterpret_cast<T*>( v_ );
359  end_ = begin_ + sv.size();
360  final_ = begin_ + N;
361  uninitialized_move( sv.begin(), sv.end(), begin_ );
362  }
363 
364  sv.begin_ = reinterpret_cast<T*>( sv.v_ );
365  sv.end_ = sv.begin_;
366  sv.final_ = sv.begin_ + N;
367 }
368 //*************************************************************************************************
369 
370 
371 //*************************************************************************************************
377 template< typename T // Data type of the elements
378  , size_t N // Number of preallocated elements
379  , typename A > // Type of the allocator
380 inline SmallVector<T,N,A>::SmallVector( size_t n, const A& alloc, Uninitialized )
381  // v_ is intentionally not initialized
382  // begin_ is intentionally not initialized
383  // end_ is intentionally not initialized
384  // final_ is intentionally not initialized
385  : A( alloc ) // Base class initialization
386 {
387  if( n <= N ) {
388  begin_ = reinterpret_cast<T*>( v_ );
389  end_ = begin_ + n;
390  final_ = begin_ + N;
391  }
392  else {
393  begin_ = allocate( n );
394  end_ = begin_ + n;
395  final_ = begin_ + n;
396  }
397 }
398 //*************************************************************************************************
399 
400 
401 
402 
403 //=================================================================================================
404 //
405 // DESTRUCTOR
406 //
407 //=================================================================================================
408 
409 //*************************************************************************************************
412 template< typename T // Data type of the elements
413  , size_t N // Number of preallocated elements
414  , typename A > // Type of the allocator
416 {
417  using blaze::destroy;
418 
419  destroy( begin_, end_ );
420 
421  if( isDynamic() ) {
422  deallocate( begin_, capacity() );
423  }
424 }
425 //*************************************************************************************************
426 
427 
428 
429 
430 
431 //=================================================================================================
432 //
433 // DATA ACCESS FUNCTIONS
434 //
435 //=================================================================================================
436 
437 //*************************************************************************************************
446 template< typename T // Data type of the elements
447  , size_t N // Number of preallocated elements
448  , typename A > // Type of the allocator
449 inline typename SmallVector<T,N,A>::Reference
450  SmallVector<T,N,A>::operator[]( size_t index ) noexcept
451 {
452  BLAZE_USER_ASSERT( index < size(), "Invalid small vector access index" );
453  return begin_[index];
454 }
455 //*************************************************************************************************
456 
457 
458 //*************************************************************************************************
467 template< typename T // Data type of the elements
468  , size_t N // Number of preallocated elements
469  , typename A > // Type of the allocator
471  SmallVector<T,N,A>::operator[]( size_t index ) const noexcept
472 {
473  BLAZE_USER_ASSERT( index < size(), "Invalid small vector access index" );
474  return begin_[index];
475 }
476 //*************************************************************************************************
477 
478 
479 //*************************************************************************************************
489 template< typename T // Data type of the elements
490  , size_t N // Number of preallocated elements
491  , typename A > // Type of the allocator
492 inline typename SmallVector<T,N,A>::Reference
493  SmallVector<T,N,A>::at( size_t index )
494 {
495  if( index >= size() ) {
496  BLAZE_THROW_OUT_OF_RANGE( "Invalid small vector access index" );
497  }
498  return begin_[index];
499 }
500 //*************************************************************************************************
501 
502 
503 //*************************************************************************************************
513 template< typename T // Data type of the elements
514  , size_t N // Number of preallocated elements
515  , typename A > // Type of the allocator
517  SmallVector<T,N,A>::at( size_t index ) const
518 {
519  if( index >= size() ) {
520  BLAZE_THROW_OUT_OF_RANGE( "Invalid small vector access index" );
521  }
522  return begin_[index];
523 }
524 //*************************************************************************************************
525 
526 
527 //*************************************************************************************************
534 template< typename T // Data type of the elements
535  , size_t N // Number of preallocated elements
536  , typename A > // Type of the allocator
537 inline typename SmallVector<T,N,A>::Pointer
539 {
540  return begin_;
541 }
542 //*************************************************************************************************
543 
544 
545 //*************************************************************************************************
552 template< typename T // Data type of the elements
553  , size_t N // Number of preallocated elements
554  , typename A > // Type of the allocator
555 inline typename SmallVector<T,N,A>::ConstPointer
556  SmallVector<T,N,A>::data() const noexcept
557 {
558  return begin_;
559 }
560 //*************************************************************************************************
561 
562 
563 //*************************************************************************************************
568 template< typename T // Data type of the elements
569  , size_t N // Number of preallocated elements
570  , typename A > // Type of the allocator
571 inline typename SmallVector<T,N,A>::Iterator
573 {
574  return begin_;
575 }
576 //*************************************************************************************************
577 
578 
579 //*************************************************************************************************
584 template< typename T // Data type of the elements
585  , size_t N // Number of preallocated elements
586  , typename A > // Type of the allocator
587 inline typename SmallVector<T,N,A>::ConstIterator
588  SmallVector<T,N,A>::begin() const noexcept
589 {
590  return begin_;
591 }
592 //*************************************************************************************************
593 
594 
595 //*************************************************************************************************
600 template< typename T // Data type of the elements
601  , size_t N // Number of preallocated elements
602  , typename A > // Type of the allocator
603 inline typename SmallVector<T,N,A>::ConstIterator
604  SmallVector<T,N,A>::cbegin() const noexcept
605 {
606  return begin_;
607 }
608 //*************************************************************************************************
609 
610 
611 //*************************************************************************************************
616 template< typename T // Data type of the elements
617  , size_t N // Number of preallocated elements
618  , typename A > // Type of the allocator
619 inline typename SmallVector<T,N,A>::Iterator
621 {
622  return end_;
623 }
624 //*************************************************************************************************
625 
626 
627 //*************************************************************************************************
632 template< typename T // Data type of the elements
633  , size_t N // Number of preallocated elements
634  , typename A > // Type of the allocator
635 inline typename SmallVector<T,N,A>::ConstIterator
636  SmallVector<T,N,A>::end() const noexcept
637 {
638  return end_;
639 }
640 //*************************************************************************************************
641 
642 
643 //*************************************************************************************************
648 template< typename T // Data type of the elements
649  , size_t N // Number of preallocated elements
650  , typename A > // Type of the allocator
651 inline typename SmallVector<T,N,A>::ConstIterator
652  SmallVector<T,N,A>::cend() const noexcept
653 {
654  return end_;
655 }
656 //*************************************************************************************************
657 
658 
659 
660 
661 //=================================================================================================
662 //
663 // ASSIGNMENT OPERATORS
664 //
665 //=================================================================================================
666 
667 //*************************************************************************************************
683 template< typename T // Data type of the elements
684  , size_t N // Number of preallocated elements
685  , typename A > // Type of the allocator
686 template< typename U > // Type of the initializer list elements
688 {
689  resize( list.size() );
690  std::copy( list.begin(), list.end(), begin_ );
691 
692  return *this;
693 }
694 //*************************************************************************************************
695 
696 
697 //*************************************************************************************************
706 template< typename T // Data type of the elements
707  , size_t N // Number of preallocated elements
708  , typename A > // Type of the allocator
710 {
711  resize( rhs.size() );
712  std::copy( rhs.begin(), rhs.end(), begin_ );
713 
714  return *this;
715 }
716 //*************************************************************************************************
717 
718 
719 //*************************************************************************************************
725 template< typename T // Data type of the elements
726  , size_t N // Number of preallocated elements
727  , typename A > // Type of the allocator
729 {
730  resize( rhs.size() );
731  std::move( rhs.begin(), rhs.end(), begin_ );
732 
733  return *this;
734 }
735 //*************************************************************************************************
736 
737 
738 
739 
740 //=================================================================================================
741 //
742 // UTILITY FUNCTIONS
743 //
744 //=================================================================================================
745 
746 //*************************************************************************************************
751 template< typename T // Data type of the elements
752  , size_t N // Number of preallocated elements
753  , typename A > // Type of the allocator
754 inline bool SmallVector<T,N,A>::empty() const noexcept
755 {
756  return begin_ == end_;
757 }
758 //*************************************************************************************************
759 
760 
761 //*************************************************************************************************
766 template< typename T // Data type of the elements
767  , size_t N // Number of preallocated elements
768  , typename A > // Type of the allocator
769 inline size_t SmallVector<T,N,A>::size() const noexcept
770 {
771  return end_ - begin_;
772 }
773 //*************************************************************************************************
774 
775 
776 //*************************************************************************************************
781 template< typename T // Data type of the elements
782  , size_t N // Number of preallocated elements
783  , typename A > // Type of the allocator
784 inline size_t SmallVector<T,N,A>::capacity() const noexcept
785 {
786  return final_ - begin_;
787 }
788 //*************************************************************************************************
789 
790 
791 //*************************************************************************************************
798 template< typename T // Data type of the elements
799  , size_t N // Number of preallocated elements
800  , typename A > // Type of the allocator
802 {
803  using blaze::destroy;
804 
805  destroy( begin_, end_ );
806 
807  if( isDynamic() ) {
808  deallocate( begin_, capacity() );
809  }
810 
811  begin_ = reinterpret_cast<T*>( v_ );
812  end_ = begin_;
813  final_ = begin_ + N;
814 }
815 //*************************************************************************************************
816 
817 
818 //*************************************************************************************************
828 template< typename T // Data type of the elements
829  , size_t N // Number of preallocated elements
830  , typename A > // Type of the allocator
832 {
833  using blaze::destroy;
834 
835  if( n > size() )
836  {
837  reserve( n );
839  end_ = begin_ + n;
840  }
841  else if( n < size() )
842  {
843  destroy( begin_+size(), end_ );
844  end_ = begin_ + n;
845  }
846 }
847 //*************************************************************************************************
848 
849 
850 //*************************************************************************************************
861 template< typename T // Data type of the elements
862  , size_t N // Number of preallocated elements
863  , typename A > // Type of the allocator
864 void SmallVector<T,N,A>::resize( size_t n, const T& value )
865 {
866  using blaze::destroy;
867 
868  if( n > size() )
869  {
870  reserve( n );
871  std::uninitialized_fill( begin_+size(), begin_+n, value );
872  end_ = begin_ + n;
873  }
874  else if( n < size() )
875  {
876  destroy( begin_+size(), end_ );
877  end_ = begin_ + n;
878  }
879 }
880 //*************************************************************************************************
881 
882 
883 //*************************************************************************************************
892 template< typename T // Data type of the elements
893  , size_t N // Number of preallocated elements
894  , typename A > // Type of the allocator
896 {
897  using blaze::destroy;
898 
899  const size_t oldCapacity( capacity() );
900 
901  if( n > oldCapacity )
902  {
903  const size_t oldSize( size() );
904  T* tmp( allocate( n ) );
905 
907  uninitialized_move( begin_, end_, tmp );
908  }
909  else {
910  std::uninitialized_copy( begin_, end_, tmp );
911  }
912 
913  destroy( begin_, end_ );
914 
915  if( isDynamic() ) {
916  deallocate( begin_, oldCapacity );
917  }
918 
919  final_ = tmp + n;
920  end_ = tmp + oldSize;
921  begin_ = tmp;
922  }
923 }
924 //*************************************************************************************************
925 
926 
927 //*************************************************************************************************
936 template< typename T // Data type of the elements
937  , size_t N // Number of preallocated elements
938  , typename A > // Type of the allocator
940 {
941  using blaze::destroy;
942 
943  const size_t oldCapacity( capacity() );
944  const size_t oldSize ( size() );
945 
946  if( isDynamic() && oldCapacity > oldSize )
947  {
948  T* tmp( allocate( oldSize ) );
949 
951  uninitialized_move( begin_, end_, tmp );
952  }
953  else {
954  std::uninitialized_copy( begin_, end_, tmp );
955  }
956 
957  destroy( begin_, end_ );
958  deallocate( begin_, oldCapacity );
959 
960  final_ = tmp + oldSize;
961  end_ = final_;
962  begin_ = tmp;
963  }
964 }
965 //*************************************************************************************************
966 
967 
968 //*************************************************************************************************
974 template< typename T // Data type of the elements
975  , size_t N // Number of preallocated elements
976  , typename A > // Type of the allocator
977 void SmallVector<T,N,A>::pushBack( const T& value )
978 {
979  using blaze::max;
980 
981  const size_t oldCapacity( capacity() );
982 
983  if( size() == oldCapacity ) {
984  reserve( max( 2UL*oldCapacity, 7UL ) );
985  }
986 
987  ::new ( end_ ) T( value );
988  ++end_;
989 }
990 //*************************************************************************************************
991 
992 
993 //*************************************************************************************************
999 template< typename T // Data type of the elements
1000  , size_t N // Number of preallocated elements
1001  , typename A > // Type of the allocator
1003 {
1004  using blaze::max;
1005 
1006  const size_t oldCapacity( capacity() );
1007 
1008  if( size() == oldCapacity ) {
1009  reserve( max( 2UL*oldCapacity, 7UL ) );
1010  }
1011 
1012  ::new ( end_ ) T( std::move( value ) );
1013  ++end_;
1014 }
1015 //*************************************************************************************************
1016 
1017 
1018 //*************************************************************************************************
1025 template< typename T // Data type of the elements
1026  , size_t N // Number of preallocated elements
1027  , typename A > // Type of the allocator
1029  SmallVector<T,N,A>::insert( Iterator pos, const T& value )
1030 {
1031  using blaze::destroy;
1032 
1033  const size_t oldCapacity( capacity() );
1034  const size_t oldSize ( size() );
1035 
1036  if( oldSize == oldCapacity )
1037  {
1038  const size_t newCapacity( 2UL*oldCapacity );
1039  const size_t index( pos - begin_ );
1040 
1041  T* tmp ( allocate( newCapacity ) );
1042  T* newpos( tmp + index );
1043 
1044  uninitialized_move( begin_, pos, tmp );
1045  ::new ( newpos ) T( value );
1046  uninitialized_move( pos, end_, tmp+index+1UL );
1047  destroy( begin_, end_ );
1048 
1049  if( isDynamic() ) {
1050  deallocate( begin_, capacity() );
1051  }
1052 
1053  final_ = tmp + newCapacity;
1054  end_ = tmp + oldSize + 1UL;
1055  begin_ = tmp;
1056 
1057  return newpos;
1058  }
1059  else if( pos == end_ )
1060  {
1061  ::new( pos ) T( value );
1062  ++end_;
1063  return pos;
1064  }
1065  else
1066  {
1067  const auto tmp( end_ - 1UL );
1068  ::new ( end_ ) T( std::move( *tmp ) );
1069 
1070  try {
1071  std::move_backward( pos, tmp, end_ );
1072  destroy_at( pos );
1073  ::new ( pos ) T( value );
1074  ++end_;
1075  }
1076  catch( ... ) {
1077  destroy_at( end_ );
1078  throw;
1079  }
1080 
1081  return pos;
1082  }
1083 }
1084 //*************************************************************************************************
1085 
1086 
1087 //*************************************************************************************************
1094 template< typename T // Data type of the elements
1095  , size_t N // Number of preallocated elements
1096  , typename A > // Type of the allocator
1099 {
1100  using blaze::destroy;
1101 
1102  const size_t oldCapacity( capacity() );
1103  const size_t oldSize ( size() );
1104 
1105  if( oldSize == oldCapacity )
1106  {
1107  const size_t newCapacity( 2UL*oldCapacity );
1108  const size_t index( pos - begin_ );
1109 
1110  T* tmp ( allocate( newCapacity ) );
1111  T* newpos( tmp + index );
1112 
1113  uninitialized_move( begin_, pos, tmp );
1114  ::new ( newpos ) T( std::move( value ) );
1115  uninitialized_move( pos, end_, tmp+index+1UL );
1116  destroy( begin_, end_ );
1117 
1118  if( isDynamic() ) {
1119  deallocate( begin_, capacity() );
1120  }
1121 
1122  final_ = tmp + newCapacity;
1123  end_ = tmp + oldSize + 1UL;
1124  begin_ = tmp;
1125 
1126  return newpos;
1127  }
1128  else if( pos == end_ )
1129  {
1130  ::new( pos ) T( std::move( value ) );
1131  ++end_;
1132  return pos;
1133  }
1134  else
1135  {
1136  const auto tmp( end_ - 1UL );
1137  ::new ( end_ ) T( std::move( *tmp ) );
1138 
1139  try {
1140  std::move_backward( pos, tmp, end_ );
1141  destroy_at( pos );
1142  ::new ( pos ) T( std::move( value ) );
1143  ++end_;
1144  }
1145  catch( ... ) {
1146  destroy_at( end_ );
1147  throw;
1148  }
1149 
1150  return pos;
1151  }
1152 }
1153 //*************************************************************************************************
1154 
1155 
1156 //*************************************************************************************************
1164 template< typename T // Data type of the elements
1165  , size_t N // Number of preallocated elements
1166  , typename A > // Type of the allocator
1169 {
1170  std::move( pos+1UL, end_, pos );
1171  --end_;
1172  destroy_at( end_ );
1173 
1174  return pos;
1175 }
1176 //*************************************************************************************************
1177 
1178 
1179 //*************************************************************************************************
1188 template< typename T // Data type of the elements
1189  , size_t N // Number of preallocated elements
1190  , typename A > // Type of the allocator
1193 {
1194  using blaze::destroy;
1195 
1196  BLAZE_USER_ASSERT( first <= last, "Invalid range detected" );
1197 
1198  const size_t n( last - first );
1199 
1200  std::move( last, end_, first );
1201  end_ -= n;
1202  destroy( end_, end_+n );
1203 
1204  return first;
1205 }
1206 //*************************************************************************************************
1207 
1208 
1209 //*************************************************************************************************
1219 template< typename T // Data type of the elements
1220  , size_t N // Number of preallocated elements
1221  , typename A > // Type of the allocator
1223 {
1224  using std::swap;
1225  using blaze::destroy;
1226 
1227  if( isDynamic() && sv.isDynamic() )
1228  {
1229  swap( begin_, sv.begin_ );
1230  swap( end_ , sv.end_ );
1231  swap( final_, sv.final_ );
1232  }
1233  else if( isDynamic() )
1234  {
1235  const size_t n( sv.size() );
1236 
1237  uninitialized_move( sv.begin_, sv.end_, reinterpret_cast<T*>( v_ ) );
1238  destroy( sv.begin_, sv.end_ );
1239 
1240  sv.begin_ = begin_;
1241  sv.end_ = end_;
1242  sv.final_ = final_;
1243 
1244  begin_ = reinterpret_cast<T*>( v_ );
1245  end_ = begin_ + n;
1246  final_ = begin_ + N;
1247  }
1248  else if( sv.isDynamic() )
1249  {
1250  const size_t n( size() );
1251 
1252  uninitialized_move( begin_, end_, reinterpret_cast<T*>( sv.v_ ) );
1253  destroy( begin_, end_ );
1254 
1255  begin_ = sv.begin_;
1256  end_ = sv.end_;
1257  final_ = sv.final_;
1258 
1259  sv.begin_ = reinterpret_cast<T*>( sv.v_ );
1260  sv.end_ = sv.begin_ + n;
1261  sv.final_ = sv.begin_ + N;
1262  }
1263  else if( size() > sv.size() )
1264  {
1265  const size_t n( size() - sv.size() );
1266  const auto pos = std::swap_ranges( sv.begin_, sv.end_, begin_ );
1267 
1268  uninitialized_move( pos, end_, sv.end_ );
1269  destroy( pos, end_ );
1270  end_ -= n;
1271  sv.end_ += n;
1272  }
1273  else
1274  {
1275  const size_t n( sv.size() - size() );
1276  const auto pos = std::swap_ranges( begin_, end_, sv.begin_ );
1277 
1278  uninitialized_move( pos, sv.end_, end_ );
1279  destroy( pos, sv.end_ );
1280  end_ += n;
1281  sv.end_ -= n;
1282  }
1283 }
1284 //*************************************************************************************************
1285 
1286 
1287 //*************************************************************************************************
1292 template< typename T // Data type of the elements
1293  , size_t N // Number of preallocated elements
1294  , typename A > // Type of the allocator
1295 inline bool SmallVector<T,N,A>::isDynamic() const noexcept
1296 {
1297  return begin_ != reinterpret_cast<const T*>( v_ );
1298 }
1299 //*************************************************************************************************
1300 
1301 
1302 
1303 
1304 //=================================================================================================
1305 //
1306 // SMALLVECTOR OPERATORS
1307 //
1308 //=================================================================================================
1309 
1310 //*************************************************************************************************
1313 template< typename T1, size_t N1, typename A1, typename T2, size_t N2, typename A2 >
1314 inline bool operator==( const SmallVector<T1,N1,A1>& lhs, const SmallVector<T2,N2,A2>& rhs );
1315 
1316 template< typename T1, size_t N1, typename A1, typename T2, size_t N2, typename A2 >
1317 inline bool operator!=( const SmallVector<T1,N1,A1>& lhs, const SmallVector<T2,N2,A2>& rhs );
1318 
1319 template< typename T, size_t N, typename A >
1321 
1322 template< typename T, size_t N, typename A >
1323 inline typename SmallVector<T,N,A>::ConstIterator begin( const SmallVector<T,N,A>& sv );
1324 
1325 template< typename T, size_t N, typename A >
1326 inline typename SmallVector<T,N,A>::ConstIterator cbegin( const SmallVector<T,N,A>& sv );
1327 
1328 template< typename T, size_t N, typename A >
1329 inline typename SmallVector<T,N,A>::Iterator end( SmallVector<T,N,A>& sv );
1330 
1331 template< typename T, size_t N, typename A >
1332 inline typename SmallVector<T,N,A>::ConstIterator end( const SmallVector<T,N,A>& sv );
1333 
1334 template< typename T, size_t N, typename A >
1335 inline typename SmallVector<T,N,A>::ConstIterator cend( const SmallVector<T,N,A>& sv );
1336 
1337 template< typename T, size_t N, typename A >
1338 inline void clear( SmallVector<T,N,A>& sv );
1339 
1340 template< typename T, size_t N, typename A >
1341 inline void swap( SmallVector<T,N,A>& a, SmallVector<T,N,A>& b )
1344 //*************************************************************************************************
1345 
1346 
1347 //*************************************************************************************************
1355 template< typename T1 // Data type of the elements of the left-hand side vector
1356  , size_t N1 // Number of elements of the left-hand side vector
1357  , typename A1 // Type of the allocator of the left-hand side vector
1358  , typename T2 // Data type of the elements of the right-hand side vector
1359  , size_t N2 // Number of elements of the right-hand side vector
1360  , typename A2 > // Type of the allocator of the right-hand side vector
1361 inline bool operator==( const SmallVector<T1,N1,A1>& lhs, const SmallVector<T2,N2,A2>& rhs )
1362 {
1363  if( lhs.size() != rhs.size() ) return false;
1364 
1365  return std::equal( lhs.begin(), lhs.end(), rhs.begin() );
1366 }
1367 //*************************************************************************************************
1368 
1369 
1370 //*************************************************************************************************
1378 template< typename T1 // Data type of the elements of the left-hand side vector
1379  , size_t N1 // Number of elements of the left-hand side vector
1380  , typename A1 // Type of the allocator of the left-hand side vector
1381  , typename T2 // Data type of the elements of the right-hand side vector
1382  , size_t N2 // Number of elements of the right-hand side vector
1383  , typename A2 > // Type of the allocator of the right-hand side vector
1384 inline bool operator!=( const SmallVector<T1,N1,A1>& lhs, const SmallVector<T2,N2,A2>& rhs )
1385 {
1386  return !( lhs == rhs );
1387 }
1388 //*************************************************************************************************
1389 
1390 
1391 //*************************************************************************************************
1398 template< typename T, size_t N, typename A >
1400 {
1401  return sv.begin();
1402 }
1403 //*************************************************************************************************
1404 
1405 
1406 //*************************************************************************************************
1413 template< typename T, size_t N, typename A >
1415 {
1416  return sv.begin();
1417 }
1418 //*************************************************************************************************
1419 
1420 
1421 //*************************************************************************************************
1428 template< typename T, size_t N, typename A >
1430 {
1431  return sv.begin();
1432 }
1433 //*************************************************************************************************
1434 
1435 
1436 //*************************************************************************************************
1443 template< typename T, size_t N, typename A >
1445 {
1446  return sv.end();
1447 }
1448 //*************************************************************************************************
1449 
1450 
1451 //*************************************************************************************************
1458 template< typename T, size_t N, typename A >
1460 {
1461  return sv.end();
1462 }
1463 //*************************************************************************************************
1464 
1465 
1466 //*************************************************************************************************
1473 template< typename T, size_t N, typename A >
1475 {
1476  return sv.end();
1477 }
1478 //*************************************************************************************************
1479 
1480 
1481 //*************************************************************************************************
1488 template< typename T // Data type of the elements
1489  , size_t N // Number of preallocated elements
1490  , typename A > // Type of the allocator
1491 inline void clear( SmallVector<T,N,A>& sv )
1492 {
1493  sv.clear();
1494 }
1495 //*************************************************************************************************
1496 
1497 
1498 //*************************************************************************************************
1510 template< typename T // Data type of the elements
1511  , size_t N // Number of preallocated elements
1512  , typename A > // Type of the allocator
1515 {
1516  a.swap( b );
1517 }
1518 //*************************************************************************************************
1519 
1520 } // namespace blaze
1521 
1522 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
Headerfile for the generic destroy algorithm.
T * begin_
Pointer to the beginning of the currently used storage.
Definition: SmallVector.h:204
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the AlignmentOf type trait.
byte_t v_[NN]
The static storage.
Definition: SmallVector.h:202
Header file for basic type definitions.
const T & ConstReference
Reference to a constant vector element.
Definition: SmallVector.h:89
constexpr bool equal(const T1 &a, const T2 &b)
Generic equality check.
Definition: Equal.h:76
unsigned char byte_t
Byte data type of the Blaze library.The byte data type is guaranteed to be an integral data type of s...
Definition: Types.h:79
void clear()
Clearing the vector.
Definition: SmallVector.h:801
Iterator end() noexcept
Returns an iterator just past the last element of the small vector.
Definition: SmallVector.h:620
Header file for exception macros.
T & Reference
Reference to a non-constant vector element.
Definition: SmallVector.h:88
Implementation of a dynamic vector with small vector optimization.The SmallVector class template is a...
Definition: SmallVector.h:80
bool isDynamic() const noexcept
Returns whether the small vector uses its dynamic storage.
Definition: SmallVector.h:1295
Reference at(size_t index)
Checked access to the vector elements.
Definition: SmallVector.h:493
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:79
bool empty() const noexcept
Returns whether the vector is empty.
Definition: SmallVector.h:754
T * Pointer
Pointer to a non-constant vector element.
Definition: SmallVector.h:86
STL namespace.
void resize(size_t n)
Changing the size of the vector.
Definition: SmallVector.h:831
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1950
T * Iterator
Iterator over non-constant elements.
Definition: SmallVector.h:90
EnableIf_< IsBuiltin< T >, T *> allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:155
Header file for the initializer_list template.
Pointer data() noexcept
Low-level data access to the vector elements.
Definition: SmallVector.h:538
Headerfile for the generic max algorithm.
~SmallVector()
The destructor for DynamicVector.
Definition: SmallVector.h:415
Headerfile for the generic uninitialized_default_construct algorithm.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5908
T ElementType
Type of the vector elements.
Definition: SmallVector.h:85
Headerfile for the generic destroy_at algorithm.
Headerfile for the generic uninitialized_move algorithm.
Reference operator[](size_t index) noexcept
Subscript operator for the direct access to the vector elements.
Definition: SmallVector.h:450
ForwardIt uninitialized_move(InputIt first, InputIt last, ForwardIt dest)
Move the elements from the given source range to the uninitialized destination range.
Definition: UninitializedMove.h:70
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Constraint on the data type.
size_t capacity() const noexcept
Returns the maximum capacity of the small vector.
Definition: SmallVector.h:784
Header file for the IsConstructible type trait.
T * end_
Pointer to the end of the currently used storage.
Definition: SmallVector.h:205
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: SmallVector.h:939
Definition of the nested auxiliary struct Uninitialized.
Definition: SmallVector.h:174
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
void destroy(ForwardIt first, ForwardIt last)
Destroys the given range of objects .
Definition: Destroy.h:66
void swap(SmallVector &sv) noexcept(IsNothrowMoveConstructible< T >::value)
Swapping the contents of two small vectors.
Definition: SmallVector.h:1222
Header file for run time assertion macros.
Constraint on the data type.
ConstIterator cend() const noexcept
Returns an iterator just past the last element of the small vector.
Definition: SmallVector.h:652
const T * ConstIterator
Iterator over constant elements.
Definition: SmallVector.h:91
size_t size() const noexcept
Returns the current size/dimension of the small vector.
Definition: SmallVector.h:769
void reserve(size_t n)
Setting the minimum capacity of the vector.
Definition: SmallVector.h:895
const T * ConstPointer
Pointer to a constant vector element.
Definition: SmallVector.h:87
Header file for the IsAssignable type trait.
SmallVector(const A &alloc=A())
The (default) constructor for SmallVector.
Definition: SmallVector.h:236
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
Compile time type check.The IsNothrowMoveConstructible type trait tests whether the expression...
Definition: IsConstructible.h:281
T * final_
Pointer to the very end of the currently used storage.
Definition: SmallVector.h:206
void uninitialized_default_construct(ForwardIt first, ForwardIt last)
Default constructs elements in the given range.
Definition: UninitializedDefaultConstruct.h:67
Iterator erase(Iterator pos)
Erasing an element from the small vector.
Definition: SmallVector.h:1168
ConstIterator cbegin() const noexcept
Returns an iterator to the first element of the small vector.
Definition: SmallVector.h:604
Initializer list type of the Blaze library.
Iterator begin() noexcept
Returns an iterator to the first element of the small vector.
Definition: SmallVector.h:572
void destroy_at(T *p) noexcept
Destroys the object at the given address.
Definition: DestroyAt.h:57
void pushBack(const T &value)
Adding an element to the end of the small vector.
Definition: SmallVector.h:977
Evaluation of the required alignment of the given data type.The AlignmentOf type trait template evalu...
Definition: AlignmentOf.h:219
Iterator insert(Iterator pos, const T &value)
Inserting an element at the specified position into the small vector.
Definition: SmallVector.h:1029