Blaze 3.9
SmallArray.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_UTIL_SMALLARRAY_H_
36#define _BLAZE_UTIL_SMALLARRAY_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <algorithm>
44#include <iterator>
45#include <memory>
51#include <blaze/util/Assert.h>
57#include <blaze/util/Types.h>
60
61
62namespace blaze {
63
64//=================================================================================================
65//
66// CLASS DEFINITION
67//
68//=================================================================================================
69
70//*************************************************************************************************
78template< typename T // Data type of the elements
79 , size_t N // Number of preallocated elements
80 , typename A = std::allocator<T> > // Type of the allocator
82 : private SmallArrayData<T,N>
83 , private A
84{
85 public:
86 //**Type definitions****************************************************************************
87 using ElementType = T;
88 using Pointer = T*;
89 using ConstPointer = const T*;
90 using Reference = T&;
91 using ConstReference = const T&;
92 using Iterator = T*;
93 using ConstIterator = const T*;
94 //**********************************************************************************************
95
96 //**Constructors********************************************************************************
99 explicit inline SmallArray( const A& alloc = A() );
100 explicit inline SmallArray( size_t n, const A& alloc = A() );
101 inline SmallArray( size_t n, const T& init, const A& alloc = A() );
102
103 template< typename InputIt >
104 inline SmallArray( InputIt first, InputIt last, const A& alloc = A() );
105
106 template< typename U >
107 inline SmallArray( initializer_list<U> list, const A& alloc = A() );
108
109 inline SmallArray( const SmallArray& sa );
110 inline SmallArray( SmallArray&& sa );
112 //**********************************************************************************************
113
114 //**Destructor**********************************************************************************
117 inline ~SmallArray();
119 //**********************************************************************************************
120
121 //**Data access functions***********************************************************************
124 inline Reference operator[]( size_t index ) noexcept;
125 inline ConstReference operator[]( size_t index ) const noexcept;
126 inline Reference at( size_t index );
127 inline ConstReference at( size_t index ) const;
128 inline Pointer data() noexcept;
129 inline ConstPointer data() const noexcept;
130 inline Iterator begin () noexcept;
131 inline ConstIterator begin () const noexcept;
132 inline ConstIterator cbegin() const noexcept;
133 inline Iterator end () noexcept;
134 inline ConstIterator end () const noexcept;
135 inline ConstIterator cend () const noexcept;
137 //**********************************************************************************************
138
139 //**Assignment operators************************************************************************
142 template< typename U >
143 inline SmallArray& operator=( initializer_list<U> list );
144
145 inline SmallArray& operator=( const SmallArray& rhs );
146 inline SmallArray& operator=( SmallArray&& rhs );
148 //**********************************************************************************************
149
150 //**Utility functions***************************************************************************
153 inline bool empty() const noexcept;
154 inline size_t size() const noexcept;
155 inline size_t capacity() const noexcept;
156
157 inline void clear();
158 void resize( size_t n );
159 void resize( size_t n, const T& value );
160 void reserve( size_t n );
161 void shrinkToFit();
162 void pushBack( const T& value );
163 void pushBack( T&& value );
164 Iterator insert( Iterator pos, const T& value );
165 Iterator insert( Iterator pos, T&& value );
166 Iterator erase( Iterator pos );
167 Iterator erase( Iterator first, Iterator last );
168 void swap( SmallArray& sa ) noexcept( IsNothrowMoveConstructible_v<T> );
170 //**********************************************************************************************
171
172 private:
173 //**Uninitialized struct definition*************************************************************
176 struct Uninitialized {};
177 //**********************************************************************************************
178
179 //**Constructors********************************************************************************
182 inline SmallArray( size_t n, const A& alloc, Uninitialized );
184 //**********************************************************************************************
185
186 //**Utility functions***************************************************************************
189 using A::allocate;
190 using A::deallocate;
191
192 inline bool isDynamic() const noexcept;
194 //**********************************************************************************************
195
196 //**Member variables****************************************************************************
200 T* end_;
203 //**********************************************************************************************
204
205 //**Compile time checks*************************************************************************
210 //**********************************************************************************************
211};
212//*************************************************************************************************
213
214
215
216
217//=================================================================================================
218//
219// CONSTRUCTORS
220//
221//=================================================================================================
222
223//*************************************************************************************************
228template< typename T // Data type of the elements
229 , size_t N // Number of preallocated elements
230 , typename A > // Type of the allocator
231inline SmallArray<T,N,A>::SmallArray( const A& alloc )
232 : SmallArray( 0UL, alloc, Uninitialized() )
233{}
234//*************************************************************************************************
235
236
237//*************************************************************************************************
243template< typename T // Data type of the elements
244 , size_t N // Number of preallocated elements
245 , typename A > // Type of the allocator
246inline SmallArray<T,N,A>::SmallArray( size_t n, const A& alloc )
247 : SmallArray( n, alloc, Uninitialized() )
248{
249 std::uninitialized_fill( begin_, end_, T() );
250}
251//*************************************************************************************************
252
253
254//*************************************************************************************************
263template< typename T // Data type of the elements
264 , size_t N // Number of preallocated elements
265 , typename A > // Type of the allocator
266inline SmallArray<T,N,A>::SmallArray( size_t n, const T& init, const A& alloc )
267 : SmallArray( n, alloc, Uninitialized() )
268{
269 std::uninitialized_fill( begin_, end_, init );
270}
271//*************************************************************************************************
272
273
274//*************************************************************************************************
281template< typename T // Data type of the elements
282 , size_t N // Number of preallocated elements
283 , typename A > // Type of the allocator
284template< typename InputIt > // Type of the iterators
285inline SmallArray<T,N,A>::SmallArray( InputIt first, InputIt last, const A& alloc )
286 : SmallArray( std::distance( first, last ), alloc, Uninitialized() )
287{
288 std::uninitialized_copy( first, last, begin_ );
289}
290//*************************************************************************************************
291
292
293//*************************************************************************************************
309template< typename T // Data type of the elements
310 , size_t N // Number of preallocated elements
311 , typename A > // Type of the allocator
312template< typename U > // Type of the initializer list elements
313inline SmallArray<T,N,A>::SmallArray( initializer_list<U> list, const A& alloc )
314 : SmallArray( list.size(), alloc, Uninitialized() )
315{
316 std::uninitialized_copy( list.begin(), list.end(), begin_ );
317}
318//*************************************************************************************************
319
320
321//*************************************************************************************************
326template< typename T // Data type of the elements
327 , size_t N // Number of preallocated elements
328 , typename A > // Type of the allocator
330 : SmallArray( sa.size(), A(), Uninitialized() )
331{
332 std::uninitialized_copy( sa.begin(), sa.end(), begin_ );
333}
334//*************************************************************************************************
335
336
337//*************************************************************************************************
342template< typename T // Data type of the elements
343 , size_t N // Number of preallocated elements
344 , typename A > // Type of the allocator
346 // Base class initialization is intentionally omitted
347 : begin_( sa.begin_ ) // Pointer to the beginning of the currently used storage
348 , end_ ( sa.end_ ) // Pointer to the end of the currently used storage
349 , final_( sa.final_ ) // Pointer to the very end of the currently used storage
350{
351 if( !sa.isDynamic() ) {
352 begin_ = this->array();
353 end_ = begin_ + sa.size();
354 final_ = begin_ + N;
355 blaze::uninitialized_move( sa.begin_, sa.end_, begin_ );
356 blaze::destroy( sa.begin_, sa.end_ );
357 }
358
359 sa.begin_ = sa.array();
360 sa.end_ = sa.begin_;
361 sa.final_ = sa.begin_ + N;
362}
363//*************************************************************************************************
364
365
366//*************************************************************************************************
372template< typename T // Data type of the elements
373 , size_t N // Number of preallocated elements
374 , typename A > // Type of the allocator
375inline SmallArray<T,N,A>::SmallArray( size_t n, const A& alloc, Uninitialized )
376 // SmallArrayData is initialized
377 // begin_ is intentionally not initialized
378 // end_ is intentionally not initialized
379 // final_ is intentionally not initialized
380 : A( alloc ) // Base class initialization
381{
382 if( n <= N ) {
383 begin_ = this->array();
384 end_ = begin_ + n;
385 final_ = begin_ + N;
386 }
387 else {
388 begin_ = allocate( n );
389 end_ = begin_ + n;
390 final_ = begin_ + n;
391 }
392}
393//*************************************************************************************************
394
395
396
397
398//=================================================================================================
399//
400// DESTRUCTOR
401//
402//=================================================================================================
403
404//*************************************************************************************************
407template< typename T // Data type of the elements
408 , size_t N // Number of preallocated elements
409 , typename A > // Type of the allocator
411{
412 blaze::destroy( begin_, end_ );
413
414 if( isDynamic() ) {
415 deallocate( begin_, capacity() );
416 }
417}
418//*************************************************************************************************
419
420
421
422
423
424//=================================================================================================
425//
426// DATA ACCESS FUNCTIONS
427//
428//=================================================================================================
429
430//*************************************************************************************************
439template< typename T // Data type of the elements
440 , size_t N // Number of preallocated elements
441 , typename A > // Type of the allocator
442inline typename SmallArray<T,N,A>::Reference
443 SmallArray<T,N,A>::operator[]( size_t index ) noexcept
444{
445 BLAZE_USER_ASSERT( index < size(), "Invalid small array access index" );
446 return begin_[index];
447}
448//*************************************************************************************************
449
450
451//*************************************************************************************************
460template< typename T // Data type of the elements
461 , size_t N // Number of preallocated elements
462 , typename A > // Type of the allocator
464 SmallArray<T,N,A>::operator[]( size_t index ) const noexcept
465{
466 BLAZE_USER_ASSERT( index < size(), "Invalid small array access index" );
467 return begin_[index];
468}
469//*************************************************************************************************
470
471
472//*************************************************************************************************
482template< typename T // Data type of the elements
483 , size_t N // Number of preallocated elements
484 , typename A > // Type of the allocator
485inline typename SmallArray<T,N,A>::Reference
486 SmallArray<T,N,A>::at( size_t index )
487{
488 if( index >= size() ) {
489 BLAZE_THROW_OUT_OF_RANGE( "Invalid small array access index" );
490 }
491 return begin_[index];
492}
493//*************************************************************************************************
494
495
496//*************************************************************************************************
506template< typename T // Data type of the elements
507 , size_t N // Number of preallocated elements
508 , typename A > // Type of the allocator
510 SmallArray<T,N,A>::at( size_t index ) const
511{
512 if( index >= size() ) {
513 BLAZE_THROW_OUT_OF_RANGE( "Invalid small array access index" );
514 }
515 return begin_[index];
516}
517//*************************************************************************************************
518
519
520//*************************************************************************************************
527template< typename T // Data type of the elements
528 , size_t N // Number of preallocated elements
529 , typename A > // Type of the allocator
530inline typename SmallArray<T,N,A>::Pointer
532{
533 return begin_;
534}
535//*************************************************************************************************
536
537
538//*************************************************************************************************
545template< typename T // Data type of the elements
546 , size_t N // Number of preallocated elements
547 , typename A > // Type of the allocator
549 SmallArray<T,N,A>::data() const noexcept
550{
551 return begin_;
552}
553//*************************************************************************************************
554
555
556//*************************************************************************************************
561template< typename T // Data type of the elements
562 , size_t N // Number of preallocated elements
563 , typename A > // Type of the allocator
564inline typename SmallArray<T,N,A>::Iterator
566{
567 return begin_;
568}
569//*************************************************************************************************
570
571
572//*************************************************************************************************
577template< typename T // Data type of the elements
578 , size_t N // Number of preallocated elements
579 , typename A > // Type of the allocator
582{
583 return begin_;
584}
585//*************************************************************************************************
586
587
588//*************************************************************************************************
593template< typename T // Data type of the elements
594 , size_t N // Number of preallocated elements
595 , typename A > // Type of the allocator
598{
599 return begin_;
600}
601//*************************************************************************************************
602
603
604//*************************************************************************************************
609template< typename T // Data type of the elements
610 , size_t N // Number of preallocated elements
611 , typename A > // Type of the allocator
612inline typename SmallArray<T,N,A>::Iterator
614{
615 return end_;
616}
617//*************************************************************************************************
618
619
620//*************************************************************************************************
625template< typename T // Data type of the elements
626 , size_t N // Number of preallocated elements
627 , typename A > // Type of the allocator
629 SmallArray<T,N,A>::end() const noexcept
630{
631 return end_;
632}
633//*************************************************************************************************
634
635
636//*************************************************************************************************
641template< typename T // Data type of the elements
642 , size_t N // Number of preallocated elements
643 , typename A > // Type of the allocator
645 SmallArray<T,N,A>::cend() const noexcept
646{
647 return end_;
648}
649//*************************************************************************************************
650
651
652
653
654//=================================================================================================
655//
656// ASSIGNMENT OPERATORS
657//
658//=================================================================================================
659
660//*************************************************************************************************
676template< typename T // Data type of the elements
677 , size_t N // Number of preallocated elements
678 , typename A > // Type of the allocator
679template< typename U > // Type of the initializer list elements
680inline SmallArray<T,N,A>& SmallArray<T,N,A>::operator=( initializer_list<U> list )
681{
682 resize( list.size() );
683 std::copy( list.begin(), list.end(), begin_ );
684
685 return *this;
686}
687//*************************************************************************************************
688
689
690//*************************************************************************************************
699template< typename T // Data type of the elements
700 , size_t N // Number of preallocated elements
701 , typename A > // Type of the allocator
703{
704 resize( rhs.size() );
705 std::copy( rhs.begin(), rhs.end(), begin_ );
706
707 return *this;
708}
709//*************************************************************************************************
710
711
712//*************************************************************************************************
718template< typename T // Data type of the elements
719 , size_t N // Number of preallocated elements
720 , typename A > // Type of the allocator
722{
723 resize( rhs.size() );
724 std::move( rhs.begin_, rhs.end_, begin_ );
725 blaze::destroy( rhs.begin_, rhs.end_ );
726
727 rhs.begin_ = rhs.array();
728 rhs.end_ = rhs.begin_;
729 rhs.final_ = rhs.begin_ + N;
730
731 return *this;
732}
733//*************************************************************************************************
734
735
736
737
738//=================================================================================================
739//
740// UTILITY FUNCTIONS
741//
742//=================================================================================================
743
744//*************************************************************************************************
749template< typename T // Data type of the elements
750 , size_t N // Number of preallocated elements
751 , typename A > // Type of the allocator
752inline bool SmallArray<T,N,A>::empty() const noexcept
753{
754 return begin_ == end_;
755}
756//*************************************************************************************************
757
758
759//*************************************************************************************************
764template< typename T // Data type of the elements
765 , size_t N // Number of preallocated elements
766 , typename A > // Type of the allocator
767inline size_t SmallArray<T,N,A>::size() const noexcept
768{
769 return static_cast<size_t>( end_ - begin_ );
770}
771//*************************************************************************************************
772
773
774//*************************************************************************************************
779template< typename T // Data type of the elements
780 , size_t N // Number of preallocated elements
781 , typename A > // Type of the allocator
782inline size_t SmallArray<T,N,A>::capacity() const noexcept
783{
784 return final_ - begin_;
785}
786//*************************************************************************************************
787
788
789//*************************************************************************************************
796template< typename T // Data type of the elements
797 , size_t N // Number of preallocated elements
798 , typename A > // Type of the allocator
800{
801 blaze::destroy( begin_, end_ );
802
803 if( isDynamic() ) {
804 deallocate( begin_, capacity() );
805 }
806
807 begin_ = this->array();
808 end_ = begin_;
809 final_ = begin_ + N;
810}
811//*************************************************************************************************
812
813
814//*************************************************************************************************
824template< typename T // Data type of the elements
825 , size_t N // Number of preallocated elements
826 , typename A > // Type of the allocator
828{
829 if( n > size() )
830 {
831 reserve( n );
832 blaze::uninitialized_default_construct( begin_+size(), begin_+n );
833 end_ = begin_ + n;
834 }
835 else if( n < size() )
836 {
837 blaze::destroy( begin_+n, end_ );
838 end_ = begin_ + n;
839 }
840}
841//*************************************************************************************************
842
843
844//*************************************************************************************************
855template< typename T // Data type of the elements
856 , size_t N // Number of preallocated elements
857 , typename A > // Type of the allocator
858void SmallArray<T,N,A>::resize( size_t n, const T& value )
859{
860 if( n > size() )
861 {
862 reserve( n );
863 std::uninitialized_fill( begin_+size(), begin_+n, value );
864 end_ = begin_ + n;
865 }
866 else if( n < size() )
867 {
868 blaze::destroy( begin_+n, end_ );
869 end_ = begin_ + n;
870 }
871}
872//*************************************************************************************************
873
874
875//*************************************************************************************************
884template< typename T // Data type of the elements
885 , size_t N // Number of preallocated elements
886 , typename A > // Type of the allocator
888{
889 const size_t oldCapacity( capacity() );
890
891 if( n > oldCapacity )
892 {
893 const size_t oldSize( size() );
894 T* tmp( allocate( n ) );
895
896 if( IsNothrowMoveConstructible_v<T> ) {
897 blaze::uninitialized_move( begin_, end_, tmp );
898 }
899 else {
900 std::uninitialized_copy( begin_, end_, tmp );
901 }
902
903 blaze::destroy( begin_, end_ );
904
905 if( isDynamic() ) {
906 deallocate( begin_, oldCapacity );
907 }
908
909 final_ = tmp + n;
910 end_ = tmp + oldSize;
911 begin_ = tmp;
912 }
913}
914//*************************************************************************************************
915
916
917//*************************************************************************************************
926template< typename T // Data type of the elements
927 , size_t N // Number of preallocated elements
928 , typename A > // Type of the allocator
930{
931 const size_t oldCapacity( capacity() );
932 const size_t oldSize ( size() );
933
934 if( isDynamic() && oldCapacity > oldSize )
935 {
936 T* tmp( allocate( oldSize ) );
937
938 if( IsNothrowMoveConstructible_v<T> ) {
939 blaze::uninitialized_move( begin_, end_, tmp );
940 }
941 else {
942 std::uninitialized_copy( begin_, end_, tmp );
943 }
944
945 blaze::destroy( begin_, end_ );
946 deallocate( begin_, oldCapacity );
947
948 final_ = tmp + oldSize;
949 end_ = final_;
950 begin_ = tmp;
951 }
952}
953//*************************************************************************************************
954
955
956//*************************************************************************************************
962template< typename T // Data type of the elements
963 , size_t N // Number of preallocated elements
964 , typename A > // Type of the allocator
965void SmallArray<T,N,A>::pushBack( const T& value )
966{
967 using blaze::max;
968
969 const size_t oldCapacity( capacity() );
970
971 if( size() == oldCapacity ) {
972 reserve( max( 2UL*oldCapacity, 7UL ) );
973 }
974
975 ::new ( end_ ) T( value );
976 ++end_;
977}
978//*************************************************************************************************
979
980
981//*************************************************************************************************
987template< typename T // Data type of the elements
988 , size_t N // Number of preallocated elements
989 , typename A > // Type of the allocator
991{
992 using blaze::max;
993
994 const size_t oldCapacity( capacity() );
995
996 if( size() == oldCapacity ) {
997 reserve( max( 2UL*oldCapacity, 7UL ) );
998 }
999
1000 ::new ( end_ ) T( std::move( value ) );
1001 ++end_;
1002}
1003//*************************************************************************************************
1004
1005
1006//*************************************************************************************************
1013template< typename T // Data type of the elements
1014 , size_t N // Number of preallocated elements
1015 , typename A > // Type of the allocator
1018{
1019 const size_t oldCapacity( capacity() );
1020 const size_t oldSize ( size() );
1021
1022 if( oldSize == oldCapacity )
1023 {
1024 const size_t newCapacity( max( 1UL, 2UL*oldCapacity ) );
1025 const size_t index( pos - begin_ );
1026
1027 T* tmp ( allocate( newCapacity ) );
1028 T* newpos( tmp + index );
1029
1030 blaze::uninitialized_move( begin_, pos, tmp );
1031 ::new ( newpos ) T( value );
1032 blaze::uninitialized_move( pos, end_, tmp+index+1UL );
1033 blaze::destroy( begin_, end_ );
1034
1035 if( isDynamic() ) {
1036 deallocate( begin_, capacity() );
1037 }
1038
1039 final_ = tmp + newCapacity;
1040 end_ = tmp + oldSize + 1UL;
1041 begin_ = tmp;
1042
1043 return newpos;
1044 }
1045 else if( pos == end_ )
1046 {
1047 ::new( pos ) T( value );
1048 ++end_;
1049 return pos;
1050 }
1051 else
1052 {
1053 const auto tmp( end_ - 1UL );
1054 ::new ( end_ ) T( std::move( *tmp ) );
1055
1056 try {
1057 std::move_backward( pos, tmp, end_ );
1058 blaze::destroy_at( pos );
1059 ::new ( pos ) T( value );
1060 ++end_;
1061 }
1062 catch( ... ) {
1063 blaze::destroy_at( end_ );
1064 throw;
1065 }
1066
1067 return pos;
1068 }
1069}
1070//*************************************************************************************************
1071
1072
1073//*************************************************************************************************
1080template< typename T // Data type of the elements
1081 , size_t N // Number of preallocated elements
1082 , typename A > // Type of the allocator
1085{
1086 const size_t oldCapacity( capacity() );
1087 const size_t oldSize ( size() );
1088
1089 if( oldSize == oldCapacity )
1090 {
1091 const size_t newCapacity( max( 1UL, 2UL*oldCapacity ) );
1092 const size_t index( pos - begin_ );
1093
1094 T* tmp ( allocate( newCapacity ) );
1095 T* newpos( tmp + index );
1096
1097 blaze::uninitialized_move( begin_, pos, tmp );
1098 ::new ( newpos ) T( std::move( value ) );
1099 blaze::uninitialized_move( pos, end_, tmp+index+1UL );
1100 blaze::destroy( begin_, end_ );
1101
1102 if( isDynamic() ) {
1103 deallocate( begin_, capacity() );
1104 }
1105
1106 final_ = tmp + newCapacity;
1107 end_ = tmp + oldSize + 1UL;
1108 begin_ = tmp;
1109
1110 return newpos;
1111 }
1112 else if( pos == end_ )
1113 {
1114 ::new( pos ) T( std::move( value ) );
1115 ++end_;
1116 return pos;
1117 }
1118 else
1119 {
1120 const auto tmp( end_ - 1UL );
1121 ::new ( end_ ) T( std::move( *tmp ) );
1122
1123 try {
1124 std::move_backward( pos, tmp, end_ );
1125 blaze::destroy_at( pos );
1126 ::new ( pos ) T( std::move( value ) );
1127 ++end_;
1128 }
1129 catch( ... ) {
1130 blaze::destroy_at( end_ );
1131 throw;
1132 }
1133
1134 return pos;
1135 }
1136}
1137//*************************************************************************************************
1138
1139
1140//*************************************************************************************************
1148template< typename T // Data type of the elements
1149 , size_t N // Number of preallocated elements
1150 , typename A > // Type of the allocator
1153{
1154 std::move( pos+1UL, end_, pos );
1155 --end_;
1156 blaze::destroy_at( end_ );
1157
1158 return pos;
1159}
1160//*************************************************************************************************
1161
1162
1163//*************************************************************************************************
1172template< typename T // Data type of the elements
1173 , size_t N // Number of preallocated elements
1174 , typename A > // Type of the allocator
1177{
1178 BLAZE_USER_ASSERT( first <= last, "Invalid range detected" );
1179
1180 const size_t n( last - first );
1181
1182 std::move( last, end_, first );
1183 end_ -= n;
1184 blaze::destroy( end_, end_+n );
1185
1186 return first;
1187}
1188//*************************************************************************************************
1189
1190
1191//*************************************************************************************************
1201template< typename T // Data type of the elements
1202 , size_t N // Number of preallocated elements
1203 , typename A > // Type of the allocator
1204void SmallArray<T,N,A>::swap( SmallArray& sa ) noexcept( IsNothrowMoveConstructible_v<T> )
1205{
1206 using std::swap;
1207
1208 if( isDynamic() && sa.isDynamic() )
1209 {
1210 swap( begin_, sa.begin_ );
1211 swap( end_ , sa.end_ );
1212 swap( final_, sa.final_ );
1213 }
1214 else if( isDynamic() )
1215 {
1216 const size_t n( sa.size() );
1217
1218 blaze::uninitialized_move( sa.begin_, sa.end_, this->array() );
1219 blaze::destroy( sa.begin_, sa.end_ );
1220
1221 sa.begin_ = begin_;
1222 sa.end_ = end_;
1223 sa.final_ = final_;
1224
1225 begin_ = this->array();
1226 end_ = begin_ + n;
1227 final_ = begin_ + N;
1228 }
1229 else if( sa.isDynamic() )
1230 {
1231 const size_t n( size() );
1232
1233 blaze::uninitialized_move( begin_, end_, sa.array() );
1234 blaze::destroy( begin_, end_ );
1235
1236 begin_ = sa.begin_;
1237 end_ = sa.end_;
1238 final_ = sa.final_;
1239
1240 sa.begin_ = sa.array();
1241 sa.end_ = sa.begin_ + n;
1242 sa.final_ = sa.begin_ + N;
1243 }
1244 else if( size() > sa.size() )
1245 {
1246 const size_t n( size() - sa.size() );
1247 const auto pos = std::swap_ranges( sa.begin_, sa.end_, begin_ );
1248
1249 blaze::uninitialized_move( pos, end_, sa.end_ );
1250 blaze::destroy( pos, end_ );
1251 end_ -= n;
1252 sa.end_ += n;
1253 }
1254 else
1255 {
1256 const size_t n( sa.size() - size() );
1257 const auto pos = std::swap_ranges( begin_, end_, sa.begin_ );
1258
1259 blaze::uninitialized_move( pos, sa.end_, end_ );
1260 blaze::destroy( pos, sa.end_ );
1261 end_ += n;
1262 sa.end_ -= n;
1263 }
1264}
1265//*************************************************************************************************
1266
1267
1268//*************************************************************************************************
1273template< typename T // Data type of the elements
1274 , size_t N // Number of preallocated elements
1275 , typename A > // Type of the allocator
1276inline bool SmallArray<T,N,A>::isDynamic() const noexcept
1277{
1278 return ( N == 0UL || begin_ != this->array() );
1279}
1280//*************************************************************************************************
1281
1282
1283
1284
1285//=================================================================================================
1286//
1287// SMALLARRAY OPERATORS
1288//
1289//=================================================================================================
1290
1291//*************************************************************************************************
1294template< typename T1, size_t N1, typename A1, typename T2, size_t N2, typename A2 >
1295inline bool operator==( const SmallArray<T1,N1,A1>& lhs, const SmallArray<T2,N2,A2>& rhs );
1296
1297template< typename T1, size_t N1, typename A1, typename T2, size_t N2, typename A2 >
1298inline bool operator!=( const SmallArray<T1,N1,A1>& lhs, const SmallArray<T2,N2,A2>& rhs );
1299
1300template< typename T, size_t N, typename A >
1302
1303template< typename T, size_t N, typename A >
1304inline typename SmallArray<T,N,A>::ConstIterator begin( const SmallArray<T,N,A>& sa );
1305
1306template< typename T, size_t N, typename A >
1307inline typename SmallArray<T,N,A>::ConstIterator cbegin( const SmallArray<T,N,A>& sa );
1308
1309template< typename T, size_t N, typename A >
1311
1312template< typename T, size_t N, typename A >
1313inline typename SmallArray<T,N,A>::ConstIterator end( const SmallArray<T,N,A>& sa );
1314
1315template< typename T, size_t N, typename A >
1316inline typename SmallArray<T,N,A>::ConstIterator cend( const SmallArray<T,N,A>& sa );
1317
1318template< typename T, size_t N, typename A >
1319inline void clear( SmallArray<T,N,A>& sa );
1320
1321template< typename T, size_t N, typename A >
1322inline void swap( SmallArray<T,N,A>& a, SmallArray<T,N,A>& b )
1323 noexcept( IsNothrowMoveConstructible_v<T> );
1325//*************************************************************************************************
1326
1327
1328//*************************************************************************************************
1336template< typename T1 // Data type of the elements of the left-hand side array
1337 , size_t N1 // Number of elements of the left-hand side array
1338 , typename A1 // Type of the allocator of the left-hand side array
1339 , typename T2 // Data type of the elements of the right-hand side array
1340 , size_t N2 // Number of elements of the right-hand side array
1341 , typename A2 > // Type of the allocator of the right-hand side array
1342inline bool operator==( const SmallArray<T1,N1,A1>& lhs, const SmallArray<T2,N2,A2>& rhs )
1343{
1344 if( lhs.size() != rhs.size() ) return false;
1345
1346 return std::equal( lhs.begin(), lhs.end(), rhs.begin() );
1347}
1348//*************************************************************************************************
1349
1350
1351//*************************************************************************************************
1359template< typename T1 // Data type of the elements of the left-hand side array
1360 , size_t N1 // Number of elements of the left-hand side array
1361 , typename A1 // Type of the allocator of the left-hand side array
1362 , typename T2 // Data type of the elements of the right-hand side array
1363 , size_t N2 // Number of elements of the right-hand side array
1364 , typename A2 > // Type of the allocator of the right-hand side array
1365inline bool operator!=( const SmallArray<T1,N1,A1>& lhs, const SmallArray<T2,N2,A2>& rhs )
1366{
1367 return !( lhs == rhs );
1368}
1369//*************************************************************************************************
1370
1371
1372//*************************************************************************************************
1379template< typename T, size_t N, typename A >
1381{
1382 return sa.begin();
1383}
1384//*************************************************************************************************
1385
1386
1387//*************************************************************************************************
1394template< typename T, size_t N, typename A >
1396{
1397 return sa.begin();
1398}
1399//*************************************************************************************************
1400
1401
1402//*************************************************************************************************
1409template< typename T, size_t N, typename A >
1411{
1412 return sa.begin();
1413}
1414//*************************************************************************************************
1415
1416
1417//*************************************************************************************************
1424template< typename T, size_t N, typename A >
1426{
1427 return sa.end();
1428}
1429//*************************************************************************************************
1430
1431
1432//*************************************************************************************************
1439template< typename T, size_t N, typename A >
1441{
1442 return sa.end();
1443}
1444//*************************************************************************************************
1445
1446
1447//*************************************************************************************************
1454template< typename T, size_t N, typename A >
1456{
1457 return sa.end();
1458}
1459//*************************************************************************************************
1460
1461
1462//*************************************************************************************************
1469template< typename T // Data type of the elements
1470 , size_t N // Number of preallocated elements
1471 , typename A > // Type of the allocator
1472inline void clear( SmallArray<T,N,A>& sa )
1473{
1474 sa.clear();
1475}
1476//*************************************************************************************************
1477
1478
1479//*************************************************************************************************
1491template< typename T // Data type of the elements
1492 , size_t N // Number of preallocated elements
1493 , typename A > // Type of the allocator
1495 noexcept( IsNothrowMoveConstructible_v<T> )
1496{
1497 a.swap( b );
1498}
1499//*************************************************************************************************
1500
1501} // namespace blaze
1502
1503#endif
Header file for run time assertion macros.
Constraint on the data type.
Header file for the generic destroy_at algorithm.
Header file for the generic destroy algorithm.
Header file for the IsAssignable type trait.
Header file for the IsConstructible type trait.
Header file for the SmallArrayData class template.
Header file for the generic uninitialized_default_construct algorithm.
Header file for the generic uninitialized_move algorithm.
Constraint on the data type.
Implementation of a dynamic array with small array optimization.
Definition: SmallArray.h:84
ConstIterator cbegin() const noexcept
Returns an iterator to the first element of the small array.
Definition: SmallArray.h:597
void pushBack(const T &value)
Adding an element to the end of the small array.
Definition: SmallArray.h:965
Reference operator[](size_t index) noexcept
Subscript operator for the direct access to the array elements.
Definition: SmallArray.h:443
T * begin_
Pointer to the beginning of the currently used storage.
Definition: SmallArray.h:199
Iterator insert(Iterator pos, const T &value)
Inserting an element at the specified position into the small array.
Definition: SmallArray.h:1017
void reserve(size_t n)
Setting the minimum capacity of the array.
Definition: SmallArray.h:887
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: SmallArray.h:929
const T * ConstPointer
Pointer to a constant array element.
Definition: SmallArray.h:89
T * final_
Pointer to the very end of the currently used storage.
Definition: SmallArray.h:201
Pointer data() noexcept
Low-level data access to the array elements.
Definition: SmallArray.h:531
ConstIterator cend() const noexcept
Returns an iterator just past the last element of the small array.
Definition: SmallArray.h:645
size_t capacity() const noexcept
Returns the maximum capacity of the small array.
Definition: SmallArray.h:782
T * Pointer
Pointer to a non-constant array element.
Definition: SmallArray.h:88
T ElementType
Type of the array elements.
Definition: SmallArray.h:87
bool isDynamic() const noexcept
Returns whether the small array uses its dynamic storage.
Definition: SmallArray.h:1276
void resize(size_t n)
Changing the size of the array.
Definition: SmallArray.h:827
T & Reference
Reference to a non-constant array element.
Definition: SmallArray.h:90
Reference at(size_t index)
Checked access to the array elements.
Definition: SmallArray.h:486
Iterator begin() noexcept
Returns an iterator to the first element of the small array.
Definition: SmallArray.h:565
T * end_
Pointer to the end of the currently used storage.
Definition: SmallArray.h:200
Iterator end() noexcept
Returns an iterator just past the last element of the small array.
Definition: SmallArray.h:613
void swap(SmallArray &sa) noexcept(IsNothrowMoveConstructible_v< T >)
Swapping the contents of two small arrays.
Definition: SmallArray.h:1204
const T * ConstIterator
Iterator over constant elements.
Definition: SmallArray.h:93
bool empty() const noexcept
Returns whether the array is empty.
Definition: SmallArray.h:752
T * Iterator
Iterator over non-constant elements.
Definition: SmallArray.h:92
void clear()
Clearing the array.
Definition: SmallArray.h:799
const T & ConstReference
Reference to a constant array element.
Definition: SmallArray.h:91
size_t size() const noexcept
Returns the current size/dimension of the small array.
Definition: SmallArray.h:767
Iterator erase(Iterator pos)
Erasing an element from the small array.
Definition: SmallArray.h:1152
SmallArray(const A &alloc=A())
The (default) constructor for SmallArray.
Definition: SmallArray.h:231
~SmallArray()
The destructor for SmallArray.
Definition: SmallArray.h:410
void destroy(ForwardIt first, ForwardIt last)
Destroys the given range of objects .
Definition: Destroy.h:67
void uninitialized_default_construct(ForwardIt first, ForwardIt last)
Default constructs elements in the given range.
Definition: UninitializedDefaultConstruct.h:69
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:72
void destroy_at(T *p) noexcept
Destroys the object at the given address.
Definition: DestroyAt.h:57
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.
Definition: Volatile.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.
Definition: Const.h:79
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1375
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:692
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:1108
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
bool equal(const SharedValue< T1 > &lhs, const SharedValue< T2 > &rhs)
Equality check for a two shared values.
Definition: SharedValue.h:343
constexpr bool IsNothrowMoveConstructible_v
Auxiliary variable template for the IsNothrowMoveConstructible type trait.
Definition: IsConstructible.h:427
void deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
SmallArray< T, N, A >::ConstIterator begin(const SmallArray< T, N, A > &sa)
Returns an iterator to the first element of the given small array.
Definition: SmallArray.h:1395
SmallArray< T, N, A >::ConstIterator cbegin(const SmallArray< T, N, A > &sa)
Returns an iterator to the first element of the given small array.
Definition: SmallArray.h:1410
SmallArray< T, N, A >::ConstIterator cend(const SmallArray< T, N, A > &sa)
Returns an iterator just past the last element of the given small array.
Definition: SmallArray.h:1455
void swap(SmallArray< T, N, A > &a, SmallArray< T, N, A > &b) noexcept(IsNothrowMoveConstructible_v< T >)
Swapping the contents of two small arrays.
Definition: SmallArray.h:1494
bool operator==(const SmallArray< T1, N1, A1 > &lhs, const SmallArray< T2, N2, A2 > &rhs)
Equality operator for the comparison of two dense arrays.
Definition: SmallArray.h:1342
void clear(SmallArray< T, N, A > &sa)
Clearing the given small array.
Definition: SmallArray.h:1472
bool operator!=(const SmallArray< T1, N1, A1 > &lhs, const SmallArray< T2, N2, A2 > &rhs)
Inequality operator for the comparison of two dense arrays.
Definition: SmallArray.h:1365
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
T * allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:158
SmallArray< T, N, A >::ConstIterator end(const SmallArray< T, N, A > &sa)
Returns an iterator just past the last element of the given small array.
Definition: SmallArray.h:1440
Definition of the nested auxiliary struct Uninitialized.
Definition: SmallArray.h:176
Header file for exception macros.
Header file for the initializer_list template.
Header file for basic type definitions.
Header file for the generic max algorithm.