CustomVector.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_DENSE_CUSTOMVECTOR_H_
36 #define _BLAZE_MATH_DENSE_CUSTOMVECTOR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <utility>
45 #include <blaze/math/Aliases.h>
52 #include <blaze/math/Exception.h>
55 #include <blaze/math/Forward.h>
57 #include <blaze/math/PaddingFlag.h>
58 #include <blaze/math/shims/Clear.h>
62 #include <blaze/math/SIMD.h>
79 #include <blaze/system/CacheSize.h>
80 #include <blaze/system/Inline.h>
85 #include <blaze/util/Assert.h>
90 #include <blaze/util/DisableIf.h>
91 #include <blaze/util/EnableIf.h>
93 #include <blaze/util/TrueType.h>
94 #include <blaze/util/Types.h>
98 #include <blaze/util/Unused.h>
99 
100 
101 namespace blaze {
102 
103 //=================================================================================================
104 //
105 // CLASS DEFINITION
106 //
107 //=================================================================================================
108 
109 //*************************************************************************************************
388 template< typename Type // Data type of the vector
389  , bool AF // Alignment flag
390  , bool PF // Padding flag
391  , bool TF = defaultTransposeFlag // Transpose flag
392  , typename RT = DynamicVector<RemoveConst_t<Type>,TF> > // Result type
394  : public DenseVector< CustomVector<Type,AF,PF,TF,RT>, TF >
395 {
396  public:
397  //**Type definitions****************************************************************************
400 
402  using ResultType = RT;
403 
406 
407  using ElementType = Type;
409  using ReturnType = const Type&;
410  using CompositeType = const CustomVector&;
411 
412  using Reference = Type&;
413  using ConstReference = const Type&;
414  using Pointer = Type*;
415  using ConstPointer = const Type*;
416 
419  //**********************************************************************************************
420 
421  //**Rebind struct definition********************************************************************
424  template< typename NewType > // Data type of the other vector
425  struct Rebind {
428  };
429  //**********************************************************************************************
430 
431  //**Resize struct definition********************************************************************
434  template< size_t NewN > // Number of elements of the other vector
435  struct Resize {
438  };
439  //**********************************************************************************************
440 
441  //**Compilation flags***************************************************************************
443 
447  static constexpr bool simdEnabled = IsVectorizable_v<Type>;
448 
450 
453  static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
454  //**********************************************************************************************
455 
456  //**Constructors********************************************************************************
459  explicit inline CustomVector();
460  explicit inline CustomVector( Type* ptr, size_t n );
461  explicit inline CustomVector( Type* ptr, size_t n, size_t nn );
462 
463  inline CustomVector( const CustomVector& v );
464  inline CustomVector( CustomVector&& v ) noexcept;
466  //**********************************************************************************************
467 
468  //**Destructor**********************************************************************************
471  ~CustomVector() = default;
473  //**********************************************************************************************
474 
475  //**Data access functions***********************************************************************
478  inline Reference operator[]( size_t index ) noexcept;
479  inline ConstReference operator[]( size_t index ) const noexcept;
480  inline Reference at( size_t index );
481  inline ConstReference at( size_t index ) const;
482  inline Pointer data () noexcept;
483  inline ConstPointer data () const noexcept;
484  inline Iterator begin () noexcept;
485  inline ConstIterator begin () const noexcept;
486  inline ConstIterator cbegin() const noexcept;
487  inline Iterator end () noexcept;
488  inline ConstIterator end () const noexcept;
489  inline ConstIterator cend () const noexcept;
491  //**********************************************************************************************
492 
493  //**Assignment operators************************************************************************
496  inline CustomVector& operator=( const Type& rhs );
497  inline CustomVector& operator=( initializer_list<Type> list );
498 
499  template< typename Other, size_t N >
500  inline CustomVector& operator=( const Other (&array)[N] );
501 
502  inline CustomVector& operator=( const CustomVector& rhs );
503  inline CustomVector& operator=( CustomVector&& rhs ) noexcept;
504 
505  template< typename VT > inline CustomVector& operator= ( const Vector<VT,TF>& rhs );
506  template< typename VT > inline CustomVector& operator+=( const Vector<VT,TF>& rhs );
507  template< typename VT > inline CustomVector& operator-=( const Vector<VT,TF>& rhs );
508  template< typename VT > inline CustomVector& operator*=( const Vector<VT,TF>& rhs );
509  template< typename VT > inline CustomVector& operator/=( const DenseVector<VT,TF>& rhs );
510  template< typename VT > inline CustomVector& operator%=( const Vector<VT,TF>& rhs );
512  //**********************************************************************************************
513 
514  //**Utility functions***************************************************************************
517  inline size_t size() const noexcept;
518  inline size_t spacing() const noexcept;
519  inline size_t capacity() const noexcept;
520  inline size_t nonZeros() const;
521  inline void reset();
522  inline void clear();
523  inline void swap( CustomVector& v ) noexcept;
525  //**********************************************************************************************
526 
527  //**Numeric functions***************************************************************************
530  template< typename Other > inline CustomVector& scale( const Other& scalar );
532  //**********************************************************************************************
533 
534  //**Resource management functions***************************************************************
537  inline void reset( Type* ptr, size_t n );
538  inline void reset( Type* ptr, size_t n, size_t nn );
540  //**********************************************************************************************
541 
542  private:
543  //**********************************************************************************************
545  template< typename VT >
547  static constexpr bool VectorizedAssign_v =
548  ( useOptimizedKernels &&
549  simdEnabled && VT::simdEnabled &&
550  IsSIMDCombinable_v< Type, ElementType_t<VT> > );
552  //**********************************************************************************************
553 
554  //**********************************************************************************************
556  template< typename VT >
558  static constexpr bool VectorizedAddAssign_v =
559  ( useOptimizedKernels &&
560  simdEnabled && VT::simdEnabled &&
561  IsSIMDCombinable_v< Type, ElementType_t<VT> > &&
562  HasSIMDAdd_v< Type, ElementType_t<VT> > );
564  //**********************************************************************************************
565 
566  //**********************************************************************************************
568  template< typename VT >
570  static constexpr bool VectorizedSubAssign_v =
571  ( useOptimizedKernels &&
572  simdEnabled && VT::simdEnabled &&
573  IsSIMDCombinable_v< Type, ElementType_t<VT> > &&
574  HasSIMDSub_v< Type, ElementType_t<VT> > );
576  //**********************************************************************************************
577 
578  //**********************************************************************************************
580  template< typename VT >
582  static constexpr bool VectorizedMultAssign_v =
583  ( useOptimizedKernels &&
584  simdEnabled && VT::simdEnabled &&
585  IsSIMDCombinable_v< Type, ElementType_t<VT> > &&
586  HasSIMDMult_v< Type, ElementType_t<VT> > );
588  //**********************************************************************************************
589 
590  //**********************************************************************************************
592  template< typename VT >
594  static constexpr bool VectorizedDivAssign_v =
595  ( useOptimizedKernels &&
596  simdEnabled && VT::simdEnabled &&
597  IsSIMDCombinable_v< Type, ElementType_t<VT> > &&
598  HasSIMDDiv_v< Type, ElementType_t<VT> > );
600  //**********************************************************************************************
601 
602  //**SIMD properties*****************************************************************************
604  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
605  //**********************************************************************************************
606 
607  public:
608  //**Expression template evaluation functions****************************************************
611  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
612  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
613 
614  inline bool isAligned () const noexcept;
615  inline bool canSMPAssign() const noexcept;
616 
617  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
618  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
619  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
620 
621  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
622  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
623  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
624  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
625 
626  template< typename VT >
627  inline auto assign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
628 
629  template< typename VT >
630  inline auto assign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
631 
632  template< typename VT > inline void assign( const SparseVector<VT,TF>& rhs );
633 
634  template< typename VT >
635  inline auto addAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
636 
637  template< typename VT >
638  inline auto addAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
639 
640  template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
641 
642  template< typename VT >
643  inline auto subAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
644 
645  template< typename VT >
646  inline auto subAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
647 
648  template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
649 
650  template< typename VT >
651  inline auto multAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
652 
653  template< typename VT >
654  inline auto multAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
655 
656  template< typename VT > inline void multAssign( const SparseVector<VT,TF>& rhs );
657 
658  template< typename VT >
659  inline auto divAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
660 
661  template< typename VT >
662  inline auto divAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT> >;
664  //**********************************************************************************************
665 
666  private:
667  //**Member variables****************************************************************************
670  size_t size_;
671  Type* v_;
672 
678  //**********************************************************************************************
679 
680  //**Compile time checks*************************************************************************
688  //**********************************************************************************************
689 };
690 //*************************************************************************************************
691 
692 
693 
694 
695 //=================================================================================================
696 //
697 // CONSTRUCTORS
698 //
699 //=================================================================================================
700 
701 //*************************************************************************************************
704 template< typename Type // Data type of the vector
705  , bool AF // Alignment flag
706  , bool PF // Padding flag
707  , bool TF // Transpose flag
708  , typename RT > // Result type
709 inline CustomVector<Type,AF,PF,TF,RT>::CustomVector()
710  : size_( 0UL ) // The size/dimension of the vector
711  , v_ ( nullptr ) // The custom array of elements
712 {}
713 //*************************************************************************************************
714 
715 
716 //*************************************************************************************************
734 template< typename Type // Data type of the vector
735  , bool AF // Alignment flag
736  , bool PF // Padding flag
737  , bool TF // Transpose flag
738  , typename RT > // Result type
739 inline CustomVector<Type,AF,PF,TF,RT>::CustomVector( Type* ptr, size_t n )
740  : size_( n ) // The size/dimension of the vector
741  , v_ ( ptr ) // The custom array of elements
742 {
743  if( ptr == nullptr ) {
744  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
745  }
746 
747  if( AF && !checkAlignment( ptr ) ) {
748  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
749  }
750 }
751 //*************************************************************************************************
752 
753 
754 //*************************************************************************************************
776 template< typename Type // Data type of the vector
777  , bool AF // Alignment flag
778  , bool PF // Padding flag
779  , bool TF // Transpose flag
780  , typename RT > // Result type
781 inline CustomVector<Type,AF,PF,TF,RT>::CustomVector( Type* ptr, size_t n, size_t nn )
782  : size_( 0UL ) // The size/dimension of the vector
783  , v_ ( nullptr ) // The custom array of elements
784 {
785  BLAZE_STATIC_ASSERT( PF == padded );
786 
787  UNUSED_PARAMETER( ptr, n, nn );
788 }
789 //*************************************************************************************************
790 
791 
792 //*************************************************************************************************
799 template< typename Type // Data type of the vector
800  , bool AF // Alignment flag
801  , bool PF // Padding flag
802  , bool TF // Transpose flag
803  , typename RT > // Result type
805  : size_( v.size_ ) // The size/dimension of the vector
806  , v_ ( v.v_ ) // The custom array of elements
807 {}
808 //*************************************************************************************************
809 
810 
811 //*************************************************************************************************
816 template< typename Type // Data type of the vector
817  , bool AF // Alignment flag
818  , bool PF // Padding flag
819  , bool TF // Transpose flag
820  , typename RT > // Result type
822  : size_( v.size_ ) // The size/dimension of the vector
823  , v_ ( v.v_ ) // The custom array of elements
824 {
825  v.size_ = 0UL;
826  v.v_ = nullptr;
827 
828  BLAZE_INTERNAL_ASSERT( v.data() == nullptr, "Invalid data reference detected" );
829 }
830 //*************************************************************************************************
831 
832 
833 
834 
835 //=================================================================================================
836 //
837 // DATA ACCESS FUNCTIONS
838 //
839 //=================================================================================================
840 
841 //*************************************************************************************************
850 template< typename Type // Data type of the vector
851  , bool AF // Alignment flag
852  , bool PF // Padding flag
853  , bool TF // Transpose flag
854  , typename RT > // Result type
857 {
858  BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
859  return v_[index];
860 }
861 //*************************************************************************************************
862 
863 
864 //*************************************************************************************************
873 template< typename Type // Data type of the vector
874  , bool AF // Alignment flag
875  , bool PF // Padding flag
876  , bool TF // Transpose flag
877  , typename RT > // Result type
879  CustomVector<Type,AF,PF,TF,RT>::operator[]( size_t index ) const noexcept
880 {
881  BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
882  return v_[index];
883 }
884 //*************************************************************************************************
885 
886 
887 //*************************************************************************************************
897 template< typename Type // Data type of the vector
898  , bool AF // Alignment flag
899  , bool PF // Padding flag
900  , bool TF // Transpose flag
901  , typename RT > // Result type
904 {
905  if( index >= size_ ) {
906  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
907  }
908  return (*this)[index];
909 }
910 //*************************************************************************************************
911 
912 
913 //*************************************************************************************************
923 template< typename Type // Data type of the vector
924  , bool AF // Alignment flag
925  , bool PF // Padding flag
926  , bool TF // Transpose flag
927  , typename RT > // Result type
930 {
931  if( index >= size_ ) {
932  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
933  }
934  return (*this)[index];
935 }
936 //*************************************************************************************************
937 
938 
939 //*************************************************************************************************
946 template< typename Type // Data type of the vector
947  , bool AF // Alignment flag
948  , bool PF // Padding flag
949  , bool TF // Transpose flag
950  , typename RT > // Result type
953 {
954  return v_;
955 }
956 //*************************************************************************************************
957 
958 
959 //*************************************************************************************************
966 template< typename Type // Data type of the vector
967  , bool AF // Alignment flag
968  , bool PF // Padding flag
969  , bool TF // Transpose flag
970  , typename RT > // Result type
973 {
974  return v_;
975 }
976 //*************************************************************************************************
977 
978 
979 //*************************************************************************************************
984 template< typename Type // Data type of the vector
985  , bool AF // Alignment flag
986  , bool PF // Padding flag
987  , bool TF // Transpose flag
988  , typename RT > // Result type
991 {
992  return Iterator( v_ );
993 }
994 //*************************************************************************************************
995 
996 
997 //*************************************************************************************************
1002 template< typename Type // Data type of the vector
1003  , bool AF // Alignment flag
1004  , bool PF // Padding flag
1005  , bool TF // Transpose flag
1006  , typename RT > // Result type
1009 {
1010  return ConstIterator( v_ );
1011 }
1012 //*************************************************************************************************
1013 
1014 
1015 //*************************************************************************************************
1020 template< typename Type // Data type of the vector
1021  , bool AF // Alignment flag
1022  , bool PF // Padding flag
1023  , bool TF // Transpose flag
1024  , typename RT > // Result type
1027 {
1028  return ConstIterator( v_ );
1029 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1038 template< typename Type // Data type of the vector
1039  , bool AF // Alignment flag
1040  , bool PF // Padding flag
1041  , bool TF // Transpose flag
1042  , typename RT > // Result type
1045 {
1046  return Iterator( v_+size_ );
1047 }
1048 //*************************************************************************************************
1049 
1050 
1051 //*************************************************************************************************
1056 template< typename Type // Data type of the vector
1057  , bool AF // Alignment flag
1058  , bool PF // Padding flag
1059  , bool TF // Transpose flag
1060  , typename RT > // Result type
1063 {
1064  return ConstIterator( v_+size_ );
1065 }
1066 //*************************************************************************************************
1067 
1068 
1069 //*************************************************************************************************
1074 template< typename Type // Data type of the vector
1075  , bool AF // Alignment flag
1076  , bool PF // Padding flag
1077  , bool TF // Transpose flag
1078  , typename RT > // Result type
1081 {
1082  return ConstIterator( v_+size_ );
1083 }
1084 //*************************************************************************************************
1085 
1086 
1087 
1088 
1089 //=================================================================================================
1090 //
1091 // ASSIGNMENT OPERATORS
1092 //
1093 //=================================================================================================
1094 
1095 //*************************************************************************************************
1101 template< typename Type // Data type of the vector
1102  , bool AF // Alignment flag
1103  , bool PF // Padding flag
1104  , bool TF // Transpose flag
1105  , typename RT > // Result type
1107 {
1108  for( size_t i=0UL; i<size_; ++i )
1109  v_[i] = rhs;
1110  return *this;
1111 }
1112 //*************************************************************************************************
1113 
1114 
1115 //*************************************************************************************************
1139 template< typename Type // Data type of the vector
1140  , bool AF // Alignment flag
1141  , bool PF // Padding flag
1142  , bool TF // Transpose flag
1143  , typename RT > // Result type
1146 {
1147  if( list.size() > size_ ) {
1148  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom vector" );
1149  }
1150 
1151  std::fill( std::copy( list.begin(), list.end(), v_ ), v_+size_, Type() );
1152 
1153  return *this;
1154 }
1155 //*************************************************************************************************
1156 
1157 
1158 //*************************************************************************************************
1185 template< typename Type // Data type of the vector
1186  , bool AF // Alignment flag
1187  , bool PF // Padding flag
1188  , bool TF // Transpose flag
1189  , typename RT > // Result type
1190 template< typename Other // Data type of the initialization array
1191  , size_t N > // Dimension of the initialization array
1194 {
1195  if( size_ != N ) {
1196  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1197  }
1198 
1199  for( size_t i=0UL; i<N; ++i )
1200  v_[i] = array[i];
1201 
1202  return *this;
1203 }
1204 //*************************************************************************************************
1205 
1206 
1207 //*************************************************************************************************
1217 template< typename Type // Data type of the vector
1218  , bool AF // Alignment flag
1219  , bool PF // Padding flag
1220  , bool TF // Transpose flag
1221  , typename RT > // Result type
1224 {
1225  if( rhs.size() != size_ ) {
1226  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1227  }
1228 
1229  smpAssign( *this, ~rhs );
1230 
1231  return *this;
1232 }
1233 //*************************************************************************************************
1234 
1235 
1236 //*************************************************************************************************
1242 template< typename Type // Data type of the vector
1243  , bool AF // Alignment flag
1244  , bool PF // Padding flag
1245  , bool TF // Transpose flag
1246  , typename RT > // Result type
1249 {
1250  size_ = rhs.size_;
1251  v_ = rhs.v_;
1252 
1253  rhs.size_ = 0UL;
1254  rhs.v_ = nullptr;
1255 
1256  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
1257 
1258  return *this;
1259 }
1260 //*************************************************************************************************
1261 
1262 
1263 //*************************************************************************************************
1273 template< typename Type // Data type of the vector
1274  , bool AF // Alignment flag
1275  , bool PF // Padding flag
1276  , bool TF // Transpose flag
1277  , typename RT > // Result type
1278 template< typename VT > // Type of the right-hand side vector
1281 {
1282  if( (~rhs).size() != size_ ) {
1283  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1284  }
1285 
1286  if( (~rhs).canAlias( this ) ) {
1287  const ResultType_t<VT> tmp( ~rhs );
1288  smpAssign( *this, tmp );
1289  }
1290  else {
1291  if( IsSparseVector_v<VT> )
1292  reset();
1293  smpAssign( *this, ~rhs );
1294  }
1295 
1296  return *this;
1297 }
1298 //*************************************************************************************************
1299 
1300 
1301 //*************************************************************************************************
1311 template< typename Type // Data type of the vector
1312  , bool AF // Alignment flag
1313  , bool PF // Padding flag
1314  , bool TF // Transpose flag
1315  , typename RT > // Result type
1316 template< typename VT > // Type of the right-hand side vector
1319 {
1320  if( (~rhs).size() != size_ ) {
1321  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1322  }
1323 
1324  if( (~rhs).canAlias( this ) ) {
1325  const ResultType_t<VT> tmp( ~rhs );
1326  smpAddAssign( *this, tmp );
1327  }
1328  else {
1329  smpAddAssign( *this, ~rhs );
1330  }
1331 
1332  return *this;
1333 }
1334 //*************************************************************************************************
1335 
1336 
1337 //*************************************************************************************************
1348 template< typename Type // Data type of the vector
1349  , bool AF // Alignment flag
1350  , bool PF // Padding flag
1351  , bool TF // Transpose flag
1352  , typename RT > // Result type
1353 template< typename VT > // Type of the right-hand side vector
1356 {
1357  if( (~rhs).size() != size_ ) {
1358  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1359  }
1360 
1361  if( (~rhs).canAlias( this ) ) {
1362  const ResultType_t<VT> tmp( ~rhs );
1363  smpSubAssign( *this, tmp );
1364  }
1365  else {
1366  smpSubAssign( *this, ~rhs );
1367  }
1368 
1369  return *this;
1370 }
1371 //*************************************************************************************************
1372 
1373 
1374 //*************************************************************************************************
1385 template< typename Type // Data type of the vector
1386  , bool AF // Alignment flag
1387  , bool PF // Padding flag
1388  , bool TF // Transpose flag
1389  , typename RT > // Result type
1390 template< typename VT > // Type of the right-hand side vector
1393 {
1396 
1397  using MultType = MultTrait_t< ResultType, ResultType_t<VT> >;
1398 
1401 
1402  if( (~rhs).size() != size_ ) {
1403  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1404  }
1405 
1406  if( IsSparseVector_v<VT> || (~rhs).canAlias( this ) ) {
1407  const MultType tmp( *this * (~rhs) );
1408  if( IsSparseVector_v<MultType> )
1409  reset();
1410  smpAssign( *this, tmp );
1411  }
1412  else {
1413  smpMultAssign( *this, ~rhs );
1414  }
1415 
1416  return *this;
1417 }
1418 //*************************************************************************************************
1419 
1420 
1421 //*************************************************************************************************
1431 template< typename Type // Data type of the vector
1432  , bool AF // Alignment flag
1433  , bool PF // Padding flag
1434  , bool TF // Transpose flag
1435  , typename RT > // Result type
1436 template< typename VT > // Type of the right-hand side vector
1439 {
1442 
1443  using DivType = DivTrait_t< ResultType, ResultType_t<VT> >;
1444 
1448 
1449  if( (~rhs).size() != size_ ) {
1450  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1451  }
1452 
1453  if( (~rhs).canAlias( this ) ) {
1454  const DivType tmp( *this / (~rhs) );
1455  smpAssign( *this, tmp );
1456  }
1457  else {
1458  smpDivAssign( *this, ~rhs );
1459  }
1460 
1461  return *this;
1462 }
1463 //*************************************************************************************************
1464 
1465 
1466 //*************************************************************************************************
1477 template< typename Type // Data type of the vector
1478  , bool AF // Alignment flag
1479  , bool PF // Padding flag
1480  , bool TF // Transpose flag
1481  , typename RT > // Result type
1482 template< typename VT > // Type of the right-hand side vector
1485 {
1486  using blaze::assign;
1487 
1490 
1491  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
1492 
1496 
1497  if( size_ != 3UL || (~rhs).size() != 3UL ) {
1498  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1499  }
1500 
1501  const CrossType tmp( *this % (~rhs) );
1502  assign( *this, tmp );
1503 
1504  return *this;
1505 }
1506 //*************************************************************************************************
1507 
1508 
1509 
1510 
1511 //=================================================================================================
1512 //
1513 // UTILITY FUNCTIONS
1514 //
1515 //=================================================================================================
1516 
1517 //*************************************************************************************************
1522 template< typename Type // Data type of the vector
1523  , bool AF // Alignment flag
1524  , bool PF // Padding flag
1525  , bool TF // Transpose flag
1526  , typename RT > // Result type
1527 inline size_t CustomVector<Type,AF,PF,TF,RT>::size() const noexcept
1528 {
1529  return size_;
1530 }
1531 //*************************************************************************************************
1532 
1533 
1534 //*************************************************************************************************
1542 template< typename Type // Data type of the vector
1543  , bool AF // Alignment flag
1544  , bool PF // Padding flag
1545  , bool TF // Transpose flag
1546  , typename RT > // Result type
1547 inline size_t CustomVector<Type,AF,PF,TF,RT>::spacing() const noexcept
1548 {
1549  return size_;
1550 }
1551 //*************************************************************************************************
1552 
1553 
1554 //*************************************************************************************************
1559 template< typename Type // Data type of the vector
1560  , bool AF // Alignment flag
1561  , bool PF // Padding flag
1562  , bool TF // Transpose flag
1563  , typename RT > // Result type
1564 inline size_t CustomVector<Type,AF,PF,TF,RT>::capacity() const noexcept
1565 {
1566  return size_;
1567 }
1568 //*************************************************************************************************
1569 
1570 
1571 //*************************************************************************************************
1579 template< typename Type // Data type of the vector
1580  , bool AF // Alignment flag
1581  , bool PF // Padding flag
1582  , bool TF // Transpose flag
1583  , typename RT > // Result type
1585 {
1586  size_t nonzeros( 0 );
1587 
1588  for( size_t i=0UL; i<size_; ++i ) {
1589  if( !isDefault( v_[i] ) )
1590  ++nonzeros;
1591  }
1592 
1593  return nonzeros;
1594 }
1595 //*************************************************************************************************
1596 
1597 
1598 //*************************************************************************************************
1603 template< typename Type // Data type of the vector
1604  , bool AF // Alignment flag
1605  , bool PF // Padding flag
1606  , bool TF // Transpose flag
1607  , typename RT > // Result type
1609 {
1610  using blaze::clear;
1611  for( size_t i=0UL; i<size_; ++i )
1612  clear( v_[i] );
1613 }
1614 //*************************************************************************************************
1615 
1616 
1617 //*************************************************************************************************
1625 template< typename Type // Data type of the vector
1626  , bool AF // Alignment flag
1627  , bool PF // Padding flag
1628  , bool TF // Transpose flag
1629  , typename RT > // Result type
1631 {
1632  size_ = 0UL;
1633  v_ = nullptr;
1634 }
1635 //*************************************************************************************************
1636 
1637 
1638 //*************************************************************************************************
1644 template< typename Type // Data type of the vector
1645  , bool AF // Alignment flag
1646  , bool PF // Padding flag
1647  , bool TF // Transpose flag
1648  , typename RT > // Result type
1650 {
1651  using std::swap;
1652 
1653  swap( size_, v.size_ );
1654  swap( v_, v.v_ );
1655 }
1656 //*************************************************************************************************
1657 
1658 
1659 
1660 
1661 //=================================================================================================
1662 //
1663 // NUMERIC FUNCTIONS
1664 //
1665 //=================================================================================================
1666 
1667 //*************************************************************************************************
1688 template< typename Type // Data type of the vector
1689  , bool AF // Alignment flag
1690  , bool PF // Padding flag
1691  , bool TF // Transpose flag
1692  , typename RT > // Result type
1693 template< typename Other > // Data type of the scalar value
1695 {
1696  for( size_t i=0UL; i<size_; ++i )
1697  v_[i] *= scalar;
1698  return *this;
1699 }
1700 //*************************************************************************************************
1701 
1702 
1703 
1704 
1705 //=================================================================================================
1706 //
1707 // RESOURCE MANAGEMENT FUNCTIONS
1708 //
1709 //=================================================================================================
1710 
1711 //*************************************************************************************************
1733 template< typename Type // Data type of the vector
1734  , bool AF // Alignment flag
1735  , bool PF // Padding flag
1736  , bool TF // Transpose flag
1737  , typename RT > // Result type
1738 inline void CustomVector<Type,AF,PF,TF,RT>::reset( Type* ptr, size_t n )
1739 {
1740  CustomVector tmp( ptr, n );
1741  swap( tmp );
1742 }
1743 //*************************************************************************************************
1744 
1745 
1746 //*************************************************************************************************
1771 template< typename Type // Data type of the vector
1772  , bool AF // Alignment flag
1773  , bool PF // Padding flag
1774  , bool TF // Transpose flag
1775  , typename RT > // Result type
1776 inline void CustomVector<Type,AF,PF,TF,RT>::reset( Type* ptr, size_t n, size_t nn )
1777 {
1778  BLAZE_STATIC_ASSERT( PF == padded );
1779 
1780  UNUSED_PARAMETER( ptr, n, nn );
1781 }
1782 //*************************************************************************************************
1783 
1784 
1785 
1786 
1787 //=================================================================================================
1788 //
1789 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1790 //
1791 //=================================================================================================
1792 
1793 //*************************************************************************************************
1803 template< typename Type // Data type of the vector
1804  , bool AF // Alignment flag
1805  , bool PF // Padding flag
1806  , bool TF // Transpose flag
1807  , typename RT > // Result type
1808 template< typename Other > // Data type of the foreign expression
1809 inline bool CustomVector<Type,AF,PF,TF,RT>::canAlias( const Other* alias ) const noexcept
1810 {
1811  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1812 }
1813 //*************************************************************************************************
1814 
1815 
1816 //*************************************************************************************************
1826 template< typename Type // Data type of the vector
1827  , bool AF // Alignment flag
1828  , bool PF // Padding flag
1829  , bool TF // Transpose flag
1830  , typename RT > // Result type
1831 template< typename Other > // Data type of the foreign expression
1832 inline bool CustomVector<Type,AF,PF,TF,RT>::isAliased( const Other* alias ) const noexcept
1833 {
1834  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1835 }
1836 //*************************************************************************************************
1837 
1838 
1839 //*************************************************************************************************
1848 template< typename Type // Data type of the vector
1849  , bool AF // Alignment flag
1850  , bool PF // Padding flag
1851  , bool TF // Transpose flag
1852  , typename RT > // Result type
1853 inline bool CustomVector<Type,AF,PF,TF,RT>::isAligned() const noexcept
1854 {
1855  return ( AF || checkAlignment( v_ ) );
1856 }
1857 //*************************************************************************************************
1858 
1859 
1860 //*************************************************************************************************
1870 template< typename Type // Data type of the vector
1871  , bool AF // Alignment flag
1872  , bool PF // Padding flag
1873  , bool TF // Transpose flag
1874  , typename RT > // Result type
1876 {
1877  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1878 }
1879 //*************************************************************************************************
1880 
1881 
1882 //*************************************************************************************************
1894 template< typename Type // Data type of the vector
1895  , bool AF // Alignment flag
1896  , bool PF // Padding flag
1897  , bool TF // Transpose flag
1898  , typename RT > // Result type
1900  CustomVector<Type,AF,PF,TF,RT>::load( size_t index ) const noexcept
1901 {
1902  if( AF )
1903  return loada( index );
1904  else
1905  return loadu( index );
1906 }
1907 //*************************************************************************************************
1908 
1909 
1910 //*************************************************************************************************
1923 template< typename Type // Data type of the vector
1924  , bool AF // Alignment flag
1925  , bool PF // Padding flag
1926  , bool TF // Transpose flag
1927  , typename RT > // Result type
1929  CustomVector<Type,AF,PF,TF,RT>::loada( size_t index ) const noexcept
1930 {
1931  using blaze::loada;
1932 
1934 
1935  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
1936  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
1937  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
1938  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
1939 
1940  return loada( v_+index );
1941 }
1942 //*************************************************************************************************
1943 
1944 
1945 //*************************************************************************************************
1958 template< typename Type // Data type of the vector
1959  , bool AF // Alignment flag
1960  , bool PF // Padding flag
1961  , bool TF // Transpose flag
1962  , typename RT > // Result type
1964  CustomVector<Type,AF,PF,TF,RT>::loadu( size_t index ) const noexcept
1965 {
1966  using blaze::loadu;
1967 
1969 
1970  BLAZE_INTERNAL_ASSERT( index< size_, "Invalid vector access index" );
1971  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
1972 
1973  return loadu( v_+index );
1974 }
1975 //*************************************************************************************************
1976 
1977 
1978 //*************************************************************************************************
1991 template< typename Type // Data type of the vector
1992  , bool AF // Alignment flag
1993  , bool PF // Padding flag
1994  , bool TF // Transpose flag
1995  , typename RT > // Result type
1997  CustomVector<Type,AF,PF,TF,RT>::store( size_t index, const SIMDType& value ) noexcept
1998 {
1999  if( AF )
2000  storea( index, value );
2001  else
2002  storeu( index, value );
2003 }
2004 //*************************************************************************************************
2005 
2006 
2007 //*************************************************************************************************
2020 template< typename Type // Data type of the vector
2021  , bool AF // Alignment flag
2022  , bool PF // Padding flag
2023  , bool TF // Transpose flag
2024  , typename RT > // Result type
2026  CustomVector<Type,AF,PF,TF,RT>::storea( size_t index, const SIMDType& value ) noexcept
2027 {
2028  using blaze::storea;
2029 
2031 
2032  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
2033  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2034  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
2035  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
2036 
2037  storea( v_+index, value );
2038 }
2039 //*************************************************************************************************
2040 
2041 
2042 //*************************************************************************************************
2055 template< typename Type // Data type of the vector
2056  , bool AF // Alignment flag
2057  , bool PF // Padding flag
2058  , bool TF // Transpose flag
2059  , typename RT > // Result type
2061  CustomVector<Type,AF,PF,TF,RT>::storeu( size_t index, const SIMDType& value ) noexcept
2062 {
2063  using blaze::storeu;
2064 
2066 
2067  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
2068  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2069 
2070  storeu( v_+index, value );
2071 }
2072 //*************************************************************************************************
2073 
2074 
2075 //*************************************************************************************************
2089 template< typename Type // Data type of the vector
2090  , bool AF // Alignment flag
2091  , bool PF // Padding flag
2092  , bool TF // Transpose flag
2093  , typename RT > // Result type
2095  CustomVector<Type,AF,PF,TF,RT>::stream( size_t index, const SIMDType& value ) noexcept
2096 {
2097  using blaze::stream;
2098 
2100 
2101  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
2102  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2103  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
2104  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
2105 
2106  stream( v_+index, value );
2107 }
2108 //*************************************************************************************************
2109 
2110 
2111 //*************************************************************************************************
2122 template< typename Type // Data type of the vector
2123  , bool AF // Alignment flag
2124  , bool PF // Padding flag
2125  , bool TF // Transpose flag
2126  , typename RT > // Result type
2127 template< typename VT > // Type of the right-hand side dense vector
2130 {
2131  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2132 
2133  const size_t ipos( size_ & size_t(-2) );
2134  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2135 
2136  for( size_t i=0UL; i<ipos; i+=2UL ) {
2137  v_[i ] = (~rhs)[i ];
2138  v_[i+1UL] = (~rhs)[i+1UL];
2139  }
2140  if( ipos < (~rhs).size() )
2141  v_[ipos] = (~rhs)[ipos];
2142 }
2143 //*************************************************************************************************
2144 
2145 
2146 //*************************************************************************************************
2157 template< typename Type // Data type of the vector
2158  , bool AF // Alignment flag
2159  , bool PF // Padding flag
2160  , bool TF // Transpose flag
2161  , typename RT > // Result type
2162 template< typename VT > // Type of the right-hand side dense vector
2165 {
2167 
2168  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2169 
2170  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2171  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2172 
2173  if( AF && useStreaming && size_ > ( cacheSize/( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
2174  {
2175  size_t i( 0UL );
2176 
2177  for( ; i<ipos; i+=SIMDSIZE ) {
2178  stream( i, (~rhs).load(i) );
2179  }
2180  for( ; i<size_; ++i ) {
2181  v_[i] = (~rhs)[i];
2182  }
2183  }
2184  else
2185  {
2186  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
2187  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2188  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2189 
2190  size_t i( 0UL );
2191  ConstIterator_t<VT> it( (~rhs).begin() );
2192 
2193  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2194  store( i , it.load() ); it += SIMDSIZE;
2195  store( i+SIMDSIZE , it.load() ); it += SIMDSIZE;
2196  store( i+SIMDSIZE*2UL, it.load() ); it += SIMDSIZE;
2197  store( i+SIMDSIZE*3UL, it.load() ); it += SIMDSIZE;
2198  }
2199  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2200  store( i, it.load() );
2201  }
2202  for( ; i<size_; ++i, ++it ) {
2203  v_[i] = *it;
2204  }
2205  }
2206 }
2207 //*************************************************************************************************
2208 
2209 
2210 //*************************************************************************************************
2221 template< typename Type // Data type of the vector
2222  , bool AF // Alignment flag
2223  , bool PF // Padding flag
2224  , bool TF // Transpose flag
2225  , typename RT > // Result type
2226 template< typename VT > // Type of the right-hand side sparse vector
2228 {
2229  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2230 
2231  for( auto element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2232  v_[element->index()] = element->value();
2233 }
2234 //*************************************************************************************************
2235 
2236 
2237 //*************************************************************************************************
2248 template< typename Type // Data type of the vector
2249  , bool AF // Alignment flag
2250  , bool PF // Padding flag
2251  , bool TF // Transpose flag
2252  , typename RT > // Result type
2253 template< typename VT > // Type of the right-hand side dense vector
2256 {
2257  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2258 
2259  const size_t ipos( size_ & size_t(-2) );
2260  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2261 
2262  for( size_t i=0UL; i<ipos; i+=2UL ) {
2263  v_[i ] += (~rhs)[i ];
2264  v_[i+1UL] += (~rhs)[i+1UL];
2265  }
2266  if( ipos < (~rhs).size() )
2267  v_[ipos] += (~rhs)[ipos];
2268 }
2269 //*************************************************************************************************
2270 
2271 
2272 //*************************************************************************************************
2283 template< typename Type // Data type of the vector
2284  , bool AF // Alignment flag
2285  , bool PF // Padding flag
2286  , bool TF // Transpose flag
2287  , typename RT > // Result type
2288 template< typename VT > // Type of the right-hand side dense vector
2291 {
2293 
2294  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2295 
2296  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2297  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2298 
2299  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
2300  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2301  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2302 
2303  size_t i( 0UL );
2304  ConstIterator_t<VT> it( (~rhs).begin() );
2305 
2306  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2307  store( i , load(i ) + it.load() ); it += SIMDSIZE;
2308  store( i+SIMDSIZE , load(i+SIMDSIZE ) + it.load() ); it += SIMDSIZE;
2309  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) + it.load() ); it += SIMDSIZE;
2310  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) + it.load() ); it += SIMDSIZE;
2311  }
2312  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2313  store( i, load(i) + it.load() );
2314  }
2315  for( ; i<size_; ++i, ++it ) {
2316  v_[i] += *it;
2317  }
2318 }
2319 //*************************************************************************************************
2320 
2321 
2322 //*************************************************************************************************
2333 template< typename Type // Data type of the vector
2334  , bool AF // Alignment flag
2335  , bool PF // Padding flag
2336  , bool TF // Transpose flag
2337  , typename RT > // Result type
2338 template< typename VT > // Type of the right-hand side sparse vector
2340 {
2341  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2342 
2343  for( auto element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2344  v_[element->index()] += element->value();
2345 }
2346 //*************************************************************************************************
2347 
2348 
2349 //*************************************************************************************************
2360 template< typename Type // Data type of the vector
2361  , bool AF // Alignment flag
2362  , bool PF // Padding flag
2363  , bool TF // Transpose flag
2364  , typename RT > // Result type
2365 template< typename VT > // Type of the right-hand side dense vector
2368 {
2369  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2370 
2371  const size_t ipos( size_ & size_t(-2) );
2372  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2373 
2374  for( size_t i=0UL; i<ipos; i+=2UL ) {
2375  v_[i ] -= (~rhs)[i ];
2376  v_[i+1UL] -= (~rhs)[i+1UL];
2377  }
2378  if( ipos < (~rhs).size() )
2379  v_[ipos] -= (~rhs)[ipos];
2380 }
2381 //*************************************************************************************************
2382 
2383 
2384 //*************************************************************************************************
2395 template< typename Type // Data type of the vector
2396  , bool AF // Alignment flag
2397  , bool PF // Padding flag
2398  , bool TF // Transpose flag
2399  , typename RT > // Result type
2400 template< typename VT > // Type of the right-hand side dense vector
2403 {
2405 
2406  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2407 
2408  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2409  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2410 
2411  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
2412  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2413  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2414 
2415  size_t i( 0UL );
2416  ConstIterator_t<VT> it( (~rhs).begin() );
2417 
2418  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2419  store( i , load(i ) - it.load() ); it += SIMDSIZE;
2420  store( i+SIMDSIZE , load(i+SIMDSIZE ) - it.load() ); it += SIMDSIZE;
2421  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) - it.load() ); it += SIMDSIZE;
2422  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) - it.load() ); it += SIMDSIZE;
2423  }
2424  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2425  store( i, load(i) - it.load() );
2426  }
2427  for( ; i<size_; ++i, ++it ) {
2428  v_[i] -= *it;
2429  }
2430 }
2431 //*************************************************************************************************
2432 
2433 
2434 //*************************************************************************************************
2445 template< typename Type // Data type of the vector
2446  , bool AF // Alignment flag
2447  , bool PF // Padding flag
2448  , bool TF // Transpose flag
2449  , typename RT > // Result type
2450 template< typename VT > // Type of the right-hand side sparse vector
2452 {
2453  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2454 
2455  for( auto element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2456  v_[element->index()] -= element->value();
2457 }
2458 //*************************************************************************************************
2459 
2460 
2461 //*************************************************************************************************
2472 template< typename Type // Data type of the vector
2473  , bool AF // Alignment flag
2474  , bool PF // Padding flag
2475  , bool TF // Transpose flag
2476  , typename RT > // Result type
2477 template< typename VT > // Type of the right-hand side dense vector
2480 {
2481  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2482 
2483  const size_t ipos( size_ & size_t(-2) );
2484  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2485 
2486  for( size_t i=0UL; i<ipos; i+=2UL ) {
2487  v_[i ] *= (~rhs)[i ];
2488  v_[i+1UL] *= (~rhs)[i+1UL];
2489  }
2490  if( ipos < (~rhs).size() )
2491  v_[ipos] *= (~rhs)[ipos];
2492 }
2493 //*************************************************************************************************
2494 
2495 
2496 //*************************************************************************************************
2507 template< typename Type // Data type of the vector
2508  , bool AF // Alignment flag
2509  , bool PF // Padding flag
2510  , bool TF // Transpose flag
2511  , typename RT > // Result type
2512 template< typename VT > // Type of the right-hand side dense vector
2515 {
2517 
2518  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2519 
2520  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2521  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2522 
2523  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
2524  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2525  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2526 
2527  size_t i( 0UL );
2528  ConstIterator_t<VT> it( (~rhs).begin() );
2529 
2530  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2531  store( i , load(i ) * it.load() ); it += SIMDSIZE;
2532  store( i+SIMDSIZE , load(i+SIMDSIZE ) * it.load() ); it += SIMDSIZE;
2533  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) * it.load() ); it += SIMDSIZE;
2534  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) * it.load() ); it += SIMDSIZE;
2535  }
2536  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2537  store( i, load(i) * it.load() );
2538  }
2539  for( ; i<size_; ++i, ++it ) {
2540  v_[i] *= *it;
2541  }
2542 }
2543 //*************************************************************************************************
2544 
2545 
2546 //*************************************************************************************************
2557 template< typename Type // Data type of the vector
2558  , bool AF // Alignment flag
2559  , bool PF // Padding flag
2560  , bool TF // Transpose flag
2561  , typename RT > // Result type
2562 template< typename VT > // Type of the right-hand side sparse vector
2564 {
2565  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2566 
2567  const ResultType tmp( serial( *this ) );
2568 
2569  reset();
2570 
2571  for( auto element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2572  v_[element->index()] = tmp[element->index()] * element->value();
2573 }
2574 //*************************************************************************************************
2575 
2576 
2577 //*************************************************************************************************
2588 template< typename Type // Data type of the vector
2589  , bool AF // Alignment flag
2590  , bool PF // Padding flag
2591  , bool TF // Transpose flag
2592  , typename RT > // Result type
2593 template< typename VT > // Type of the right-hand side dense vector
2596 {
2597  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2598 
2599  const size_t ipos( size_ & size_t(-2) );
2600  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2601 
2602  for( size_t i=0UL; i<ipos; i+=2UL ) {
2603  v_[i ] /= (~rhs)[i ];
2604  v_[i+1UL] /= (~rhs)[i+1UL];
2605  }
2606  if( ipos < (~rhs).size() )
2607  v_[ipos] /= (~rhs)[ipos];
2608 }
2609 //*************************************************************************************************
2610 
2611 
2612 //*************************************************************************************************
2623 template< typename Type // Data type of the vector
2624  , bool AF // Alignment flag
2625  , bool PF // Padding flag
2626  , bool TF // Transpose flag
2627  , typename RT > // Result type
2628 template< typename VT > // Type of the right-hand side dense vector
2631 {
2633 
2634  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2635 
2636  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2637  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2638 
2639  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
2640  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2641  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2642 
2643  size_t i( 0UL );
2644  ConstIterator_t<VT> it( (~rhs).begin() );
2645 
2646  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2647  store( i , load(i ) / it.load() ); it += SIMDSIZE;
2648  store( i+SIMDSIZE , load(i+SIMDSIZE ) / it.load() ); it += SIMDSIZE;
2649  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) / it.load() ); it += SIMDSIZE;
2650  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) / it.load() ); it += SIMDSIZE;
2651  }
2652  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2653  store( i, load(i) / it.load() );
2654  }
2655  for( ; i<size_; ++i, ++it ) {
2656  v_[i] /= *it;
2657  }
2658 }
2659 //*************************************************************************************************
2660 
2661 
2662 
2663 
2664 
2665 
2666 
2667 
2668 //=================================================================================================
2669 //
2670 // CLASS TEMPLATE SPECIALIZATION FOR PADDED VECTORS
2671 //
2672 //=================================================================================================
2673 
2674 //*************************************************************************************************
2682 template< typename Type // Data type of the vector
2683  , bool AF // Alignment flag
2684  , bool TF // Transpose flag
2685  , typename RT > // Result type
2686 class CustomVector<Type,AF,padded,TF,RT>
2687  : public DenseVector< CustomVector<Type,AF,padded,TF,RT>, TF >
2688 {
2689  public:
2690  //**Type definitions****************************************************************************
2691  using This = CustomVector<Type,AF,padded,TF,RT>;
2692  using BaseType = DenseVector<This,TF>;
2693 
2695  using ResultType = RT;
2696 
2698  using TransposeType = TransposeType_t<ResultType>;
2699 
2700  using ElementType = Type;
2701  using SIMDType = SIMDTrait_t<ElementType>;
2702  using ReturnType = const Type&;
2703  using CompositeType = const CustomVector&;
2704 
2705  using Reference = Type&;
2706  using ConstReference = const Type&;
2707  using Pointer = Type*;
2708  using ConstPointer = const Type*;
2709 
2710  using Iterator = DenseIterator<Type,AF>;
2711  using ConstIterator = DenseIterator<const Type,AF>;
2712  //**********************************************************************************************
2713 
2714  //**Rebind struct definition********************************************************************
2717  template< typename NewType > // Data type of the other vector
2718  struct Rebind {
2719  using RRT = Rebind_t< RT, RemoveConst_t<NewType> >;
2720  using Other = CustomVector<NewType,AF,padded,TF,RRT>;
2721  };
2722  //**********************************************************************************************
2723 
2724  //**Resize struct definition********************************************************************
2727  template< size_t NewN > // Number of elements of the other vector
2728  struct Resize {
2729  using RRT = Resize_t<RT,NewN>;
2730  using Other = CustomVector<Type,AF,padded,TF,RRT>;
2731  };
2732  //**********************************************************************************************
2733 
2734  //**Compilation flags***************************************************************************
2736 
2740  static constexpr bool simdEnabled = IsVectorizable_v<Type>;
2741 
2743 
2746  static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
2747  //**********************************************************************************************
2748 
2749  //**Constructors********************************************************************************
2752  explicit inline CustomVector();
2753  explicit inline CustomVector( Type* ptr, size_t n, size_t nn );
2754 
2755  inline CustomVector( const CustomVector& v );
2756  inline CustomVector( CustomVector&& v ) noexcept;
2758  //**********************************************************************************************
2759 
2760  //**Destructor**********************************************************************************
2763  ~CustomVector() = default;
2765  //**********************************************************************************************
2766 
2767  //**Data access functions***********************************************************************
2770  inline Reference operator[]( size_t index ) noexcept;
2771  inline ConstReference operator[]( size_t index ) const noexcept;
2772  inline Reference at( size_t index );
2773  inline ConstReference at( size_t index ) const;
2774  inline Pointer data () noexcept;
2775  inline ConstPointer data () const noexcept;
2776  inline Iterator begin () noexcept;
2777  inline ConstIterator begin () const noexcept;
2778  inline ConstIterator cbegin() const noexcept;
2779  inline Iterator end () noexcept;
2780  inline ConstIterator end () const noexcept;
2781  inline ConstIterator cend () const noexcept;
2783  //**********************************************************************************************
2784 
2785  //**Assignment operators************************************************************************
2788  inline CustomVector& operator=( const Type& rhs );
2789  inline CustomVector& operator=( initializer_list<Type> list );
2790 
2791  template< typename Other, size_t N >
2792  inline CustomVector& operator=( const Other (&array)[N] );
2793 
2794  inline CustomVector& operator=( const CustomVector& rhs );
2795  inline CustomVector& operator=( CustomVector&& rhs ) noexcept;
2796 
2797  template< typename VT > inline CustomVector& operator= ( const Vector<VT,TF>& rhs );
2798  template< typename VT > inline CustomVector& operator+=( const Vector<VT,TF>& rhs );
2799  template< typename VT > inline CustomVector& operator-=( const Vector<VT,TF>& rhs );
2800  template< typename VT > inline CustomVector& operator*=( const Vector<VT,TF>& rhs );
2801  template< typename VT > inline CustomVector& operator/=( const DenseVector<VT,TF>& rhs );
2802  template< typename VT > inline CustomVector& operator%=( const Vector<VT,TF>& rhs );
2804  //**********************************************************************************************
2805 
2806  //**Utility functions***************************************************************************
2809  inline size_t size() const noexcept;
2810  inline size_t spacing() const noexcept;
2811  inline size_t capacity() const noexcept;
2812  inline size_t nonZeros() const;
2813  inline void reset();
2814  inline void clear();
2815  inline void swap( CustomVector& v ) noexcept;
2817  //**********************************************************************************************
2818 
2819  //**Numeric functions***************************************************************************
2822  template< typename Other > inline CustomVector& scale( const Other& scalar );
2824  //**********************************************************************************************
2825 
2826  //**Resource management functions***************************************************************
2829  inline void reset( Type* ptr, size_t n, size_t nn );
2831  //**********************************************************************************************
2832 
2833  private:
2834  //**********************************************************************************************
2836  template< typename VT >
2837  static constexpr bool VectorizedAssign_v =
2838  ( useOptimizedKernels &&
2839  simdEnabled && VT::simdEnabled &&
2840  IsSIMDCombinable_v< Type, ElementType_t<VT> > );
2841  //**********************************************************************************************
2842 
2843  //**********************************************************************************************
2845  template< typename VT >
2846  static constexpr bool VectorizedAddAssign_v =
2847  ( useOptimizedKernels &&
2848  simdEnabled && VT::simdEnabled &&
2849  IsSIMDCombinable_v< Type, ElementType_t<VT> > &&
2850  HasSIMDAdd_v< Type, ElementType_t<VT> > );
2851  //**********************************************************************************************
2852 
2853  //**********************************************************************************************
2855  template< typename VT >
2856  static constexpr bool VectorizedSubAssign_v =
2857  ( useOptimizedKernels &&
2858  simdEnabled && VT::simdEnabled &&
2859  IsSIMDCombinable_v< Type, ElementType_t<VT> > &&
2860  HasSIMDSub_v< Type, ElementType_t<VT> > );
2861  //**********************************************************************************************
2862 
2863  //**********************************************************************************************
2865  template< typename VT >
2866  static constexpr bool VectorizedMultAssign_v =
2867  ( useOptimizedKernels &&
2868  simdEnabled && VT::simdEnabled &&
2869  IsSIMDCombinable_v< Type, ElementType_t<VT> > &&
2870  HasSIMDMult_v< Type, ElementType_t<VT> > );
2871  //**********************************************************************************************
2872 
2873  //**********************************************************************************************
2875  template< typename VT >
2876  static constexpr bool VectorizedDivAssign_v =
2877  ( useOptimizedKernels &&
2878  simdEnabled && VT::simdEnabled &&
2879  IsSIMDCombinable_v< Type, ElementType_t<VT> > &&
2880  HasSIMDDiv_v< Type, ElementType_t<VT> > );
2881  //**********************************************************************************************
2882 
2883  //**SIMD properties*****************************************************************************
2885  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
2886  //**********************************************************************************************
2887 
2888  public:
2889  //**Expression template evaluation functions****************************************************
2892  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
2893  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
2894 
2895  inline bool isAligned () const noexcept;
2896  inline bool canSMPAssign() const noexcept;
2897 
2898  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
2899  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
2900  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
2901 
2902  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
2903  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
2904  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
2905  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
2906 
2907  template< typename VT >
2908  inline auto assign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
2909 
2910  template< typename VT >
2911  inline auto assign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
2912 
2913  template< typename VT > inline void assign( const SparseVector<VT,TF>& rhs );
2914 
2915  template< typename VT >
2916  inline auto addAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
2917 
2918  template< typename VT >
2919  inline auto addAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
2920 
2921  template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
2922 
2923  template< typename VT >
2924  inline auto subAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
2925 
2926  template< typename VT >
2927  inline auto subAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
2928 
2929  template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
2930 
2931  template< typename VT >
2932  inline auto multAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
2933 
2934  template< typename VT >
2935  inline auto multAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
2936 
2937  template< typename VT > inline void multAssign( const SparseVector<VT,TF>& rhs );
2938 
2939  template< typename VT >
2940  inline auto divAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
2941 
2942  template< typename VT >
2943  inline auto divAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT> >;
2945  //**********************************************************************************************
2946 
2947  private:
2948  //**Member variables****************************************************************************
2951  size_t size_;
2952  size_t capacity_;
2953  Type* v_;
2954 
2960  //**********************************************************************************************
2961 
2962  //**Compile time checks*************************************************************************
2968  //**********************************************************************************************
2969 };
2971 //*************************************************************************************************
2972 
2973 
2974 
2975 
2976 //=================================================================================================
2977 //
2978 // CONSTRUCTORS
2979 //
2980 //=================================================================================================
2981 
2982 //*************************************************************************************************
2986 template< typename Type // Data type of the vector
2987  , bool AF // Alignment flag
2988  , bool TF // Transpose flag
2989  , typename RT > // Result type
2990 inline CustomVector<Type,AF,padded,TF,RT>::CustomVector()
2991  : size_ ( 0UL ) // The size/dimension of the vector
2992  , capacity_( 0UL ) // The maximum capacity of the vector
2993  , v_ ( nullptr ) // The custom array of elements
2994 {}
2996 //*************************************************************************************************
2997 
2998 
2999 //*************************************************************************************************
3021 template< typename Type // Data type of the vector
3022  , bool AF // Alignment flag
3023  , bool TF // Transpose flag
3024  , typename RT > // Result type
3025 inline CustomVector<Type,AF,padded,TF,RT>::CustomVector( Type* ptr, size_t n, size_t nn )
3026  : size_ ( n ) // The size/dimension of the vector
3027  , capacity_( nn ) // The maximum capacity of the vector
3028  , v_ ( ptr ) // The custom array of elements
3029 {
3030  using blaze::clear;
3031 
3032  if( ptr == nullptr ) {
3033  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3034  }
3035 
3036  if( AF && !checkAlignment( ptr ) ) {
3037  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3038  }
3039 
3040  if( IsVectorizable_v<Type> && capacity_ < nextMultiple<size_t>( size_, SIMDSIZE ) ) {
3041  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded vector" );
3042  }
3043 
3044  if( IsVectorizable_v<Type> ) {
3045  for( size_t i=size_; i<capacity_; ++i )
3046  clear( v_[i] );
3047  }
3048 }
3050 //*************************************************************************************************
3051 
3052 
3053 //*************************************************************************************************
3061 template< typename Type // Data type of the vector
3062  , bool AF // Alignment flag
3063  , bool TF // Transpose flag
3064  , typename RT > // Result type
3065 inline CustomVector<Type,AF,padded,TF,RT>::CustomVector( const CustomVector& v )
3066  : size_ ( v.size_ ) // The size/dimension of the vector
3067  , capacity_( v.capacity_ ) // The maximum capacity of the vector
3068  , v_ ( v.v_ ) // The custom array of elements
3069 {}
3071 //*************************************************************************************************
3072 
3073 
3074 //*************************************************************************************************
3080 template< typename Type // Data type of the vector
3081  , bool AF // Alignment flag
3082  , bool TF // Transpose flag
3083  , typename RT > // Result type
3084 inline CustomVector<Type,AF,padded,TF,RT>::CustomVector( CustomVector&& v ) noexcept
3085  : size_ ( v.size_ ) // The size/dimension of the vector
3086  , capacity_( v.capacity_ ) // The maximum capacity of the vector
3087  , v_ ( v.v_ ) // The custom array of elements
3088 {
3089  v.size_ = 0UL;
3090  v.capacity_ = 0UL;
3091  v.v_ = nullptr;
3092 
3093  BLAZE_INTERNAL_ASSERT( v.data() == nullptr, "Invalid data reference detected" );
3094 }
3096 //*************************************************************************************************
3097 
3098 
3099 
3100 
3101 //=================================================================================================
3102 //
3103 // DATA ACCESS FUNCTIONS
3104 //
3105 //=================================================================================================
3106 
3107 //*************************************************************************************************
3117 template< typename Type // Data type of the vector
3118  , bool AF // Alignment flag
3119  , bool TF // Transpose flag
3120  , typename RT > // Result type
3122  CustomVector<Type,AF,padded,TF,RT>::operator[]( size_t index ) noexcept
3123 {
3124  BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
3125  return v_[index];
3126 }
3128 //*************************************************************************************************
3129 
3130 
3131 //*************************************************************************************************
3141 template< typename Type // Data type of the vector
3142  , bool AF // Alignment flag
3143  , bool TF // Transpose flag
3144  , typename RT > // Result type
3146  CustomVector<Type,AF,padded,TF,RT>::operator[]( size_t index ) const noexcept
3147 {
3148  BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
3149  return v_[index];
3150 }
3152 //*************************************************************************************************
3153 
3154 
3155 //*************************************************************************************************
3166 template< typename Type // Data type of the vector
3167  , bool AF // Alignment flag
3168  , bool TF // Transpose flag
3169  , typename RT > // Result type
3172 {
3173  if( index >= size_ ) {
3174  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
3175  }
3176  return (*this)[index];
3177 }
3179 //*************************************************************************************************
3180 
3181 
3182 //*************************************************************************************************
3193 template< typename Type // Data type of the vector
3194  , bool AF // Alignment flag
3195  , bool TF // Transpose flag
3196  , typename RT > // Result type
3198  CustomVector<Type,AF,padded,TF,RT>::at( size_t index ) const
3199 {
3200  if( index >= size_ ) {
3201  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
3202  }
3203  return (*this)[index];
3204 }
3206 //*************************************************************************************************
3207 
3208 
3209 //*************************************************************************************************
3217 template< typename Type // Data type of the vector
3218  , bool AF // Alignment flag
3219  , bool TF // Transpose flag
3220  , typename RT > // Result type
3223 {
3224  return v_;
3225 }
3227 //*************************************************************************************************
3228 
3229 
3230 //*************************************************************************************************
3238 template< typename Type // Data type of the vector
3239  , bool AF // Alignment flag
3240  , bool TF // Transpose flag
3241  , typename RT > // Result type
3244 {
3245  return v_;
3246 }
3248 //*************************************************************************************************
3249 
3250 
3251 //*************************************************************************************************
3257 template< typename Type // Data type of the vector
3258  , bool AF // Alignment flag
3259  , bool TF // Transpose flag
3260  , typename RT > // Result type
3263 {
3264  return Iterator( v_ );
3265 }
3267 //*************************************************************************************************
3268 
3269 
3270 //*************************************************************************************************
3276 template< typename Type // Data type of the vector
3277  , bool AF // Alignment flag
3278  , bool TF // Transpose flag
3279  , typename RT > // Result type
3282 {
3283  return ConstIterator( v_ );
3284 }
3286 //*************************************************************************************************
3287 
3288 
3289 //*************************************************************************************************
3295 template< typename Type // Data type of the vector
3296  , bool AF // Alignment flag
3297  , bool TF // Transpose flag
3298  , typename RT > // Result type
3301 {
3302  return ConstIterator( v_ );
3303 }
3305 //*************************************************************************************************
3306 
3307 
3308 //*************************************************************************************************
3314 template< typename Type // Data type of the vector
3315  , bool AF // Alignment flag
3316  , bool TF // Transpose flag
3317  , typename RT > // Result type
3320 {
3321  return Iterator( v_+size_ );
3322 }
3324 //*************************************************************************************************
3325 
3326 
3327 //*************************************************************************************************
3333 template< typename Type // Data type of the vector
3334  , bool AF // Alignment flag
3335  , bool TF // Transpose flag
3336  , typename RT > // Result type
3339 {
3340  return ConstIterator( v_+size_ );
3341 }
3343 //*************************************************************************************************
3344 
3345 
3346 //*************************************************************************************************
3352 template< typename Type // Data type of the vector
3353  , bool AF // Alignment flag
3354  , bool TF // Transpose flag
3355  , typename RT > // Result type
3358 {
3359  return ConstIterator( v_+size_ );
3360 }
3362 //*************************************************************************************************
3363 
3364 
3365 
3366 
3367 //=================================================================================================
3368 //
3369 // ASSIGNMENT OPERATORS
3370 //
3371 //=================================================================================================
3372 
3373 //*************************************************************************************************
3380 template< typename Type // Data type of the vector
3381  , bool AF // Alignment flag
3382  , bool TF // Transpose flag
3383  , typename RT > // Result type
3384 inline CustomVector<Type,AF,padded,TF,RT>&
3386 {
3387  for( size_t i=0UL; i<size_; ++i )
3388  v_[i] = rhs;
3389  return *this;
3390 }
3392 //*************************************************************************************************
3393 
3394 
3395 //*************************************************************************************************
3420 template< typename Type // Data type of the vector
3421  , bool AF // Alignment flag
3422  , bool TF // Transpose flag
3423  , typename RT > // Result type
3424 inline CustomVector<Type,AF,padded,TF,RT>&
3425  CustomVector<Type,AF,padded,TF,RT>::operator=( initializer_list<Type> list )
3426 {
3427  if( list.size() > size_ ) {
3428  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom vector" );
3429  }
3430 
3431  std::fill( std::copy( list.begin(), list.end(), v_ ), v_+capacity_, Type() );
3432 
3433  return *this;
3434 }
3436 //*************************************************************************************************
3437 
3438 
3439 //*************************************************************************************************
3467 template< typename Type // Data type of the vector
3468  , bool AF // Alignment flag
3469  , bool TF // Transpose flag
3470  , typename RT > // Result type
3471 template< typename Other // Data type of the initialization array
3472  , size_t N > // Dimension of the initialization array
3473 inline CustomVector<Type,AF,padded,TF,RT>&
3474  CustomVector<Type,AF,padded,TF,RT>::operator=( const Other (&array)[N] )
3475 {
3476  if( size_ != N ) {
3477  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
3478  }
3479 
3480  for( size_t i=0UL; i<N; ++i )
3481  v_[i] = array[i];
3482 
3483  return *this;
3484 }
3486 //*************************************************************************************************
3487 
3488 
3489 //*************************************************************************************************
3500 template< typename Type // Data type of the vector
3501  , bool AF // Alignment flag
3502  , bool TF // Transpose flag
3503  , typename RT > // Result type
3504 inline CustomVector<Type,AF,padded,TF,RT>&
3505  CustomVector<Type,AF,padded,TF,RT>::operator=( const CustomVector& rhs )
3506 {
3507  if( rhs.size() != size_ ) {
3508  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3509  }
3510 
3511  smpAssign( *this, ~rhs );
3512 
3513  return *this;
3514 }
3516 //*************************************************************************************************
3517 
3518 
3519 //*************************************************************************************************
3526 template< typename Type // Data type of the vector
3527  , bool AF // Alignment flag
3528  , bool TF // Transpose flag
3529  , typename RT > // Result type
3530 inline CustomVector<Type,AF,padded,TF,RT>&
3531  CustomVector<Type,AF,padded,TF,RT>::operator=( CustomVector&& rhs ) noexcept
3532 {
3533  size_ = rhs.size_;
3534  capacity_ = rhs.capacity_;
3535  v_ = rhs.v_;
3536 
3537  rhs.size_ = 0UL;
3538  rhs.capacity_ = 0UL;
3539  rhs.v_ = nullptr;
3540 
3541  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
3542 
3543  return *this;
3544 }
3546 //*************************************************************************************************
3547 
3548 
3549 //*************************************************************************************************
3560 template< typename Type // Data type of the vector
3561  , bool AF // Alignment flag
3562  , bool TF // Transpose flag
3563  , typename RT > // Result type
3564 template< typename VT > // Type of the right-hand side vector
3565 inline CustomVector<Type,AF,padded,TF,RT>&
3566  CustomVector<Type,AF,padded,TF,RT>::operator=( const Vector<VT,TF>& rhs )
3567 {
3568  if( (~rhs).size() != size_ ) {
3569  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3570  }
3571 
3572  if( (~rhs).canAlias( this ) ) {
3573  const ResultType_t<VT> tmp( ~rhs );
3574  smpAssign( *this, tmp );
3575  }
3576  else {
3577  if( IsSparseVector_v<VT> )
3578  reset();
3579  smpAssign( *this, ~rhs );
3580  }
3581 
3582  return *this;
3583 }
3585 //*************************************************************************************************
3586 
3587 
3588 //*************************************************************************************************
3599 template< typename Type // Data type of the vector
3600  , bool AF // Alignment flag
3601  , bool TF // Transpose flag
3602  , typename RT > // Result type
3603 template< typename VT > // Type of the right-hand side vector
3604 inline CustomVector<Type,AF,padded,TF,RT>&
3605  CustomVector<Type,AF,padded,TF,RT>::operator+=( const Vector<VT,TF>& rhs )
3606 {
3607  if( (~rhs).size() != size_ ) {
3608  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3609  }
3610 
3611  if( (~rhs).canAlias( this ) ) {
3612  const ResultType_t<VT> tmp( ~rhs );
3613  smpAddAssign( *this, tmp );
3614  }
3615  else {
3616  smpAddAssign( *this, ~rhs );
3617  }
3618 
3619  return *this;
3620 }
3622 //*************************************************************************************************
3623 
3624 
3625 //*************************************************************************************************
3637 template< typename Type // Data type of the vector
3638  , bool AF // Alignment flag
3639  , bool TF // Transpose flag
3640  , typename RT > // Result type
3641 template< typename VT > // Type of the right-hand side vector
3642 inline CustomVector<Type,AF,padded,TF,RT>&
3643  CustomVector<Type,AF,padded,TF,RT>::operator-=( const Vector<VT,TF>& rhs )
3644 {
3645  if( (~rhs).size() != size_ ) {
3646  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3647  }
3648 
3649  if( (~rhs).canAlias( this ) ) {
3650  const ResultType_t<VT> tmp( ~rhs );
3651  smpSubAssign( *this, tmp );
3652  }
3653  else {
3654  smpSubAssign( *this, ~rhs );
3655  }
3656 
3657  return *this;
3658 }
3660 //*************************************************************************************************
3661 
3662 
3663 //*************************************************************************************************
3675 template< typename Type // Data type of the vector
3676  , bool AF // Alignment flag
3677  , bool TF // Transpose flag
3678  , typename RT > // Result type
3679 template< typename VT > // Type of the right-hand side vector
3680 inline CustomVector<Type,AF,padded,TF,RT>&
3681  CustomVector<Type,AF,padded,TF,RT>::operator*=( const Vector<VT,TF>& rhs )
3682 {
3685 
3686  using MultType = MultTrait_t< ResultType, ResultType_t<VT> >;
3687 
3690 
3691  if( (~rhs).size() != size_ ) {
3692  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3693  }
3694 
3695  if( IsSparseVector_v<VT> || (~rhs).canAlias( this ) ) {
3696  const MultType tmp( *this * (~rhs) );
3697  if( IsSparseVector_v<MultType> )
3698  reset();
3699  smpAssign( *this, tmp );
3700  }
3701  else {
3702  smpMultAssign( *this, ~rhs );
3703  }
3704 
3705  return *this;
3706 }
3708 //*************************************************************************************************
3709 
3710 
3711 //*************************************************************************************************
3722 template< typename Type // Data type of the vector
3723  , bool AF // Alignment flag
3724  , bool TF // Transpose flag
3725  , typename RT > // Result type
3726 template< typename VT > // Type of the right-hand side vector
3727 inline CustomVector<Type,AF,padded,TF,RT>&
3728  CustomVector<Type,AF,padded,TF,RT>::operator/=( const DenseVector<VT,TF>& rhs )
3729 {
3732 
3733  using DivType = DivTrait_t< ResultType, ResultType_t<VT> >;
3734 
3738 
3739  if( (~rhs).size() != size_ ) {
3740  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3741  }
3742 
3743  if( (~rhs).canAlias( this ) ) {
3744  const DivType tmp( *this / (~rhs) );
3745  smpAssign( *this, tmp );
3746  }
3747  else {
3748  smpDivAssign( *this, ~rhs );
3749  }
3750 
3751  return *this;
3752 }
3754 //*************************************************************************************************
3755 
3756 
3757 //*************************************************************************************************
3769 template< typename Type // Data type of the vector
3770  , bool AF // Alignment flag
3771  , bool TF // Transpose flag
3772  , typename RT > // Result type
3773 template< typename VT > // Type of the right-hand side vector
3774 inline CustomVector<Type,AF,padded,TF,RT>&
3775  CustomVector<Type,AF,padded,TF,RT>::operator%=( const Vector<VT,TF>& rhs )
3776 {
3777  using blaze::assign;
3778 
3781 
3782  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
3783 
3787 
3788  if( size_ != 3UL || (~rhs).size() != 3UL ) {
3789  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3790  }
3791 
3792  const CrossType tmp( *this % (~rhs) );
3793  assign( *this, tmp );
3794 
3795  return *this;
3796 }
3798 //*************************************************************************************************
3799 
3800 
3801 
3802 
3803 //=================================================================================================
3804 //
3805 // UTILITY FUNCTIONS
3806 //
3807 //=================================================================================================
3808 
3809 //*************************************************************************************************
3815 template< typename Type // Data type of the vector
3816  , bool AF // Alignment flag
3817  , bool TF // Transpose flag
3818  , typename RT > // Result type
3819 inline size_t CustomVector<Type,AF,padded,TF,RT>::size() const noexcept
3820 {
3821  return size_;
3822 }
3824 //*************************************************************************************************
3825 
3826 
3827 //*************************************************************************************************
3836 template< typename Type // Data type of the vector
3837  , bool AF // Alignment flag
3838  , bool TF // Transpose flag
3839  , typename RT > // Result type
3840 inline size_t CustomVector<Type,AF,padded,TF,RT>::spacing() const noexcept
3841 {
3842  return capacity_;
3843 }
3845 //*************************************************************************************************
3846 
3847 
3848 //*************************************************************************************************
3854 template< typename Type // Data type of the vector
3855  , bool AF // Alignment flag
3856  , bool TF // Transpose flag
3857  , typename RT > // Result type
3858 inline size_t CustomVector<Type,AF,padded,TF,RT>::capacity() const noexcept
3859 {
3860  return capacity_;
3861 }
3863 //*************************************************************************************************
3864 
3865 
3866 //*************************************************************************************************
3875 template< typename Type // Data type of the vector
3876  , bool AF // Alignment flag
3877  , bool TF // Transpose flag
3878  , typename RT > // Result type
3880 {
3881  size_t nonzeros( 0 );
3882 
3883  for( size_t i=0UL; i<size_; ++i ) {
3884  if( !isDefault( v_[i] ) )
3885  ++nonzeros;
3886  }
3887 
3888  return nonzeros;
3889 }
3891 //*************************************************************************************************
3892 
3893 
3894 //*************************************************************************************************
3900 template< typename Type // Data type of the vector
3901  , bool AF // Alignment flag
3902  , bool TF // Transpose flag
3903  , typename RT > // Result type
3905 {
3906  using blaze::clear;
3907  for( size_t i=0UL; i<size_; ++i )
3908  clear( v_[i] );
3909 }
3911 //*************************************************************************************************
3912 
3913 
3914 //*************************************************************************************************
3923 template< typename Type // Data type of the vector
3924  , bool AF // Alignment flag
3925  , bool TF // Transpose flag
3926  , typename RT > // Result type
3928 {
3929  size_ = 0UL;
3930  capacity_ = 0UL;
3931  v_ = nullptr;
3932 }
3934 //*************************************************************************************************
3935 
3936 
3937 //*************************************************************************************************
3944 template< typename Type // Data type of the vector
3945  , bool AF // Alignment flag
3946  , bool TF // Transpose flag
3947  , typename RT > // Result type
3948 inline void CustomVector<Type,AF,padded,TF,RT>::swap( CustomVector& v ) noexcept
3949 {
3950  using std::swap;
3951 
3952  swap( size_, v.size_ );
3953  swap( capacity_, v.capacity_ );
3954  swap( v_, v.v_ );
3955 }
3957 //*************************************************************************************************
3958 
3959 
3960 
3961 
3962 //=================================================================================================
3963 //
3964 // NUMERIC FUNCTIONS
3965 //
3966 //=================================================================================================
3967 
3968 //*************************************************************************************************
3990 template< typename Type // Data type of the vector
3991  , bool AF // Alignment flag
3992  , bool TF // Transpose flag
3993  , typename RT > // Result type
3994 template< typename Other > // Data type of the scalar value
3995 inline CustomVector<Type,AF,padded,TF,RT>&
3996  CustomVector<Type,AF,padded,TF,RT>::scale( const Other& scalar )
3997 {
3998  for( size_t i=0UL; i<size_; ++i )
3999  v_[i] *= scalar;
4000  return *this;
4001 }
4003 //*************************************************************************************************
4004 
4005 
4006 
4007 
4008 //=================================================================================================
4009 //
4010 // RESOURCE MANAGEMENT FUNCTIONS
4011 //
4012 //=================================================================================================
4013 
4014 //*************************************************************************************************
4037 template< typename Type // Data type of the vector
4038  , bool AF // Alignment flag
4039  , bool TF // Transpose flag
4040  , typename RT > // Result type
4041 inline void CustomVector<Type,AF,padded,TF,RT>::reset( Type* ptr, size_t n, size_t nn )
4042 {
4043  CustomVector tmp( ptr, n, nn );
4044  swap( tmp );
4045 }
4047 //*************************************************************************************************
4048 
4049 
4050 
4051 
4052 //=================================================================================================
4053 //
4054 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4055 //
4056 //=================================================================================================
4057 
4058 //*************************************************************************************************
4069 template< typename Type // Data type of the vector
4070  , bool AF // Alignment flag
4071  , bool TF // Transpose flag
4072  , typename RT > // Result type
4073 template< typename Other > // Data type of the foreign expression
4074 inline bool CustomVector<Type,AF,padded,TF,RT>::canAlias( const Other* alias ) const noexcept
4075 {
4076  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4077 }
4079 //*************************************************************************************************
4080 
4081 
4082 //*************************************************************************************************
4093 template< typename Type // Data type of the vector
4094  , bool AF // Alignment flag
4095  , bool TF // Transpose flag
4096  , typename RT > // Result type
4097 template< typename Other > // Data type of the foreign expression
4098 inline bool CustomVector<Type,AF,padded,TF,RT>::isAliased( const Other* alias ) const noexcept
4099 {
4100  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4101 }
4103 //*************************************************************************************************
4104 
4105 
4106 //*************************************************************************************************
4116 template< typename Type // Data type of the vector
4117  , bool AF // Alignment flag
4118  , bool TF // Transpose flag
4119  , typename RT > // Result type
4120 inline bool CustomVector<Type,AF,padded,TF,RT>::isAligned() const noexcept
4121 {
4122  return ( AF || checkAlignment( v_ ) );
4123 }
4125 //*************************************************************************************************
4126 
4127 
4128 //*************************************************************************************************
4139 template< typename Type // Data type of the vector
4140  , bool AF // Alignment flag
4141  , bool TF // Transpose flag
4142  , typename RT > // Result type
4143 inline bool CustomVector<Type,AF,padded,TF,RT>::canSMPAssign() const noexcept
4144 {
4145  return ( size() > SMP_DVECASSIGN_THRESHOLD );
4146 }
4148 //*************************************************************************************************
4149 
4150 
4151 //*************************************************************************************************
4164 template< typename Type // Data type of the vector
4165  , bool AF // Alignment flag
4166  , bool TF // Transpose flag
4167  , typename RT > // Result type
4169  CustomVector<Type,AF,padded,TF,RT>::load( size_t index ) const noexcept
4170 {
4171  if( AF )
4172  return loada( index );
4173  else
4174  return loadu( index );
4175 }
4177 //*************************************************************************************************
4178 
4179 
4180 //*************************************************************************************************
4194 template< typename Type // Data type of the vector
4195  , bool AF // Alignment flag
4196  , bool TF // Transpose flag
4197  , typename RT > // Result type
4199  CustomVector<Type,AF,padded,TF,RT>::loada( size_t index ) const noexcept
4200 {
4201  using blaze::loada;
4202 
4204 
4205  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4206  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4207  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
4208  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
4209 
4210  return loada( v_+index );
4211 }
4213 //*************************************************************************************************
4214 
4215 
4216 //*************************************************************************************************
4230 template< typename Type // Data type of the vector
4231  , bool AF // Alignment flag
4232  , bool TF // Transpose flag
4233  , typename RT > // Result type
4235  CustomVector<Type,AF,padded,TF,RT>::loadu( size_t index ) const noexcept
4236 {
4237  using blaze::loadu;
4238 
4240 
4241  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4242  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4243 
4244  return loadu( v_+index );
4245 }
4247 //*************************************************************************************************
4248 
4249 
4250 //*************************************************************************************************
4264 template< typename Type // Data type of the vector
4265  , bool AF // Alignment flag
4266  , bool TF // Transpose flag
4267  , typename RT > // Result type
4269  CustomVector<Type,AF,padded,TF,RT>::store( size_t index, const SIMDType& value ) noexcept
4270 {
4271  if( AF )
4272  storea( index, value );
4273  else
4274  storeu( index, value );
4275 }
4277 //*************************************************************************************************
4278 
4279 
4280 //*************************************************************************************************
4294 template< typename Type // Data type of the vector
4295  , bool AF // Alignment flag
4296  , bool TF // Transpose flag
4297  , typename RT > // Result type
4299  CustomVector<Type,AF,padded,TF,RT>::storea( size_t index, const SIMDType& value ) noexcept
4300 {
4301  using blaze::storea;
4302 
4304 
4305  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4306  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4307  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
4308  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
4309 
4310  storea( v_+index, value );
4311 }
4313 //*************************************************************************************************
4314 
4315 
4316 //*************************************************************************************************
4330 template< typename Type // Data type of the vector
4331  , bool AF // Alignment flag
4332  , bool TF // Transpose flag
4333  , typename RT > // Result type
4335  CustomVector<Type,AF,padded,TF,RT>::storeu( size_t index, const SIMDType& value ) noexcept
4336 {
4337  using blaze::storeu;
4338 
4340 
4341  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4342  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4343 
4344  storeu( v_+index, value );
4345 }
4347 //*************************************************************************************************
4348 
4349 
4350 //*************************************************************************************************
4365 template< typename Type // Data type of the vector
4366  , bool AF // Alignment flag
4367  , bool TF // Transpose flag
4368  , typename RT > // Result type
4370  CustomVector<Type,AF,padded,TF,RT>::stream( size_t index, const SIMDType& value ) noexcept
4371 {
4372  using blaze::stream;
4373 
4375 
4376  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4377  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4378  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
4379 
4380  stream( v_+index, value );
4381 }
4383 //*************************************************************************************************
4384 
4385 
4386 //*************************************************************************************************
4398 template< typename Type // Data type of the vector
4399  , bool AF // Alignment flag
4400  , bool TF // Transpose flag
4401  , typename RT > // Result type
4402 template< typename VT > // Type of the right-hand side dense vector
4403 inline auto CustomVector<Type,AF,padded,TF,RT>::assign( const DenseVector<VT,TF>& rhs )
4404  -> DisableIf_t< VectorizedAssign_v<VT> >
4405 {
4406  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4407 
4408  const size_t ipos( size_ & size_t(-2) );
4409  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4410 
4411  for( size_t i=0UL; i<ipos; i+=2UL ) {
4412  v_[i ] = (~rhs)[i ];
4413  v_[i+1UL] = (~rhs)[i+1UL];
4414  }
4415  if( ipos < (~rhs).size() )
4416  v_[ipos] = (~rhs)[ipos];
4417 }
4419 //*************************************************************************************************
4420 
4421 
4422 //*************************************************************************************************
4434 template< typename Type // Data type of the vector
4435  , bool AF // Alignment flag
4436  , bool TF // Transpose flag
4437  , typename RT > // Result type
4438 template< typename VT > // Type of the right-hand side dense vector
4439 inline auto CustomVector<Type,AF,padded,TF,RT>::assign( const DenseVector<VT,TF>& rhs )
4440  -> EnableIf_t< VectorizedAssign_v<VT> >
4441 {
4443 
4444  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4445 
4446  constexpr bool remainder( !IsPadded_v<VT> );
4447 
4448  const size_t ipos( ( remainder )?( size_ & size_t(-SIMDSIZE) ):( size_ ) );
4449  BLAZE_INTERNAL_ASSERT( !remainder || ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4450 
4451  if( AF && useStreaming && size_ > ( cacheSize/( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
4452  {
4453  size_t i( 0UL );
4454 
4455  for( ; i<ipos; i+=SIMDSIZE ) {
4456  stream( i, (~rhs).load(i) );
4457  }
4458  for( ; remainder && i<size_; ++i ) {
4459  v_[i] = (~rhs)[i];
4460  }
4461  }
4462  else
4463  {
4464  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
4465  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4466  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4467 
4468  size_t i( 0UL );
4469  ConstIterator_t<VT> it( (~rhs).begin() );
4470 
4471  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4472  store( i , it.load() ); it += SIMDSIZE;
4473  store( i+SIMDSIZE , it.load() ); it += SIMDSIZE;
4474  store( i+SIMDSIZE*2UL, it.load() ); it += SIMDSIZE;
4475  store( i+SIMDSIZE*3UL, it.load() ); it += SIMDSIZE;
4476  }
4477  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4478  store( i, it.load() );
4479  }
4480  for( ; remainder && i<size_; ++i, ++it ) {
4481  v_[i] = *it;
4482  }
4483  }
4484 }
4486 //*************************************************************************************************
4487 
4488 
4489 //*************************************************************************************************
4501 template< typename Type // Data type of the vector
4502  , bool AF // Alignment flag
4503  , bool TF // Transpose flag
4504  , typename RT > // Result type
4505 template< typename VT > // Type of the right-hand side sparse vector
4506 inline void CustomVector<Type,AF,padded,TF,RT>::assign( const SparseVector<VT,TF>& rhs )
4507 {
4508  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4509 
4510  for( auto element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4511  v_[element->index()] = element->value();
4512 }
4514 //*************************************************************************************************
4515 
4516 
4517 //*************************************************************************************************
4529 template< typename Type // Data type of the vector
4530  , bool AF // Alignment flag
4531  , bool TF // Transpose flag
4532  , typename RT > // Result type
4533 template< typename VT > // Type of the right-hand side dense vector
4534 inline auto CustomVector<Type,AF,padded,TF,RT>::addAssign( const DenseVector<VT,TF>& rhs )
4535  -> DisableIf_t< VectorizedAddAssign_v<VT> >
4536 {
4537  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4538 
4539  const size_t ipos( size_ & size_t(-2) );
4540  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4541 
4542  for( size_t i=0UL; i<ipos; i+=2UL ) {
4543  v_[i ] += (~rhs)[i ];
4544  v_[i+1UL] += (~rhs)[i+1UL];
4545  }
4546  if( ipos < (~rhs).size() )
4547  v_[ipos] += (~rhs)[ipos];
4548 }
4550 //*************************************************************************************************
4551 
4552 
4553 //*************************************************************************************************
4565 template< typename Type // Data type of the vector
4566  , bool AF // Alignment flag
4567  , bool TF // Transpose flag
4568  , typename RT > // Result type
4569 template< typename VT > // Type of the right-hand side dense vector
4570 inline auto CustomVector<Type,AF,padded,TF,RT>::addAssign( const DenseVector<VT,TF>& rhs )
4571  -> EnableIf_t< VectorizedAddAssign_v<VT> >
4572 {
4574 
4575  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4576 
4577  constexpr bool remainder( !IsPadded_v<VT> );
4578 
4579  const size_t ipos( ( remainder )?( size_ & size_t(-SIMDSIZE) ):( size_ ) );
4580  BLAZE_INTERNAL_ASSERT( !remainder || ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4581 
4582  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
4583  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4584  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4585 
4586  size_t i( 0UL );
4587  ConstIterator_t<VT> it( (~rhs).begin() );
4588 
4589  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4590  store( i , load(i ) + it.load() ); it += SIMDSIZE;
4591  store( i+SIMDSIZE , load(i+SIMDSIZE ) + it.load() ); it += SIMDSIZE;
4592  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) + it.load() ); it += SIMDSIZE;
4593  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) + it.load() ); it += SIMDSIZE;
4594  }
4595  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4596  store( i, load(i) + it.load() );
4597  }
4598  for( ; remainder && i<size_; ++i, ++it ) {
4599  v_[i] += *it;
4600  }
4601 }
4603 //*************************************************************************************************
4604 
4605 
4606 //*************************************************************************************************
4618 template< typename Type // Data type of the vector
4619  , bool AF // Alignment flag
4620  , bool TF // Transpose flag
4621  , typename RT > // Result type
4622 template< typename VT > // Type of the right-hand side sparse vector
4623 inline void CustomVector<Type,AF,padded,TF,RT>::addAssign( const SparseVector<VT,TF>& rhs )
4624 {
4625  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4626 
4627  for( auto element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4628  v_[element->index()] += element->value();
4629 }
4631 //*************************************************************************************************
4632 
4633 
4634 //*************************************************************************************************
4646 template< typename Type // Data type of the vector
4647  , bool AF // Alignment flag
4648  , bool TF // Transpose flag
4649  , typename RT > // Result type
4650 template< typename VT > // Type of the right-hand side dense vector
4651 inline auto CustomVector<Type,AF,padded,TF,RT>::subAssign( const DenseVector<VT,TF>& rhs )
4652  -> DisableIf_t< VectorizedSubAssign_v<VT> >
4653 {
4654  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4655 
4656  const size_t ipos( size_ & size_t(-2) );
4657  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4658 
4659  for( size_t i=0UL; i<ipos; i+=2UL ) {
4660  v_[i ] -= (~rhs)[i ];
4661  v_[i+1UL] -= (~rhs)[i+1UL];
4662  }
4663  if( ipos < (~rhs).size() )
4664  v_[ipos] -= (~rhs)[ipos];
4665 }
4667 //*************************************************************************************************
4668 
4669 
4670 //*************************************************************************************************
4682 template< typename Type // Data type of the vector
4683  , bool AF // Alignment flag
4684  , bool TF // Transpose flag
4685  , typename RT > // Result type
4686 template< typename VT > // Type of the right-hand side dense vector
4687 inline auto CustomVector<Type,AF,padded,TF,RT>::subAssign( const DenseVector<VT,TF>& rhs )
4688  -> EnableIf_t< VectorizedSubAssign_v<VT> >
4689 {
4691 
4692  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4693 
4694  constexpr bool remainder( !IsPadded_v<VT> );
4695 
4696  const size_t ipos( ( remainder )?( size_ & size_t(-SIMDSIZE) ):( size_ ) );
4697  BLAZE_INTERNAL_ASSERT( !remainder || ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4698 
4699  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
4700  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4701  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4702 
4703  size_t i( 0UL );
4704  ConstIterator_t<VT> it( (~rhs).begin() );
4705 
4706  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4707  store( i , load(i ) - it.load() ); it += SIMDSIZE;
4708  store( i+SIMDSIZE , load(i+SIMDSIZE ) - it.load() ); it += SIMDSIZE;
4709  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) - it.load() ); it += SIMDSIZE;
4710  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) - it.load() ); it += SIMDSIZE;
4711  }
4712  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4713  store( i, load(i) - it.load() );
4714  }
4715  for( ; remainder && i<size_; ++i, ++it ) {
4716  v_[i] -= *it;
4717  }
4718 }
4720 //*************************************************************************************************
4721 
4722 
4723 //*************************************************************************************************
4735 template< typename Type // Data type of the vector
4736  , bool AF // Alignment flag
4737  , bool TF // Transpose flag
4738  , typename RT > // Result type
4739 template< typename VT > // Type of the right-hand side sparse vector
4740 inline void CustomVector<Type,AF,padded,TF,RT>::subAssign( const SparseVector<VT,TF>& rhs )
4741 {
4742  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4743 
4744  for( auto element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4745  v_[element->index()] -= element->value();
4746 }
4748 //*************************************************************************************************
4749 
4750 
4751 //*************************************************************************************************
4763 template< typename Type // Data type of the vector
4764  , bool AF // Alignment flag
4765  , bool TF // Transpose flag
4766  , typename RT > // Result type
4767 template< typename VT > // Type of the right-hand side dense vector
4768 inline auto CustomVector<Type,AF,padded,TF,RT>::multAssign( const DenseVector<VT,TF>& rhs )
4769  -> DisableIf_t< VectorizedMultAssign_v<VT> >
4770 {
4771  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4772 
4773  const size_t ipos( size_ & size_t(-2) );
4774  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4775 
4776  for( size_t i=0UL; i<ipos; i+=2UL ) {
4777  v_[i ] *= (~rhs)[i ];
4778  v_[i+1UL] *= (~rhs)[i+1UL];
4779  }
4780  if( ipos < (~rhs).size() )
4781  v_[ipos] *= (~rhs)[ipos];
4782 }
4784 //*************************************************************************************************
4785 
4786 
4787 //*************************************************************************************************
4799 template< typename Type // Data type of the vector
4800  , bool AF // Alignment flag
4801  , bool TF // Transpose flag
4802  , typename RT > // Result type
4803 template< typename VT > // Type of the right-hand side dense vector
4804 inline auto CustomVector<Type,AF,padded,TF,RT>::multAssign( const DenseVector<VT,TF>& rhs )
4805  -> EnableIf_t< VectorizedMultAssign_v<VT> >
4806 {
4808 
4809  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4810 
4811  constexpr bool remainder( !IsPadded_v<VT> );
4812 
4813  const size_t ipos( ( remainder )?( size_ & size_t(-SIMDSIZE) ):( size_ ) );
4814  BLAZE_INTERNAL_ASSERT( !remainder || ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4815 
4816  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
4817  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4818  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4819 
4820  size_t i( 0UL );
4821  ConstIterator_t<VT> it( (~rhs).begin() );
4822 
4823  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4824  store( i , load(i ) * it.load() ); it += SIMDSIZE;
4825  store( i+SIMDSIZE , load(i+SIMDSIZE ) * it.load() ); it += SIMDSIZE;
4826  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) * it.load() ); it += SIMDSIZE;
4827  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) * it.load() ); it += SIMDSIZE;
4828  }
4829  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4830  store( i, load(i) * it.load() );
4831  }
4832  for( ; remainder && i<size_; ++i, ++it ) {
4833  v_[i] *= *it;
4834  }
4835 }
4837 //*************************************************************************************************
4838 
4839 
4840 //*************************************************************************************************
4852 template< typename Type // Data type of the vector
4853  , bool AF // Alignment flag
4854  , bool TF // Transpose flag
4855  , typename RT > // Result type
4856 template< typename VT > // Type of the right-hand side sparse vector
4857 inline void CustomVector<Type,AF,padded,TF,RT>::multAssign( const SparseVector<VT,TF>& rhs )
4858 {
4859  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4860 
4861  const ResultType tmp( serial( *this ) );
4862 
4863  reset();
4864 
4865  for( auto element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4866  v_[element->index()] = tmp[element->index()] * element->value();
4867 }
4869 //*************************************************************************************************
4870 
4871 
4872 //*************************************************************************************************
4884 template< typename Type // Data type of the vector
4885  , bool AF // Alignment flag
4886  , bool TF // Transpose flag
4887  , typename RT > // Result type
4888 template< typename VT > // Type of the right-hand side dense vector
4889 inline auto CustomVector<Type,AF,padded,TF,RT>::divAssign( const DenseVector<VT,TF>& rhs )
4890  -> DisableIf_t< VectorizedDivAssign_v<VT> >
4891 {
4892  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4893 
4894  const size_t ipos( size_ & size_t(-2) );
4895  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4896 
4897  for( size_t i=0UL; i<ipos; i+=2UL ) {
4898  v_[i ] /= (~rhs)[i ];
4899  v_[i+1UL] /= (~rhs)[i+1UL];
4900  }
4901  if( ipos < (~rhs).size() )
4902  v_[ipos] /= (~rhs)[ipos];
4903 }
4905 //*************************************************************************************************
4906 
4907 
4908 //*************************************************************************************************
4920 template< typename Type // Data type of the vector
4921  , bool AF // Alignment flag
4922  , bool TF // Transpose flag
4923  , typename RT > // Result type
4924 template< typename VT > // Type of the right-hand side dense vector
4925 inline auto CustomVector<Type,AF,padded,TF,RT>::divAssign( const DenseVector<VT,TF>& rhs )
4926  -> EnableIf_t< VectorizedDivAssign_v<VT> >
4927 {
4929 
4930  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4931 
4932  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4933  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4934 
4935  const size_t i4way( size_ & size_t( -(SIMDSIZE*4UL) ) );
4936  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4937  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4938 
4939  size_t i( 0UL );
4940  ConstIterator_t<VT> it( (~rhs).begin() );
4941 
4942  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4943  store( i , load(i ) / it.load() ); it += SIMDSIZE;
4944  store( i+SIMDSIZE , load(i+SIMDSIZE ) / it.load() ); it += SIMDSIZE;
4945  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) / it.load() ); it += SIMDSIZE;
4946  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) / it.load() ); it += SIMDSIZE;
4947  }
4948  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4949  store( i, load(i) / it.load() );
4950  }
4951  for( ; i<size_; ++i, ++it ) {
4952  v_[i] /= *it;
4953  }
4954 }
4956 //*************************************************************************************************
4957 
4958 
4959 
4960 
4961 
4962 
4963 
4964 
4965 //=================================================================================================
4966 //
4967 // CUSTOMVECTOR OPERATORS
4968 //
4969 //=================================================================================================
4970 
4971 //*************************************************************************************************
4974 template< typename Type, bool AF, bool PF, bool TF, typename RT >
4975 void reset( CustomVector<Type,AF,PF,TF,RT>& v );
4976 
4977 template< typename Type, bool AF, bool PF, bool TF, typename RT >
4978 void clear( CustomVector<Type,AF,PF,TF,RT>& v );
4979 
4980 template< bool RF, typename Type, bool AF, bool PF, bool TF, typename RT >
4981 bool isDefault( const CustomVector<Type,AF,PF,TF,RT>& v );
4982 
4983 template< typename Type, bool AF, bool PF, bool TF, typename RT >
4984 bool isIntact( const CustomVector<Type,AF,PF,TF,RT>& v ) noexcept;
4985 
4986 template< typename Type, bool AF, bool PF, bool TF, typename RT >
4987 void swap( CustomVector<Type,AF,PF,TF,RT>& a, CustomVector<Type,AF,PF,TF,RT>& b ) noexcept;
4989 //*************************************************************************************************
4990 
4991 
4992 //*************************************************************************************************
4999 template< typename Type // Data type of the vector
5000  , bool AF // Alignment flag
5001  , bool PF // Padding flag
5002  , bool TF // Transpose flag
5003  , typename RT > // Result type
5005 {
5006  v.reset();
5007 }
5008 //*************************************************************************************************
5009 
5010 
5011 //*************************************************************************************************
5018 template< typename Type // Data type of the vector
5019  , bool AF // Alignment flag
5020  , bool PF // Padding flag
5021  , bool TF // Transpose flag
5022  , typename RT > // Result type
5024 {
5025  v.clear();
5026 }
5027 //*************************************************************************************************
5028 
5029 
5030 //*************************************************************************************************
5058 template< bool RF // Relaxation flag
5059  , typename Type // Data type of the vector
5060  , bool AF // Alignment flag
5061  , bool PF // Padding flag
5062  , bool TF // Transpose flag
5063  , typename RT > // Result type
5065 {
5066  return ( v.size() == 0UL );
5067 }
5068 //*************************************************************************************************
5069 
5070 
5071 //*************************************************************************************************
5092 template< typename Type // Data type of the vector
5093  , bool AF // Alignment flag
5094  , bool PF // Padding flag
5095  , bool TF // Transpose flag
5096  , typename RT > // Result type
5097 inline bool isIntact( const CustomVector<Type,AF,PF,TF,RT>& v ) noexcept
5098 {
5099  return ( v.size() <= v.capacity() );
5100 }
5101 //*************************************************************************************************
5102 
5103 
5104 //*************************************************************************************************
5112 template< typename Type // Data type of the vector
5113  , bool AF // Alignment flag
5114  , bool PF // Padding flag
5115  , bool TF // Transpose flag
5116  , typename RT > // Result type
5118 {
5119  a.swap( b );
5120 }
5121 //*************************************************************************************************
5122 
5123 
5124 
5125 
5126 //=================================================================================================
5127 //
5128 // HASCONSTDATAACCESS SPECIALIZATIONS
5129 //
5130 //=================================================================================================
5131 
5132 //*************************************************************************************************
5134 template< typename T, bool AF, bool PF, bool TF, typename RT >
5135 struct HasConstDataAccess< CustomVector<T,AF,PF,TF,RT> >
5136  : public TrueType
5137 {};
5139 //*************************************************************************************************
5140 
5141 
5142 
5143 
5144 //=================================================================================================
5145 //
5146 // HASMUTABLEDATAACCESS SPECIALIZATIONS
5147 //
5148 //=================================================================================================
5149 
5150 //*************************************************************************************************
5152 template< typename T, bool AF, bool PF, bool TF, typename RT >
5153 struct HasMutableDataAccess< CustomVector<T,AF,PF,TF,RT> >
5154  : public TrueType
5155 {};
5157 //*************************************************************************************************
5158 
5159 
5160 
5161 
5162 //=================================================================================================
5163 //
5164 // ISCUSTOM SPECIALIZATIONS
5165 //
5166 //=================================================================================================
5167 
5168 //*************************************************************************************************
5170 template< typename T, bool AF, bool PF, bool TF, typename RT >
5171 struct IsCustom< CustomVector<T,AF,PF,TF,RT> >
5172  : public TrueType
5173 {};
5175 //*************************************************************************************************
5176 
5177 
5178 
5179 
5180 //=================================================================================================
5181 //
5182 // ISALIGNED SPECIALIZATIONS
5183 //
5184 //=================================================================================================
5185 
5186 //*************************************************************************************************
5188 template< typename T, bool PF, bool TF, typename RT >
5189 struct IsAligned< CustomVector<T,aligned,PF,TF,RT> >
5190  : public TrueType
5191 {};
5193 //*************************************************************************************************
5194 
5195 
5196 
5197 
5198 //=================================================================================================
5199 //
5200 // ISALIGNED SPECIALIZATIONS
5201 //
5202 //=================================================================================================
5203 
5204 //*************************************************************************************************
5206 template< typename T, bool PF, bool TF, typename RT >
5207 struct IsContiguous< CustomVector<T,aligned,PF,TF,RT> >
5208  : public TrueType
5209 {};
5211 //*************************************************************************************************
5212 
5213 
5214 
5215 
5216 //=================================================================================================
5217 //
5218 // ISPADDED SPECIALIZATIONS
5219 //
5220 //=================================================================================================
5221 
5222 //*************************************************************************************************
5224 template< typename T, bool AF, bool TF, typename RT >
5225 struct IsPadded< CustomVector<T,AF,padded,TF,RT> >
5226  : public TrueType
5227 {};
5229 //*************************************************************************************************
5230 
5231 } // namespace blaze
5232 
5233 #endif
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD element.
Definition: CustomVector.h:604
typename T1::template Rebind< T2 >::Other Rebind_t
Alias declaration for nested Rebind class templates.The Rebind_t alias declaration provides a conveni...
Definition: Aliases.h:310
Header file for the nextMultiple shim.
#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
auto subAssign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedSubAssign_v< VT > >
Default implementation of the subtraction assignment of a dense vector.
Definition: CustomVector.h:2366
Header file for the alignment flag values.
Header file for the UNUSED_PARAMETER function template.
Header file for basic type definitions.
Header file for the SparseVector base class.
bool canSMPAssign() const noexcept
Returns whether the vector can be used in SMP assignments.
Definition: CustomVector.h:1875
CustomVector< NewType, AF, PF, TF, RRT > Other
The type of the other CustomVector.
Definition: CustomVector.h:427
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:188
BLAZE_ALWAYS_INLINE SIMDType loada(size_t index) const noexcept
Aligned load of a SIMD element of the vector.
Definition: CustomVector.h:1929
auto divAssign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedDivAssign_v< VT > >
Default implementation of the division assignment of a dense vector.
Definition: CustomVector.h:2594
Iterator end() noexcept
Returns an iterator just past the last element of the custom vector.
Definition: CustomVector.h:1044
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
Header file for the serial shim.
typename DivTrait< T1, T2 >::Type DivTrait_t
Auxiliary alias declaration for the DivTrait class template.The DivTrait_t alias declaration provides...
Definition: DivTrait.h:239
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CustomVector.h:453
void clear()
Clearing the vector to its default state.
Definition: CustomVector.h:1630
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: CustomVector.h:405
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3077
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
CustomVector< Type, AF, PF, TF, RT > This
Type of this CustomVector instance.
Definition: CustomVector.h:398
Header file for the IsIntegral type trait.
typename SIMDTrait< T >::Type SIMDTrait_t
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_t alias declaration provid...
Definition: SIMDTrait.h:315
Header file for the DenseVector base class.
DenseVector< This, TF > BaseType
Base type of this CustomVector instance.
Definition: CustomVector.h:399
auto assign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedAssign_v< VT > >
Default implementation of the assignment of a dense vector.
Definition: CustomVector.h:2128
#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
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3085
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the implementation of an arbitrarily sized vector.
typename T::template Resize< Ns... >::Other Resize_t
Alias declaration for nested Resize class templates.The Resize_t alias declaration provides a conveni...
Definition: Aliases.h:370
auto addAssign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedAddAssign_v< VT > >
Default implementation of the addition assignment of a dense vector.
Definition: CustomVector.h:2254
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
auto smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:220
BLAZE_ALWAYS_INLINE void store(size_t index, const SIMDType &value) noexcept
Store of a SIMD element of the vector.
Definition: CustomVector.h:1997
void reset()
Reset to the default initial values.
Definition: CustomVector.h:1608
Type ElementType
Type of the vector elements.
Definition: CustomVector.h:407
Constraint on the data type.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:3291
SIMDTrait_t< ElementType > SIMDType
SIMD type of the vector elements.
Definition: CustomVector.h:408
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
BLAZE_ALWAYS_INLINE void stream(size_t index, const SIMDType &value) noexcept
Aligned, non-temporal store of a SIMD element of the vector.
Definition: CustomVector.h:2095
Iterator begin() noexcept
Returns an iterator to the first element of the custom vector.
Definition: CustomVector.h:990
Header file for the DisableIf class template.
void swap(CustomVector &v) noexcept
Swapping the contents of two vectors.
Definition: CustomVector.h:1649
BLAZE_ALWAYS_INLINE void storea(size_t index, const SIMDType &value) noexcept
Aligned store of a SIMD element of the vector.
Definition: CustomVector.h:2026
Header file for the IsCustom type trait.
Header file for the multiplication trait.
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
bool isAligned() const noexcept
Returns whether the vector is properly aligned in memory.
Definition: CustomVector.h:1853
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5907
Compile time assertion.
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:189
Header file for all forward declarations of the math module.
ConstIterator cend() const noexcept
Returns an iterator just past the last element of the custom vector.
Definition: CustomVector.h:1080
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Header file for the IsSMPAssignable type trait.
Resize_t< RT, NewN > RRT
The resized result type.
Definition: CustomVector.h:436
Type & Reference
Reference to a non-constant vector value.
Definition: CustomVector.h:412
#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
Header file for the HasSIMDAdd type trait.
constexpr bool HasSIMDDiv_v
Auxiliary variable template for the HasSIMDDiv type trait.The HasSIMDDiv_v variable template provides...
Definition: HasSIMDDiv.h:172
Header file for the DenseIterator class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
Header file for all SIMD functionality.
Constraint on the data type.
CustomVector< Type, AF, PF, TF, RRT > Other
The type of the other CustomVector.
Definition: CustomVector.h:437
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
Type * Pointer
Pointer to a non-constant vector value.
Definition: CustomVector.h:414
Header file for the IsAligned type trait.
Constraint on the data type.
Efficient implementation of a customizable vector.
Definition: CustomVector.h:393
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
Constraint on the data type.
Header file for the exception macros of the math module.
Type * v_
The custom array of elements.
Definition: CustomVector.h:671
Reference at(size_t index)
Checked access to the vector elements.
Definition: CustomVector.h:903
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
Constraint on the data type.
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:611
Header file for the IsPadded type trait.
BLAZE_ALWAYS_INLINE SIMDType load(size_t index) const noexcept
Load of a SIMD element of the vector.
Definition: CustomVector.h:1900
typename CrossTrait< T1, T2 >::Type CrossTrait_t
Auxiliary alias declaration for the CrossTrait class template.The CrossTrait_t alias declaration prov...
Definition: CrossTrait.h:165
static constexpr bool simdEnabled
Compilation flag for SIMD optimization.
Definition: CustomVector.h:447
typename MultTrait< T1, T2 >::Type MultTrait_t
Auxiliary alias declaration for the MultTrait class template.The MultTrait_t alias declaration provid...
Definition: MultTrait.h:240
Header file for the IsVectorizable type trait.
size_t capacity() const noexcept
Returns the maximum capacity of the vector.
Definition: CustomVector.h:1564
Resize mechanism to obtain a CustomVector with a different fixed number of elements.
Definition: CustomVector.h:435
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
Header file for the HasConstDataAccess type trait.
BLAZE_ALWAYS_INLINE void storeu(size_t index, const SIMDType &value) noexcept
Unaligned store of a SIMD element of the vector.
Definition: CustomVector.h:2061
auto multAssign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedMultAssign_v< VT > >
Default implementation of the multiplication assignment of a dense vector.
Definition: CustomVector.h:2478
Header file for the RemoveConst type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
Header file for the HasSIMDMult type trait.
Rebind mechanism to obtain a CustomVector with different data/element type.
Definition: CustomVector.h:425
size_t spacing() const noexcept
Returns the minimum capacity of the vector.
Definition: CustomVector.h:1547
size_t nonZeros() const
Returns the number of non-zero elements in the vector.
Definition: CustomVector.h:1584
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
Header file for run time assertion macros.
Header file for the cross product trait.
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
Header file for the division trait.
ConstIterator cbegin() const noexcept
Returns an iterator to the first element of the custom vector.
Definition: CustomVector.h:1026
Header file for the IsContiguous type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CustomVector.h:409
RT ResultType
Result type for expression template evaluations.
Definition: CustomVector.h:402
const CustomVector & CompositeType
Data type for composite expression templates.
Definition: CustomVector.h:410
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:295
Header file for the cache size of the target architecture.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:281
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
Constraint on the data type.
Header file for the HasSIMDSub type trait.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
Header file for the HasMutableDataAccess type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
DenseIterator< Type, AF > Iterator
Iterator over non-constant elements.
Definition: CustomVector.h:417
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
CustomVector & operator=(const Type &rhs)
Homogenous assignment to all vector elements.
Definition: CustomVector.h:1106
Header file for the padding flag values.
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.The ConstIterator_t alias declaration pro...
Definition: Aliases.h:110
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
size_t size_
The size/dimension of the custom vector.
Definition: CustomVector.h:670
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
size_t size() const noexcept
Returns the size/dimension of the vector.
Definition: CustomVector.h:1527
Header file for the HasSIMDDiv type trait.
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: CustomVector.h:418
Base class for N-dimensional vectors.The Vector class is a base class for all arbitrarily sized (N-di...
Definition: Forward.h:186
CustomVector()
The default constructor for CustomVector.
Definition: CustomVector.h:709
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
Header file for the default transpose flag for all vectors of the Blaze library.
Initializer list type of the Blaze library.
Rebind_t< RT, RemoveConst_t< NewType > > RRT
The rebound result type.
Definition: CustomVector.h:426
Reference operator[](size_t index) noexcept
Subscript operator for the direct access to the vector elements.
Definition: CustomVector.h:856
Header file for the alignment check function.
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:188
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:138
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
const Type * ConstPointer
Pointer to a constant vector value.
Definition: CustomVector.h:415
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t index) const noexcept
Unaligned load of a SIMD element of the vector.
Definition: CustomVector.h:1964
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
bool isAliased(const Other *alias) const noexcept
Returns whether the vector is aliased with the given address alias.
Definition: CustomVector.h:1832
System settings for the inline keywords.
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
constexpr bool padded
Padding flag for padded vectors and matrices.Via this flag it is possible to specify custom vectors a...
Definition: PaddingFlag.h:86
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:191
const Type & ConstReference
Reference to a constant vector value.
Definition: CustomVector.h:413
Header file for the TrueType type/value trait base class.
Header file for the clear shim.
Pointer data() noexcept
Low-level data access to the vector elements.
Definition: CustomVector.h:952
bool canAlias(const Other *alias) const noexcept
Returns whether the vector can alias with the given address alias.
Definition: CustomVector.h:1809