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>
56 #include <blaze/math/Functions.h>
58 #include <blaze/math/PaddingFlag.h>
59 #include <blaze/math/shims/Clear.h>
62 #include <blaze/math/SIMD.h>
83 #include <blaze/system/CacheSize.h>
84 #include <blaze/system/Inline.h>
89 #include <blaze/util/Assert.h>
94 #include <blaze/util/DisableIf.h>
95 #include <blaze/util/EnableIf.h>
97 #include <blaze/util/Template.h>
98 #include <blaze/util/TrueType.h>
99 #include <blaze/util/Types.h>
103 #include <blaze/util/Unused.h>
104 
105 
106 namespace blaze {
107 
108 //=================================================================================================
109 //
110 // CLASS DEFINITION
111 //
112 //=================================================================================================
113 
114 //*************************************************************************************************
393 template< typename Type // Data type of the vector
394  , bool AF // Alignment flag
395  , bool PF // Padding flag
396  , bool TF = defaultTransposeFlag > // Transpose flag
398  : public DenseVector< CustomVector<Type,AF,PF,TF>, TF >
399 {
400  public:
401  //**Type definitions****************************************************************************
404 
407 
410 
411  using ElementType = Type;
413  using ReturnType = const Type&;
414  using CompositeType = const CustomVector&;
415 
416  using Reference = Type&;
417  using ConstReference = const Type&;
418  using Pointer = Type*;
419  using ConstPointer = const Type*;
420 
423  //**********************************************************************************************
424 
425  //**Rebind struct definition********************************************************************
428  template< typename NewType > // Data type of the other vector
429  struct Rebind {
431  };
432  //**********************************************************************************************
433 
434  //**Resize struct definition********************************************************************
437  template< size_t NewN > // Number of elements of the other vector
438  struct Resize {
440  };
441  //**********************************************************************************************
442 
443  //**Compilation flags***************************************************************************
445 
449  enum : bool { simdEnabled = IsVectorizable<Type>::value };
450 
452 
455  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
456  //**********************************************************************************************
457 
458  //**Constructors********************************************************************************
461  explicit inline CustomVector();
462  explicit inline CustomVector( Type* ptr, size_t n );
463  explicit inline CustomVector( Type* ptr, size_t n, size_t nn );
464 
465  inline CustomVector( const CustomVector& v );
466  inline CustomVector( CustomVector&& v ) noexcept;
468  //**********************************************************************************************
469 
470  //**Destructor**********************************************************************************
471  // No explicitly declared destructor.
472  //**********************************************************************************************
473 
474  //**Data access functions***********************************************************************
477  inline Reference operator[]( size_t index ) noexcept;
478  inline ConstReference operator[]( size_t index ) const noexcept;
479  inline Reference at( size_t index );
480  inline ConstReference at( size_t index ) const;
481  inline Pointer data () noexcept;
482  inline ConstPointer data () const noexcept;
483  inline Iterator begin () noexcept;
484  inline ConstIterator begin () const noexcept;
485  inline ConstIterator cbegin() const noexcept;
486  inline Iterator end () noexcept;
487  inline ConstIterator end () const noexcept;
488  inline ConstIterator cend () const noexcept;
490  //**********************************************************************************************
491 
492  //**Assignment operators************************************************************************
495  inline CustomVector& operator=( const Type& rhs );
497 
498  template< typename Other, size_t N >
499  inline CustomVector& operator=( const Other (&array)[N] );
500 
501  inline CustomVector& operator=( const CustomVector& rhs );
502  inline CustomVector& operator=( CustomVector&& rhs ) noexcept;
503 
504  template< typename VT > inline CustomVector& operator= ( const Vector<VT,TF>& rhs );
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 DenseVector<VT,TF>& rhs );
509  template< typename VT > inline CustomVector& operator%=( const Vector<VT,TF>& rhs );
511  //**********************************************************************************************
512 
513  //**Utility functions***************************************************************************
516  inline size_t size() const noexcept;
517  inline size_t spacing() const noexcept;
518  inline size_t capacity() const noexcept;
519  inline size_t nonZeros() const;
520  inline void reset();
521  inline void clear();
522  inline void swap( CustomVector& v ) noexcept;
524  //**********************************************************************************************
525 
526  //**Numeric functions***************************************************************************
529  template< typename Other > inline CustomVector& scale( const Other& scalar );
531  //**********************************************************************************************
532 
533  //**Resource management functions***************************************************************
536  inline void reset( Type* ptr, size_t n );
537  inline void reset( Type* ptr, size_t n, size_t nn );
539  //**********************************************************************************************
540 
541  private:
542  //**********************************************************************************************
544  template< typename VT >
546  struct VectorizedAssign {
547  enum : bool { value = useOptimizedKernels &&
548  simdEnabled && VT::simdEnabled &&
550  };
552  //**********************************************************************************************
553 
554  //**********************************************************************************************
556  template< typename VT >
558  struct VectorizedAddAssign {
559  enum : bool { value = useOptimizedKernels &&
560  simdEnabled && VT::simdEnabled &&
563  };
565  //**********************************************************************************************
566 
567  //**********************************************************************************************
569  template< typename VT >
571  struct VectorizedSubAssign {
572  enum : bool { value = useOptimizedKernels &&
573  simdEnabled && VT::simdEnabled &&
576  };
578  //**********************************************************************************************
579 
580  //**********************************************************************************************
582  template< typename VT >
584  struct VectorizedMultAssign {
585  enum : bool { value = useOptimizedKernels &&
586  simdEnabled && VT::simdEnabled &&
589  };
591  //**********************************************************************************************
592 
593  //**********************************************************************************************
595  template< typename VT >
597  struct VectorizedDivAssign {
598  enum : bool { value = useOptimizedKernels &&
599  simdEnabled && VT::simdEnabled &&
602  };
604  //**********************************************************************************************
605 
606  //**SIMD properties*****************************************************************************
608  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
609  //**********************************************************************************************
610 
611  public:
612  //**Expression template evaluation functions****************************************************
615  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
616  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
617 
618  inline bool isAligned () const noexcept;
619  inline bool canSMPAssign() const noexcept;
620 
621  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
622  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
623  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
624 
625  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
626  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
627  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
628  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
629 
630  template< typename VT >
631  inline DisableIf_<VectorizedAssign<VT> > assign( const DenseVector<VT,TF>& rhs );
632 
633  template< typename VT >
634  inline EnableIf_<VectorizedAssign<VT> > assign( const DenseVector<VT,TF>& rhs );
635 
636  template< typename VT > inline void assign( const SparseVector<VT,TF>& rhs );
637 
638  template< typename VT >
639  inline DisableIf_<VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,TF>& rhs );
640 
641  template< typename VT >
642  inline EnableIf_<VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,TF>& rhs );
643 
644  template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
645 
646  template< typename VT >
647  inline DisableIf_<VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,TF>& rhs );
648 
649  template< typename VT >
650  inline EnableIf_<VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,TF>& rhs );
651 
652  template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
653 
654  template< typename VT >
655  inline DisableIf_<VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,TF>& rhs );
656 
657  template< typename VT >
658  inline EnableIf_<VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,TF>& rhs );
659 
660  template< typename VT > inline void multAssign( const SparseVector<VT,TF>& rhs );
661 
662  template< typename VT >
663  inline DisableIf_<VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,TF>& rhs );
664 
665  template< typename VT >
666  inline EnableIf_<VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,TF>& rhs );
668  //**********************************************************************************************
669 
670  private:
671  //**Member variables****************************************************************************
674  size_t size_;
675  Type* v_;
676 
682  //**********************************************************************************************
683 
684  //**Compile time checks*************************************************************************
690  //**********************************************************************************************
691 };
692 //*************************************************************************************************
693 
694 
695 
696 
697 //=================================================================================================
698 //
699 // CONSTRUCTORS
700 //
701 //=================================================================================================
702 
703 //*************************************************************************************************
706 template< typename Type // Data type of the vector
707  , bool AF // Alignment flag
708  , bool PF // Padding flag
709  , bool TF > // Transpose flag
711  : size_( 0UL ) // The size/dimension of the vector
712  , v_ ( nullptr ) // The custom array of elements
713 {}
714 //*************************************************************************************************
715 
716 
717 //*************************************************************************************************
735 template< typename Type // Data type of the vector
736  , bool AF // Alignment flag
737  , bool PF // Padding flag
738  , bool TF > // Transpose flag
739 inline CustomVector<Type,AF,PF,TF>::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 inline CustomVector<Type,AF,PF,TF>::CustomVector( Type* ptr, size_t n, size_t nn )
781  : size_( 0UL ) // The size/dimension of the vector
782  , v_ ( nullptr ) // The custom array of elements
783 {
784  BLAZE_STATIC_ASSERT( PF == padded );
785 
786  UNUSED_PARAMETER( ptr, n, nn );
787 }
788 //*************************************************************************************************
789 
790 
791 //*************************************************************************************************
798 template< typename Type // Data type of the vector
799  , bool AF // Alignment flag
800  , bool PF // Padding flag
801  , bool TF > // Transpose flag
803  : size_( v.size_ ) // The size/dimension of the vector
804  , v_ ( v.v_ ) // The custom array of elements
805 {}
806 //*************************************************************************************************
807 
808 
809 //*************************************************************************************************
814 template< typename Type // Data type of the vector
815  , bool AF // Alignment flag
816  , bool PF // Padding flag
817  , bool TF > // Transpose flag
819  : size_( v.size_ ) // The size/dimension of the vector
820  , v_ ( v.v_ ) // The custom array of elements
821 {
822  v.size_ = 0UL;
823  v.v_ = nullptr;
824 
825  BLAZE_INTERNAL_ASSERT( v.data() == nullptr, "Invalid data reference detected" );
826 }
827 //*************************************************************************************************
828 
829 
830 
831 
832 //=================================================================================================
833 //
834 // DATA ACCESS FUNCTIONS
835 //
836 //=================================================================================================
837 
838 //*************************************************************************************************
847 template< typename Type // Data type of the vector
848  , bool AF // Alignment flag
849  , bool PF // Padding flag
850  , bool TF > // Transpose flag
853 {
854  BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
855  return v_[index];
856 }
857 //*************************************************************************************************
858 
859 
860 //*************************************************************************************************
869 template< typename Type // Data type of the vector
870  , bool AF // Alignment flag
871  , bool PF // Padding flag
872  , bool TF > // Transpose flag
874  CustomVector<Type,AF,PF,TF>::operator[]( size_t index ) const noexcept
875 {
876  BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
877  return v_[index];
878 }
879 //*************************************************************************************************
880 
881 
882 //*************************************************************************************************
892 template< typename Type // Data type of the vector
893  , bool AF // Alignment flag
894  , bool PF // Padding flag
895  , bool TF > // Transpose flag
898 {
899  if( index >= size_ ) {
900  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
901  }
902  return (*this)[index];
903 }
904 //*************************************************************************************************
905 
906 
907 //*************************************************************************************************
917 template< typename Type // Data type of the vector
918  , bool AF // Alignment flag
919  , bool PF // Padding flag
920  , bool TF > // Transpose flag
922  CustomVector<Type,AF,PF,TF>::at( size_t index ) const
923 {
924  if( index >= size_ ) {
925  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
926  }
927  return (*this)[index];
928 }
929 //*************************************************************************************************
930 
931 
932 //*************************************************************************************************
939 template< typename Type // Data type of the vector
940  , bool AF // Alignment flag
941  , bool PF // Padding flag
942  , bool TF > // Transpose flag
945 {
946  return v_;
947 }
948 //*************************************************************************************************
949 
950 
951 //*************************************************************************************************
958 template< typename Type // Data type of the vector
959  , bool AF // Alignment flag
960  , bool PF // Padding flag
961  , bool TF > // Transpose flag
964 {
965  return v_;
966 }
967 //*************************************************************************************************
968 
969 
970 //*************************************************************************************************
975 template< typename Type // Data type of the vector
976  , bool AF // Alignment flag
977  , bool PF // Padding flag
978  , bool TF > // Transpose flag
981 {
982  return Iterator( v_ );
983 }
984 //*************************************************************************************************
985 
986 
987 //*************************************************************************************************
992 template< typename Type // Data type of the vector
993  , bool AF // Alignment flag
994  , bool PF // Padding flag
995  , bool TF > // Transpose flag
998 {
999  return ConstIterator( v_ );
1000 }
1001 //*************************************************************************************************
1002 
1003 
1004 //*************************************************************************************************
1009 template< typename Type // Data type of the vector
1010  , bool AF // Alignment flag
1011  , bool PF // Padding flag
1012  , bool TF > // Transpose flag
1015 {
1016  return ConstIterator( v_ );
1017 }
1018 //*************************************************************************************************
1019 
1020 
1021 //*************************************************************************************************
1026 template< typename Type // Data type of the vector
1027  , bool AF // Alignment flag
1028  , bool PF // Padding flag
1029  , bool TF > // Transpose flag
1032 {
1033  return Iterator( v_+size_ );
1034 }
1035 //*************************************************************************************************
1036 
1037 
1038 //*************************************************************************************************
1043 template< typename Type // Data type of the vector
1044  , bool AF // Alignment flag
1045  , bool PF // Padding flag
1046  , bool TF > // Transpose flag
1049 {
1050  return ConstIterator( v_+size_ );
1051 }
1052 //*************************************************************************************************
1053 
1054 
1055 //*************************************************************************************************
1060 template< typename Type // Data type of the vector
1061  , bool AF // Alignment flag
1062  , bool PF // Padding flag
1063  , bool TF > // Transpose flag
1066 {
1067  return ConstIterator( v_+size_ );
1068 }
1069 //*************************************************************************************************
1070 
1071 
1072 
1073 
1074 //=================================================================================================
1075 //
1076 // ASSIGNMENT OPERATORS
1077 //
1078 //=================================================================================================
1079 
1080 //*************************************************************************************************
1086 template< typename Type // Data type of the vector
1087  , bool AF // Alignment flag
1088  , bool PF // Padding flag
1089  , bool TF > // Transpose flag
1091 {
1092  for( size_t i=0UL; i<size_; ++i )
1093  v_[i] = rhs;
1094  return *this;
1095 }
1096 //*************************************************************************************************
1097 
1098 
1099 //*************************************************************************************************
1123 template< typename Type // Data type of the vector
1124  , bool AF // Alignment flag
1125  , bool PF // Padding flag
1126  , bool TF > // Transpose flag
1128 {
1129  if( list.size() > size_ ) {
1130  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom vector" );
1131  }
1132 
1133  std::fill( std::copy( list.begin(), list.end(), v_ ), v_+size_, Type() );
1134 
1135  return *this;
1136 }
1137 //*************************************************************************************************
1138 
1139 
1140 //*************************************************************************************************
1167 template< typename Type // Data type of the vector
1168  , bool AF // Alignment flag
1169  , bool PF // Padding flag
1170  , bool TF > // Transpose flag
1171 template< typename Other // Data type of the initialization array
1172  , size_t N > // Dimension of the initialization array
1174 {
1175  if( size_ != N ) {
1176  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1177  }
1178 
1179  for( size_t i=0UL; i<N; ++i )
1180  v_[i] = array[i];
1181 
1182  return *this;
1183 }
1184 //*************************************************************************************************
1185 
1186 
1187 //*************************************************************************************************
1197 template< typename Type // Data type of the vector
1198  , bool AF // Alignment flag
1199  , bool PF // Padding flag
1200  , bool TF > // Transpose flag
1202 {
1203  if( rhs.size() != size_ ) {
1204  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1205  }
1206 
1207  smpAssign( *this, ~rhs );
1208 
1209  return *this;
1210 }
1211 //*************************************************************************************************
1212 
1213 
1214 //*************************************************************************************************
1220 template< typename Type // Data type of the vector
1221  , bool AF // Alignment flag
1222  , bool PF // Padding flag
1223  , bool TF > // Transpose flag
1226 {
1227  size_ = rhs.size_;
1228  v_ = rhs.v_;
1229 
1230  rhs.size_ = 0UL;
1231  rhs.v_ = nullptr;
1232 
1233  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
1234 
1235  return *this;
1236 }
1237 //*************************************************************************************************
1238 
1239 
1240 //*************************************************************************************************
1250 template< typename Type // Data type of the vector
1251  , bool AF // Alignment flag
1252  , bool PF // Padding flag
1253  , bool TF > // Transpose flag
1254 template< typename VT > // Type of the right-hand side vector
1256 {
1257  if( (~rhs).size() != size_ ) {
1258  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1259  }
1260 
1261  if( (~rhs).canAlias( this ) ) {
1262  const ResultType_<VT> tmp( ~rhs );
1263  smpAssign( *this, tmp );
1264  }
1265  else {
1267  reset();
1268  smpAssign( *this, ~rhs );
1269  }
1270 
1271  return *this;
1272 }
1273 //*************************************************************************************************
1274 
1275 
1276 //*************************************************************************************************
1286 template< typename Type // Data type of the vector
1287  , bool AF // Alignment flag
1288  , bool PF // Padding flag
1289  , bool TF > // Transpose flag
1290 template< typename VT > // Type of the right-hand side vector
1292 {
1293  if( (~rhs).size() != size_ ) {
1294  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1295  }
1296 
1297  if( (~rhs).canAlias( this ) ) {
1298  const ResultType_<VT> tmp( ~rhs );
1299  smpAddAssign( *this, tmp );
1300  }
1301  else {
1302  smpAddAssign( *this, ~rhs );
1303  }
1304 
1305  return *this;
1306 }
1307 //*************************************************************************************************
1308 
1309 
1310 //*************************************************************************************************
1321 template< typename Type // Data type of the vector
1322  , bool AF // Alignment flag
1323  , bool PF // Padding flag
1324  , bool TF > // Transpose flag
1325 template< typename VT > // Type of the right-hand side vector
1327 {
1328  if( (~rhs).size() != size_ ) {
1329  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1330  }
1331 
1332  if( (~rhs).canAlias( this ) ) {
1333  const ResultType_<VT> tmp( ~rhs );
1334  smpSubAssign( *this, tmp );
1335  }
1336  else {
1337  smpSubAssign( *this, ~rhs );
1338  }
1339 
1340  return *this;
1341 }
1342 //*************************************************************************************************
1343 
1344 
1345 //*************************************************************************************************
1356 template< typename Type // Data type of the vector
1357  , bool AF // Alignment flag
1358  , bool PF // Padding flag
1359  , bool TF > // Transpose flag
1360 template< typename VT > // Type of the right-hand side vector
1362 {
1365 
1366  using MultType = MultTrait_< ResultType, ResultType_<VT> >;
1367 
1370 
1371  if( (~rhs).size() != size_ ) {
1372  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1373  }
1374 
1375  if( IsSparseVector<VT>::value || (~rhs).canAlias( this ) ) {
1376  const MultType tmp( *this * (~rhs) );
1378  reset();
1379  smpAssign( *this, tmp );
1380  }
1381  else {
1382  smpMultAssign( *this, ~rhs );
1383  }
1384 
1385  return *this;
1386 }
1387 //*************************************************************************************************
1388 
1389 
1390 //*************************************************************************************************
1400 template< typename Type // Data type of the vector
1401  , bool AF // Alignment flag
1402  , bool PF // Padding flag
1403  , bool TF > // Transpose flag
1404 template< typename VT > // Type of the right-hand side vector
1407 {
1410 
1411  using DivType = DivTrait_< ResultType, ResultType_<VT> >;
1412 
1416 
1417  if( (~rhs).size() != size_ ) {
1418  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1419  }
1420 
1421  if( (~rhs).canAlias( this ) ) {
1422  const DivType tmp( *this / (~rhs) );
1423  smpAssign( *this, tmp );
1424  }
1425  else {
1426  smpDivAssign( *this, ~rhs );
1427  }
1428 
1429  return *this;
1430 }
1431 //*************************************************************************************************
1432 
1433 
1434 //*************************************************************************************************
1445 template< typename Type // Data type of the vector
1446  , bool AF // Alignment flag
1447  , bool PF // Padding flag
1448  , bool TF > // Transpose flag
1449 template< typename VT > // Type of the right-hand side vector
1451 {
1452  using blaze::assign;
1453 
1456 
1457  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
1458 
1462 
1463  if( size_ != 3UL || (~rhs).size() != 3UL ) {
1464  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1465  }
1466 
1467  const CrossType tmp( *this % (~rhs) );
1468  assign( *this, tmp );
1469 
1470  return *this;
1471 }
1472 //*************************************************************************************************
1473 
1474 
1475 
1476 
1477 //=================================================================================================
1478 //
1479 // UTILITY FUNCTIONS
1480 //
1481 //=================================================================================================
1482 
1483 //*************************************************************************************************
1488 template< typename Type // Data type of the vector
1489  , bool AF // Alignment flag
1490  , bool PF // Padding flag
1491  , bool TF > // Transpose flag
1492 inline size_t CustomVector<Type,AF,PF,TF>::size() const noexcept
1493 {
1494  return size_;
1495 }
1496 //*************************************************************************************************
1497 
1498 
1499 //*************************************************************************************************
1507 template< typename Type // Data type of the vector
1508  , bool AF // Alignment flag
1509  , bool PF // Padding flag
1510  , bool TF > // Transpose flag
1511 inline size_t CustomVector<Type,AF,PF,TF>::spacing() const noexcept
1512 {
1513  return size_;
1514 }
1515 //*************************************************************************************************
1516 
1517 
1518 //*************************************************************************************************
1523 template< typename Type // Data type of the vector
1524  , bool AF // Alignment flag
1525  , bool PF // Padding flag
1526  , bool TF > // Transpose flag
1527 inline size_t CustomVector<Type,AF,PF,TF>::capacity() 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
1547 {
1548  size_t nonzeros( 0 );
1549 
1550  for( size_t i=0UL; i<size_; ++i ) {
1551  if( !isDefault( v_[i] ) )
1552  ++nonzeros;
1553  }
1554 
1555  return nonzeros;
1556 }
1557 //*************************************************************************************************
1558 
1559 
1560 //*************************************************************************************************
1565 template< typename Type // Data type of the vector
1566  , bool AF // Alignment flag
1567  , bool PF // Padding flag
1568  , bool TF > // Transpose flag
1570 {
1571  using blaze::clear;
1572  for( size_t i=0UL; i<size_; ++i )
1573  clear( v_[i] );
1574 }
1575 //*************************************************************************************************
1576 
1577 
1578 //*************************************************************************************************
1586 template< typename Type // Data type of the vector
1587  , bool AF // Alignment flag
1588  , bool PF // Padding flag
1589  , bool TF > // Transpose flag
1591 {
1592  size_ = 0UL;
1593  v_ = nullptr;
1594 }
1595 //*************************************************************************************************
1596 
1597 
1598 //*************************************************************************************************
1604 template< typename Type // Data type of the vector
1605  , bool AF // Alignment flag
1606  , bool PF // Padding flag
1607  , bool TF > // Transpose flag
1609 {
1610  using std::swap;
1611 
1612  swap( size_, v.size_ );
1613  swap( v_, v.v_ );
1614 }
1615 //*************************************************************************************************
1616 
1617 
1618 
1619 
1620 //=================================================================================================
1621 //
1622 // NUMERIC FUNCTIONS
1623 //
1624 //=================================================================================================
1625 
1626 //*************************************************************************************************
1647 template< typename Type // Data type of the vector
1648  , bool AF // Alignment flag
1649  , bool PF // Padding flag
1650  , bool TF > // Transpose flag
1651 template< typename Other > // Data type of the scalar value
1653 {
1654  for( size_t i=0UL; i<size_; ++i )
1655  v_[i] *= scalar;
1656  return *this;
1657 }
1658 //*************************************************************************************************
1659 
1660 
1661 
1662 
1663 //=================================================================================================
1664 //
1665 // RESOURCE MANAGEMENT FUNCTIONS
1666 //
1667 //=================================================================================================
1668 
1669 //*************************************************************************************************
1691 template< typename Type // Data type of the vector
1692  , bool AF // Alignment flag
1693  , bool PF // Padding flag
1694  , bool TF > // Transpose flag
1695 inline void CustomVector<Type,AF,PF,TF>::reset( Type* ptr, size_t n )
1696 {
1697  CustomVector tmp( ptr, n );
1698  swap( tmp );
1699 }
1700 //*************************************************************************************************
1701 
1702 
1703 //*************************************************************************************************
1728 template< typename Type // Data type of the vector
1729  , bool AF // Alignment flag
1730  , bool PF // Padding flag
1731  , bool TF > // Transpose flag
1732 inline void CustomVector<Type,AF,PF,TF>::reset( Type* ptr, size_t n, size_t nn )
1733 {
1734  BLAZE_STATIC_ASSERT( PF == padded );
1735 
1736  UNUSED_PARAMETER( ptr, n, nn );
1737 }
1738 //*************************************************************************************************
1739 
1740 
1741 
1742 
1743 //=================================================================================================
1744 //
1745 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1746 //
1747 //=================================================================================================
1748 
1749 //*************************************************************************************************
1759 template< typename Type // Data type of the vector
1760  , bool AF // Alignment flag
1761  , bool PF // Padding flag
1762  , bool TF > // Transpose flag
1763 template< typename Other > // Data type of the foreign expression
1764 inline bool CustomVector<Type,AF,PF,TF>::canAlias( const Other* alias ) const noexcept
1765 {
1766  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1767 }
1768 //*************************************************************************************************
1769 
1770 
1771 //*************************************************************************************************
1781 template< typename Type // Data type of the vector
1782  , bool AF // Alignment flag
1783  , bool PF // Padding flag
1784  , bool TF > // Transpose flag
1785 template< typename Other > // Data type of the foreign expression
1786 inline bool CustomVector<Type,AF,PF,TF>::isAliased( const Other* alias ) const noexcept
1787 {
1788  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1789 }
1790 //*************************************************************************************************
1791 
1792 
1793 //*************************************************************************************************
1802 template< typename Type // Data type of the vector
1803  , bool AF // Alignment flag
1804  , bool PF // Padding flag
1805  , bool TF > // Transpose flag
1806 inline bool CustomVector<Type,AF,PF,TF>::isAligned() const noexcept
1807 {
1808  return ( AF || checkAlignment( v_ ) );
1809 }
1810 //*************************************************************************************************
1811 
1812 
1813 //*************************************************************************************************
1823 template< typename Type // Data type of the vector
1824  , bool AF // Alignment flag
1825  , bool PF // Padding flag
1826  , bool TF > // Transpose flag
1827 inline bool CustomVector<Type,AF,PF,TF>::canSMPAssign() const noexcept
1828 {
1829  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1830 }
1831 //*************************************************************************************************
1832 
1833 
1834 //*************************************************************************************************
1846 template< typename Type // Data type of the vector
1847  , bool AF // Alignment flag
1848  , bool PF // Padding flag
1849  , bool TF > // Transpose flag
1851  CustomVector<Type,AF,PF,TF>::load( size_t index ) const noexcept
1852 {
1853  if( AF )
1854  return loada( index );
1855  else
1856  return loadu( index );
1857 }
1858 //*************************************************************************************************
1859 
1860 
1861 //*************************************************************************************************
1874 template< typename Type // Data type of the vector
1875  , bool AF // Alignment flag
1876  , bool PF // Padding flag
1877  , bool TF > // Transpose flag
1879  CustomVector<Type,AF,PF,TF>::loada( size_t index ) const noexcept
1880 {
1881  using blaze::loada;
1882 
1884 
1885  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
1886  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
1887  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
1888  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
1889 
1890  return loada( v_+index );
1891 }
1892 //*************************************************************************************************
1893 
1894 
1895 //*************************************************************************************************
1908 template< typename Type // Data type of the vector
1909  , bool AF // Alignment flag
1910  , bool PF // Padding flag
1911  , bool TF > // Transpose flag
1913  CustomVector<Type,AF,PF,TF>::loadu( size_t index ) const noexcept
1914 {
1915  using blaze::loadu;
1916 
1918 
1919  BLAZE_INTERNAL_ASSERT( index< size_, "Invalid vector access index" );
1920  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
1921 
1922  return loadu( v_+index );
1923 }
1924 //*************************************************************************************************
1925 
1926 
1927 //*************************************************************************************************
1940 template< typename Type // Data type of the vector
1941  , bool AF // Alignment flag
1942  , bool PF // Padding flag
1943  , bool TF > // Transpose flag
1944 BLAZE_ALWAYS_INLINE void CustomVector<Type,AF,PF,TF>::store( size_t index, const SIMDType& value ) noexcept
1945 {
1946  if( AF )
1947  storea( index, value );
1948  else
1949  storeu( index, value );
1950 }
1951 //*************************************************************************************************
1952 
1953 
1954 //*************************************************************************************************
1967 template< typename Type // Data type of the vector
1968  , bool AF // Alignment flag
1969  , bool PF // Padding flag
1970  , bool TF > // Transpose flag
1971 BLAZE_ALWAYS_INLINE void CustomVector<Type,AF,PF,TF>::storea( size_t index, const SIMDType& value ) noexcept
1972 {
1973  using blaze::storea;
1974 
1976 
1977  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
1978  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
1979  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
1980  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
1981 
1982  storea( v_+index, value );
1983 }
1984 //*************************************************************************************************
1985 
1986 
1987 //*************************************************************************************************
2000 template< typename Type // Data type of the vector
2001  , bool AF // Alignment flag
2002  , bool PF // Padding flag
2003  , bool TF > // Transpose flag
2004 BLAZE_ALWAYS_INLINE void CustomVector<Type,AF,PF,TF>::storeu( size_t index, const SIMDType& value ) noexcept
2005 {
2006  using blaze::storeu;
2007 
2009 
2010  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
2011  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2012 
2013  storeu( v_+index, value );
2014 }
2015 //*************************************************************************************************
2016 
2017 
2018 //*************************************************************************************************
2032 template< typename Type // Data type of the vector
2033  , bool AF // Alignment flag
2034  , bool PF // Padding flag
2035  , bool TF > // Transpose flag
2036 BLAZE_ALWAYS_INLINE void CustomVector<Type,AF,PF,TF>::stream( size_t index, const SIMDType& value ) noexcept
2037 {
2038  using blaze::stream;
2039 
2041 
2042  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
2043  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2044  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
2045  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
2046 
2047  stream( v_+index, value );
2048 }
2049 //*************************************************************************************************
2050 
2051 
2052 //*************************************************************************************************
2063 template< typename Type // Data type of the vector
2064  , bool AF // Alignment flag
2065  , bool PF // Padding flag
2066  , bool TF > // Transpose flag
2067 template< typename VT > // Type of the right-hand side dense vector
2070 {
2071  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2072 
2073  const size_t ipos( size_ & size_t(-2) );
2074  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2075 
2076  for( size_t i=0UL; i<ipos; i+=2UL ) {
2077  v_[i ] = (~rhs)[i ];
2078  v_[i+1UL] = (~rhs)[i+1UL];
2079  }
2080  if( ipos < (~rhs).size() )
2081  v_[ipos] = (~rhs)[ipos];
2082 }
2083 //*************************************************************************************************
2084 
2085 
2086 //*************************************************************************************************
2097 template< typename Type // Data type of the vector
2098  , bool AF // Alignment flag
2099  , bool PF // Padding flag
2100  , bool TF > // Transpose flag
2101 template< typename VT > // Type of the right-hand side dense vector
2104 {
2106 
2107  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2108 
2109  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2110  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2111 
2112  if( AF && useStreaming && size_ > ( cacheSize/( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
2113  {
2114  size_t i( 0UL );
2115 
2116  for( ; i<ipos; i+=SIMDSIZE ) {
2117  stream( i, (~rhs).load(i) );
2118  }
2119  for( ; i<size_; ++i ) {
2120  v_[i] = (~rhs)[i];
2121  }
2122  }
2123  else
2124  {
2125  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
2126  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2127  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2128 
2129  size_t i( 0UL );
2130  ConstIterator_<VT> it( (~rhs).begin() );
2131 
2132  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2133  store( i , it.load() ); it += SIMDSIZE;
2134  store( i+SIMDSIZE , it.load() ); it += SIMDSIZE;
2135  store( i+SIMDSIZE*2UL, it.load() ); it += SIMDSIZE;
2136  store( i+SIMDSIZE*3UL, it.load() ); it += SIMDSIZE;
2137  }
2138  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2139  store( i, it.load() );
2140  }
2141  for( ; i<size_; ++i, ++it ) {
2142  v_[i] = *it;
2143  }
2144  }
2145 }
2146 //*************************************************************************************************
2147 
2148 
2149 //*************************************************************************************************
2160 template< typename Type // Data type of the vector
2161  , bool AF // Alignment flag
2162  , bool PF // Padding flag
2163  , bool TF > // Transpose flag
2164 template< typename VT > // Type of the right-hand side sparse vector
2166 {
2167  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2168 
2169  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2170  v_[element->index()] = element->value();
2171 }
2172 //*************************************************************************************************
2173 
2174 
2175 //*************************************************************************************************
2186 template< typename Type // Data type of the vector
2187  , bool AF // Alignment flag
2188  , bool PF // Padding flag
2189  , bool TF > // Transpose flag
2190 template< typename VT > // Type of the right-hand side dense vector
2193 {
2194  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2195 
2196  const size_t ipos( size_ & size_t(-2) );
2197  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2198 
2199  for( size_t i=0UL; i<ipos; i+=2UL ) {
2200  v_[i ] += (~rhs)[i ];
2201  v_[i+1UL] += (~rhs)[i+1UL];
2202  }
2203  if( ipos < (~rhs).size() )
2204  v_[ipos] += (~rhs)[ipos];
2205 }
2206 //*************************************************************************************************
2207 
2208 
2209 //*************************************************************************************************
2220 template< typename Type // Data type of the vector
2221  , bool AF // Alignment flag
2222  , bool PF // Padding flag
2223  , bool TF > // Transpose flag
2224 template< typename VT > // Type of the right-hand side dense vector
2227 {
2229 
2230  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2231 
2232  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2233  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2234 
2235  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
2236  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2237  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2238 
2239  size_t i( 0UL );
2240  ConstIterator_<VT> it( (~rhs).begin() );
2241 
2242  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2243  store( i , load(i ) + it.load() ); it += SIMDSIZE;
2244  store( i+SIMDSIZE , load(i+SIMDSIZE ) + it.load() ); it += SIMDSIZE;
2245  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) + it.load() ); it += SIMDSIZE;
2246  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) + it.load() ); it += SIMDSIZE;
2247  }
2248  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2249  store( i, load(i) + it.load() );
2250  }
2251  for( ; i<size_; ++i, ++it ) {
2252  v_[i] += *it;
2253  }
2254 }
2255 //*************************************************************************************************
2256 
2257 
2258 //*************************************************************************************************
2269 template< typename Type // Data type of the vector
2270  , bool AF // Alignment flag
2271  , bool PF // Padding flag
2272  , bool TF > // Transpose flag
2273 template< typename VT > // Type of the right-hand side sparse vector
2275 {
2276  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2277 
2278  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2279  v_[element->index()] += element->value();
2280 }
2281 //*************************************************************************************************
2282 
2283 
2284 //*************************************************************************************************
2295 template< typename Type // Data type of the vector
2296  , bool AF // Alignment flag
2297  , bool PF // Padding flag
2298  , bool TF > // Transpose flag
2299 template< typename VT > // Type of the right-hand side dense vector
2302 {
2303  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2304 
2305  const size_t ipos( size_ & size_t(-2) );
2306  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2307 
2308  for( size_t i=0UL; i<ipos; i+=2UL ) {
2309  v_[i ] -= (~rhs)[i ];
2310  v_[i+1UL] -= (~rhs)[i+1UL];
2311  }
2312  if( ipos < (~rhs).size() )
2313  v_[ipos] -= (~rhs)[ipos];
2314 }
2315 //*************************************************************************************************
2316 
2317 
2318 //*************************************************************************************************
2329 template< typename Type // Data type of the vector
2330  , bool AF // Alignment flag
2331  , bool PF // Padding flag
2332  , bool TF > // Transpose flag
2333 template< typename VT > // Type of the right-hand side dense vector
2336 {
2338 
2339  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2340 
2341  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2342  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2343 
2344  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
2345  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2346  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2347 
2348  size_t i( 0UL );
2349  ConstIterator_<VT> it( (~rhs).begin() );
2350 
2351  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2352  store( i , load(i ) - it.load() ); it += SIMDSIZE;
2353  store( i+SIMDSIZE , load(i+SIMDSIZE ) - it.load() ); it += SIMDSIZE;
2354  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) - it.load() ); it += SIMDSIZE;
2355  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) - it.load() ); it += SIMDSIZE;
2356  }
2357  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2358  store( i, load(i) - it.load() );
2359  }
2360  for( ; i<size_; ++i, ++it ) {
2361  v_[i] -= *it;
2362  }
2363 }
2364 //*************************************************************************************************
2365 
2366 
2367 //*************************************************************************************************
2378 template< typename Type // Data type of the vector
2379  , bool AF // Alignment flag
2380  , bool PF // Padding flag
2381  , bool TF > // Transpose flag
2382 template< typename VT > // Type of the right-hand side sparse vector
2384 {
2385  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2386 
2387  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2388  v_[element->index()] -= element->value();
2389 }
2390 //*************************************************************************************************
2391 
2392 
2393 //*************************************************************************************************
2404 template< typename Type // Data type of the vector
2405  , bool AF // Alignment flag
2406  , bool PF // Padding flag
2407  , bool TF > // Transpose flag
2408 template< typename VT > // Type of the right-hand side dense vector
2411 {
2412  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2413 
2414  const size_t ipos( size_ & size_t(-2) );
2415  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2416 
2417  for( size_t i=0UL; i<ipos; i+=2UL ) {
2418  v_[i ] *= (~rhs)[i ];
2419  v_[i+1UL] *= (~rhs)[i+1UL];
2420  }
2421  if( ipos < (~rhs).size() )
2422  v_[ipos] *= (~rhs)[ipos];
2423 }
2424 //*************************************************************************************************
2425 
2426 
2427 //*************************************************************************************************
2438 template< typename Type // Data type of the vector
2439  , bool AF // Alignment flag
2440  , bool PF // Padding flag
2441  , bool TF > // Transpose flag
2442 template< typename VT > // Type of the right-hand side dense vector
2445 {
2447 
2448  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2449 
2450  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2451  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2452 
2453  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
2454  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2455  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2456 
2457  size_t i( 0UL );
2458  ConstIterator_<VT> it( (~rhs).begin() );
2459 
2460  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2461  store( i , load(i ) * it.load() ); it += SIMDSIZE;
2462  store( i+SIMDSIZE , load(i+SIMDSIZE ) * it.load() ); it += SIMDSIZE;
2463  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) * it.load() ); it += SIMDSIZE;
2464  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) * it.load() ); it += SIMDSIZE;
2465  }
2466  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2467  store( i, load(i) * it.load() );
2468  }
2469  for( ; i<size_; ++i, ++it ) {
2470  v_[i] *= *it;
2471  }
2472 }
2473 //*************************************************************************************************
2474 
2475 
2476 //*************************************************************************************************
2487 template< typename Type // Data type of the vector
2488  , bool AF // Alignment flag
2489  , bool PF // Padding flag
2490  , bool TF > // Transpose flag
2491 template< typename VT > // Type of the right-hand side sparse vector
2493 {
2494  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2495 
2496  const ResultType tmp( serial( *this ) );
2497 
2498  reset();
2499 
2500  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2501  v_[element->index()] = tmp[element->index()] * element->value();
2502 }
2503 //*************************************************************************************************
2504 
2505 
2506 //*************************************************************************************************
2517 template< typename Type // Data type of the vector
2518  , bool AF // Alignment flag
2519  , bool PF // Padding flag
2520  , bool TF > // Transpose flag
2521 template< typename VT > // Type of the right-hand side dense vector
2524 {
2525  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2526 
2527  const size_t ipos( size_ & size_t(-2) );
2528  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
2529 
2530  for( size_t i=0UL; i<ipos; i+=2UL ) {
2531  v_[i ] /= (~rhs)[i ];
2532  v_[i+1UL] /= (~rhs)[i+1UL];
2533  }
2534  if( ipos < (~rhs).size() )
2535  v_[ipos] /= (~rhs)[ipos];
2536 }
2537 //*************************************************************************************************
2538 
2539 
2540 //*************************************************************************************************
2551 template< typename Type // Data type of the vector
2552  , bool AF // Alignment flag
2553  , bool PF // Padding flag
2554  , bool TF > // Transpose flag
2555 template< typename VT > // Type of the right-hand side dense vector
2558 {
2560 
2561  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
2562 
2563  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2564  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
2565 
2566  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
2567  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
2568  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
2569 
2570  size_t i( 0UL );
2571  ConstIterator_<VT> it( (~rhs).begin() );
2572 
2573  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2574  store( i , load(i ) / it.load() ); it += SIMDSIZE;
2575  store( i+SIMDSIZE , load(i+SIMDSIZE ) / it.load() ); it += SIMDSIZE;
2576  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) / it.load() ); it += SIMDSIZE;
2577  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) / it.load() ); it += SIMDSIZE;
2578  }
2579  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2580  store( i, load(i) / it.load() );
2581  }
2582  for( ; i<size_; ++i, ++it ) {
2583  v_[i] /= *it;
2584  }
2585 }
2586 //*************************************************************************************************
2587 
2588 
2589 
2590 
2591 
2592 
2593 
2594 
2595 //=================================================================================================
2596 //
2597 // CLASS TEMPLATE SPECIALIZATION FOR PADDED VECTORS
2598 //
2599 //=================================================================================================
2600 
2601 //*************************************************************************************************
2609 template< typename Type // Data type of the vector
2610  , bool AF // Alignment flag
2611  , bool TF > // Transpose flag
2612 class CustomVector<Type,AF,padded,TF>
2613  : public DenseVector< CustomVector<Type,AF,padded,TF>, TF >
2614 {
2615  public:
2616  //**Type definitions****************************************************************************
2618  using BaseType = DenseVector<This,TF>;
2619 
2622 
2625 
2626  using ElementType = Type;
2628  using ReturnType = const Type&;
2629  using CompositeType = const CustomVector&;
2630 
2631  using Reference = Type&;
2632  using ConstReference = const Type&;
2633  using Pointer = Type*;
2634  using ConstPointer = const Type*;
2635 
2638  //**********************************************************************************************
2639 
2640  //**Rebind struct definition********************************************************************
2643  template< typename NewType > // Data type of the other vector
2644  struct Rebind {
2645  using Other = CustomVector<NewType,AF,padded,TF>;
2646  };
2647  //**********************************************************************************************
2648 
2649  //**Resize struct definition********************************************************************
2652  template< size_t NewN > // Number of elements of the other vector
2653  struct Resize {
2654  using Other = CustomVector<Type,AF,padded,TF>;
2655  };
2656  //**********************************************************************************************
2657 
2658  //**Compilation flags***************************************************************************
2660 
2664  enum : bool { simdEnabled = IsVectorizable<Type>::value };
2665 
2667 
2670  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
2671  //**********************************************************************************************
2672 
2673  //**Constructors********************************************************************************
2676  explicit inline CustomVector();
2677  explicit inline CustomVector( Type* ptr, size_t n, size_t nn );
2678 
2679  inline CustomVector( const CustomVector& v );
2680  inline CustomVector( CustomVector&& v ) noexcept;
2682  //**********************************************************************************************
2683 
2684  //**Destructor**********************************************************************************
2685  // No explicitly declared destructor.
2686  //**********************************************************************************************
2687 
2688  //**Data access functions***********************************************************************
2691  inline Reference operator[]( size_t index ) noexcept;
2692  inline ConstReference operator[]( size_t index ) const noexcept;
2693  inline Reference at( size_t index );
2694  inline ConstReference at( size_t index ) const;
2695  inline Pointer data () noexcept;
2696  inline ConstPointer data () const noexcept;
2697  inline Iterator begin () noexcept;
2698  inline ConstIterator begin () const noexcept;
2699  inline ConstIterator cbegin() const noexcept;
2700  inline Iterator end () noexcept;
2701  inline ConstIterator end () const noexcept;
2702  inline ConstIterator cend () const noexcept;
2704  //**********************************************************************************************
2705 
2706  //**Assignment operators************************************************************************
2709  inline CustomVector& operator=( const Type& rhs );
2711 
2712  template< typename Other, size_t N >
2713  inline CustomVector& operator=( const Other (&array)[N] );
2714 
2715  inline CustomVector& operator=( const CustomVector& rhs );
2716  inline CustomVector& operator=( CustomVector&& rhs ) noexcept;
2717 
2718  template< typename VT > inline CustomVector& operator= ( const Vector<VT,TF>& rhs );
2719  template< typename VT > inline CustomVector& operator+=( const Vector<VT,TF>& rhs );
2720  template< typename VT > inline CustomVector& operator-=( const Vector<VT,TF>& rhs );
2721  template< typename VT > inline CustomVector& operator*=( const Vector<VT,TF>& rhs );
2722  template< typename VT > inline CustomVector& operator/=( const DenseVector<VT,TF>& rhs );
2723  template< typename VT > inline CustomVector& operator%=( const Vector<VT,TF>& rhs );
2725  //**********************************************************************************************
2726 
2727  //**Utility functions***************************************************************************
2730  inline size_t size() const noexcept;
2731  inline size_t spacing() const noexcept;
2732  inline size_t capacity() const noexcept;
2733  inline size_t nonZeros() const;
2734  inline void reset();
2735  inline void clear();
2736  inline void swap( CustomVector& v ) noexcept;
2738  //**********************************************************************************************
2739 
2740  //**Numeric functions***************************************************************************
2743  template< typename Other > inline CustomVector& scale( const Other& scalar );
2745  //**********************************************************************************************
2746 
2747  //**Resource management functions***************************************************************
2750  inline void reset( Type* ptr, size_t n, size_t nn );
2752  //**********************************************************************************************
2753 
2754  private:
2755  //**********************************************************************************************
2757  template< typename VT >
2758  struct VectorizedAssign {
2759  enum : bool { value = useOptimizedKernels &&
2760  simdEnabled && VT::simdEnabled &&
2762  };
2763  //**********************************************************************************************
2764 
2765  //**********************************************************************************************
2767  template< typename VT >
2768  struct VectorizedAddAssign {
2769  enum : bool { value = useOptimizedKernels &&
2770  simdEnabled && VT::simdEnabled &&
2773  };
2774  //**********************************************************************************************
2775 
2776  //**********************************************************************************************
2778  template< typename VT >
2779  struct VectorizedSubAssign {
2780  enum : bool { value = useOptimizedKernels &&
2781  simdEnabled && VT::simdEnabled &&
2784  };
2785  //**********************************************************************************************
2786 
2787  //**********************************************************************************************
2789  template< typename VT >
2790  struct VectorizedMultAssign {
2791  enum : bool { value = useOptimizedKernels &&
2792  simdEnabled && VT::simdEnabled &&
2795  };
2796  //**********************************************************************************************
2797 
2798  //**********************************************************************************************
2800  template< typename VT >
2801  struct VectorizedDivAssign {
2802  enum : bool { value = useOptimizedKernels &&
2803  simdEnabled && VT::simdEnabled &&
2806  };
2807  //**********************************************************************************************
2808 
2809  //**SIMD properties*****************************************************************************
2811  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
2812  //**********************************************************************************************
2813 
2814  public:
2815  //**Expression template evaluation functions****************************************************
2818  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
2819  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
2820 
2821  inline bool isAligned () const noexcept;
2822  inline bool canSMPAssign() const noexcept;
2823 
2824  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
2825  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
2826  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
2827 
2828  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
2829  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
2830  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
2831  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
2832 
2833  template< typename VT >
2834  inline DisableIf_<VectorizedAssign<VT> > assign( const DenseVector<VT,TF>& rhs );
2835 
2836  template< typename VT >
2837  inline EnableIf_<VectorizedAssign<VT> > assign( const DenseVector<VT,TF>& rhs );
2838 
2839  template< typename VT > inline void assign( const SparseVector<VT,TF>& rhs );
2840 
2841  template< typename VT >
2842  inline DisableIf_<VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,TF>& rhs );
2843 
2844  template< typename VT >
2845  inline EnableIf_<VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,TF>& rhs );
2846 
2847  template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
2848 
2849  template< typename VT >
2850  inline DisableIf_<VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,TF>& rhs );
2851 
2852  template< typename VT >
2853  inline EnableIf_<VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,TF>& rhs );
2854 
2855  template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
2856 
2857  template< typename VT >
2858  inline DisableIf_<VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,TF>& rhs );
2859 
2860  template< typename VT >
2861  inline EnableIf_<VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,TF>& rhs );
2862 
2863  template< typename VT > inline void multAssign( const SparseVector<VT,TF>& rhs );
2864 
2865  template< typename VT >
2866  inline DisableIf_<VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,TF>& rhs );
2867 
2868  template< typename VT >
2869  inline EnableIf_<VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,TF>& rhs );
2871  //**********************************************************************************************
2872 
2873  private:
2874  //**Member variables****************************************************************************
2877  size_t size_;
2878  size_t capacity_;
2879  Type* v_;
2880 
2886  //**********************************************************************************************
2887 
2888  //**Compile time checks*************************************************************************
2892  //**********************************************************************************************
2893 };
2895 //*************************************************************************************************
2896 
2897 
2898 
2899 
2900 //=================================================================================================
2901 //
2902 // CONSTRUCTORS
2903 //
2904 //=================================================================================================
2905 
2906 //*************************************************************************************************
2910 template< typename Type // Data type of the vector
2911  , bool AF // Alignment flag
2912  , bool TF > // Transpose flag
2914  : size_ ( 0UL ) // The size/dimension of the vector
2915  , capacity_( 0UL ) // The maximum capacity of the vector
2916  , v_ ( nullptr ) // The custom array of elements
2917 {}
2919 //*************************************************************************************************
2920 
2921 
2922 //*************************************************************************************************
2944 template< typename Type // Data type of the vector
2945  , bool AF // Alignment flag
2946  , bool TF > // Transpose flag
2947 inline CustomVector<Type,AF,padded,TF>::CustomVector( Type* ptr, size_t n, size_t nn )
2948  : size_ ( n ) // The size/dimension of the vector
2949  , capacity_( nn ) // The maximum capacity of the vector
2950  , v_ ( ptr ) // The custom array of elements
2951 {
2952  if( ptr == nullptr ) {
2953  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
2954  }
2955 
2956  if( AF && !checkAlignment( ptr ) ) {
2957  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
2958  }
2959 
2960  if( IsVectorizable<Type>::value && capacity_ < nextMultiple<size_t>( size_, SIMDSIZE ) ) {
2961  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded vector" );
2962  }
2963 
2965  for( size_t i=size_; i<capacity_; ++i )
2966  v_[i] = Type();
2967  }
2968 }
2970 //*************************************************************************************************
2971 
2972 
2973 //*************************************************************************************************
2981 template< typename Type // Data type of the vector
2982  , bool AF // Alignment flag
2983  , bool TF > // Transpose flag
2985  : size_ ( v.size_ ) // The size/dimension of the vector
2986  , capacity_( v.capacity_ ) // The maximum capacity of the vector
2987  , v_ ( v.v_ ) // The custom array of elements
2988 {}
2990 //*************************************************************************************************
2991 
2992 
2993 //*************************************************************************************************
2999 template< typename Type // Data type of the vector
3000  , bool AF // Alignment flag
3001  , bool TF > // Transpose flag
3003  : size_ ( v.size_ ) // The size/dimension of the vector
3004  , capacity_( v.capacity_ ) // The maximum capacity of the vector
3005  , v_ ( v.v_ ) // The custom array of elements
3006 {
3007  v.size_ = 0UL;
3008  v.capacity_ = 0UL;
3009  v.v_ = nullptr;
3010 
3011  BLAZE_INTERNAL_ASSERT( v.data() == nullptr, "Invalid data reference detected" );
3012 }
3014 //*************************************************************************************************
3015 
3016 
3017 
3018 
3019 //=================================================================================================
3020 //
3021 // DATA ACCESS FUNCTIONS
3022 //
3023 //=================================================================================================
3024 
3025 //*************************************************************************************************
3035 template< typename Type // Data type of the vector
3036  , bool AF // Alignment flag
3037  , bool TF > // Transpose flag
3039  CustomVector<Type,AF,padded,TF>::operator[]( size_t index ) noexcept
3040 {
3041  BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
3042  return v_[index];
3043 }
3045 //*************************************************************************************************
3046 
3047 
3048 //*************************************************************************************************
3058 template< typename Type // Data type of the vector
3059  , bool AF // Alignment flag
3060  , bool TF > // Transpose flag
3062  CustomVector<Type,AF,padded,TF>::operator[]( size_t index ) const noexcept
3063 {
3064  BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
3065  return v_[index];
3066 }
3068 //*************************************************************************************************
3069 
3070 
3071 //*************************************************************************************************
3082 template< typename Type // Data type of the vector
3083  , bool AF // Alignment flag
3084  , bool TF > // Transpose flag
3086  CustomVector<Type,AF,padded,TF>::at( size_t index )
3087 {
3088  if( index >= size_ ) {
3089  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
3090  }
3091  return (*this)[index];
3092 }
3094 //*************************************************************************************************
3095 
3096 
3097 //*************************************************************************************************
3108 template< typename Type // Data type of the vector
3109  , bool AF // Alignment flag
3110  , bool TF > // Transpose flag
3112  CustomVector<Type,AF,padded,TF>::at( size_t index ) const
3113 {
3114  if( index >= size_ ) {
3115  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
3116  }
3117  return (*this)[index];
3118 }
3120 //*************************************************************************************************
3121 
3122 
3123 //*************************************************************************************************
3131 template< typename Type // Data type of the vector
3132  , bool AF // Alignment flag
3133  , bool TF > // Transpose flag
3136 {
3137  return v_;
3138 }
3140 //*************************************************************************************************
3141 
3142 
3143 //*************************************************************************************************
3151 template< typename Type // Data type of the vector
3152  , bool AF // Alignment flag
3153  , bool TF > // Transpose flag
3155  CustomVector<Type,AF,padded,TF>::data() const noexcept
3156 {
3157  return v_;
3158 }
3160 //*************************************************************************************************
3161 
3162 
3163 //*************************************************************************************************
3169 template< typename Type // Data type of the vector
3170  , bool AF // Alignment flag
3171  , bool TF > // Transpose flag
3174 {
3175  return Iterator( v_ );
3176 }
3178 //*************************************************************************************************
3179 
3180 
3181 //*************************************************************************************************
3187 template< typename Type // Data type of the vector
3188  , bool AF // Alignment flag
3189  , bool TF > // Transpose flag
3192 {
3193  return ConstIterator( v_ );
3194 }
3196 //*************************************************************************************************
3197 
3198 
3199 //*************************************************************************************************
3205 template< typename Type // Data type of the vector
3206  , bool AF // Alignment flag
3207  , bool TF > // Transpose flag
3210 {
3211  return ConstIterator( v_ );
3212 }
3214 //*************************************************************************************************
3215 
3216 
3217 //*************************************************************************************************
3223 template< typename Type // Data type of the vector
3224  , bool AF // Alignment flag
3225  , bool TF > // Transpose flag
3228 {
3229  return Iterator( v_+size_ );
3230 }
3232 //*************************************************************************************************
3233 
3234 
3235 //*************************************************************************************************
3241 template< typename Type // Data type of the vector
3242  , bool AF // Alignment flag
3243  , bool TF > // Transpose flag
3245  CustomVector<Type,AF,padded,TF>::end() const noexcept
3246 {
3247  return ConstIterator( v_+size_ );
3248 }
3250 //*************************************************************************************************
3251 
3252 
3253 //*************************************************************************************************
3259 template< typename Type // Data type of the vector
3260  , bool AF // Alignment flag
3261  , bool TF > // Transpose flag
3263  CustomVector<Type,AF,padded,TF>::cend() const noexcept
3264 {
3265  return ConstIterator( v_+size_ );
3266 }
3268 //*************************************************************************************************
3269 
3270 
3271 
3272 
3273 //=================================================================================================
3274 //
3275 // ASSIGNMENT OPERATORS
3276 //
3277 //=================================================================================================
3278 
3279 //*************************************************************************************************
3286 template< typename Type // Data type of the vector
3287  , bool AF // Alignment flag
3288  , bool TF > // Transpose flag
3291 {
3292  for( size_t i=0UL; i<size_; ++i )
3293  v_[i] = rhs;
3294  return *this;
3295 }
3297 //*************************************************************************************************
3298 
3299 
3300 //*************************************************************************************************
3325 template< typename Type // Data type of the vector
3326  , bool AF // Alignment flag
3327  , bool TF > // Transpose flag
3330 {
3331  if( list.size() > size_ ) {
3332  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom vector" );
3333  }
3334 
3335  std::fill( std::copy( list.begin(), list.end(), v_ ), v_+capacity_, Type() );
3336 
3337  return *this;
3338 }
3340 //*************************************************************************************************
3341 
3342 
3343 //*************************************************************************************************
3371 template< typename Type // Data type of the vector
3372  , bool AF // Alignment flag
3373  , bool TF > // Transpose flag
3374 template< typename Other // Data type of the initialization array
3375  , size_t N > // Dimension of the initialization array
3377  CustomVector<Type,AF,padded,TF>::operator=( const Other (&array)[N] )
3378 {
3379  if( size_ != N ) {
3380  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
3381  }
3382 
3383  for( size_t i=0UL; i<N; ++i )
3384  v_[i] = array[i];
3385 
3386  return *this;
3387 }
3389 //*************************************************************************************************
3390 
3391 
3392 //*************************************************************************************************
3403 template< typename Type // Data type of the vector
3404  , bool AF // Alignment flag
3405  , bool TF > // Transpose flag
3408 {
3409  if( rhs.size() != size_ ) {
3410  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3411  }
3412 
3413  smpAssign( *this, ~rhs );
3414 
3415  return *this;
3416 }
3418 //*************************************************************************************************
3419 
3420 
3421 //*************************************************************************************************
3428 template< typename Type // Data type of the vector
3429  , bool AF // Alignment flag
3430  , bool TF > // Transpose flag
3433 {
3434  size_ = rhs.size_;
3435  capacity_ = rhs.capacity_;
3436  v_ = rhs.v_;
3437 
3438  rhs.size_ = 0UL;
3439  rhs.capacity_ = 0UL;
3440  rhs.v_ = nullptr;
3441 
3442  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
3443 
3444  return *this;
3445 }
3447 //*************************************************************************************************
3448 
3449 
3450 //*************************************************************************************************
3461 template< typename Type // Data type of the vector
3462  , bool AF // Alignment flag
3463  , bool TF > // Transpose flag
3464 template< typename VT > // Type of the right-hand side vector
3467 {
3468  if( (~rhs).size() != size_ ) {
3469  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3470  }
3471 
3472  if( (~rhs).canAlias( this ) ) {
3473  const ResultType_<VT> tmp( ~rhs );
3474  smpAssign( *this, tmp );
3475  }
3476  else {
3478  reset();
3479  smpAssign( *this, ~rhs );
3480  }
3481 
3482  return *this;
3483 }
3485 //*************************************************************************************************
3486 
3487 
3488 //*************************************************************************************************
3499 template< typename Type // Data type of the vector
3500  , bool AF // Alignment flag
3501  , bool TF > // Transpose flag
3502 template< typename VT > // Type of the right-hand side vector
3505 {
3506  if( (~rhs).size() != size_ ) {
3507  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3508  }
3509 
3510  if( (~rhs).canAlias( this ) ) {
3511  const ResultType_<VT> tmp( ~rhs );
3512  smpAddAssign( *this, tmp );
3513  }
3514  else {
3515  smpAddAssign( *this, ~rhs );
3516  }
3517 
3518  return *this;
3519 }
3521 //*************************************************************************************************
3522 
3523 
3524 //*************************************************************************************************
3536 template< typename Type // Data type of the vector
3537  , bool AF // Alignment flag
3538  , bool TF > // Transpose flag
3539 template< typename VT > // Type of the right-hand side vector
3542 {
3543  if( (~rhs).size() != size_ ) {
3544  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3545  }
3546 
3547  if( (~rhs).canAlias( this ) ) {
3548  const ResultType_<VT> tmp( ~rhs );
3549  smpSubAssign( *this, tmp );
3550  }
3551  else {
3552  smpSubAssign( *this, ~rhs );
3553  }
3554 
3555  return *this;
3556 }
3558 //*************************************************************************************************
3559 
3560 
3561 //*************************************************************************************************
3573 template< typename Type // Data type of the vector
3574  , bool AF // Alignment flag
3575  , bool TF > // Transpose flag
3576 template< typename VT > // Type of the right-hand side vector
3579 {
3582 
3583  using MultType = MultTrait_< ResultType, ResultType_<VT> >;
3584 
3587 
3588  if( (~rhs).size() != size_ ) {
3589  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3590  }
3591 
3592  if( IsSparseVector<VT>::value || (~rhs).canAlias( this ) ) {
3593  const MultType tmp( *this * (~rhs) );
3595  reset();
3596  smpAssign( *this, tmp );
3597  }
3598  else {
3599  smpMultAssign( *this, ~rhs );
3600  }
3601 
3602  return *this;
3603 }
3605 //*************************************************************************************************
3606 
3607 
3608 //*************************************************************************************************
3619 template< typename Type // Data type of the vector
3620  , bool AF // Alignment flag
3621  , bool TF > // Transpose flag
3622 template< typename VT > // Type of the right-hand side vector
3625 {
3628 
3629  using DivType = DivTrait_< ResultType, ResultType_<VT> >;
3630 
3634 
3635  if( (~rhs).size() != size_ ) {
3636  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3637  }
3638 
3639  if( (~rhs).canAlias( this ) ) {
3640  const DivType tmp( *this / (~rhs) );
3641  smpAssign( *this, tmp );
3642  }
3643  else {
3644  smpDivAssign( *this, ~rhs );
3645  }
3646 
3647  return *this;
3648 }
3650 //*************************************************************************************************
3651 
3652 
3653 //*************************************************************************************************
3665 template< typename Type // Data type of the vector
3666  , bool AF // Alignment flag
3667  , bool TF > // Transpose flag
3668 template< typename VT > // Type of the right-hand side vector
3671 {
3672  using blaze::assign;
3673 
3676 
3677  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
3678 
3682 
3683  if( size_ != 3UL || (~rhs).size() != 3UL ) {
3684  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3685  }
3686 
3687  const CrossType tmp( *this % (~rhs) );
3688  assign( *this, tmp );
3689 
3690  return *this;
3691 }
3693 //*************************************************************************************************
3694 
3695 
3696 
3697 
3698 //=================================================================================================
3699 //
3700 // UTILITY FUNCTIONS
3701 //
3702 //=================================================================================================
3703 
3704 //*************************************************************************************************
3710 template< typename Type // Data type of the vector
3711  , bool AF // Alignment flag
3712  , bool TF > // Transpose flag
3713 inline size_t CustomVector<Type,AF,padded,TF>::size() const noexcept
3714 {
3715  return size_;
3716 }
3718 //*************************************************************************************************
3719 
3720 
3721 //*************************************************************************************************
3730 template< typename Type // Data type of the vector
3731  , bool AF // Alignment flag
3732  , bool TF > // Transpose flag
3733 inline size_t CustomVector<Type,AF,padded,TF>::spacing() const noexcept
3734 {
3735  return capacity_;
3736 }
3738 //*************************************************************************************************
3739 
3740 
3741 //*************************************************************************************************
3747 template< typename Type // Data type of the vector
3748  , bool AF // Alignment flag
3749  , bool TF > // Transpose flag
3750 inline size_t CustomVector<Type,AF,padded,TF>::capacity() const noexcept
3751 {
3752  return capacity_;
3753 }
3755 //*************************************************************************************************
3756 
3757 
3758 //*************************************************************************************************
3767 template< typename Type // Data type of the vector
3768  , bool AF // Alignment flag
3769  , bool TF > // Transpose flag
3770 inline size_t CustomVector<Type,AF,padded,TF>::nonZeros() const
3771 {
3772  size_t nonzeros( 0 );
3773 
3774  for( size_t i=0UL; i<size_; ++i ) {
3775  if( !isDefault( v_[i] ) )
3776  ++nonzeros;
3777  }
3778 
3779  return nonzeros;
3780 }
3782 //*************************************************************************************************
3783 
3784 
3785 //*************************************************************************************************
3791 template< typename Type // Data type of the vector
3792  , bool AF // Alignment flag
3793  , bool TF > // Transpose flag
3795 {
3796  using blaze::clear;
3797  for( size_t i=0UL; i<size_; ++i )
3798  clear( v_[i] );
3799 }
3801 //*************************************************************************************************
3802 
3803 
3804 //*************************************************************************************************
3813 template< typename Type // Data type of the vector
3814  , bool AF // Alignment flag
3815  , bool TF > // Transpose flag
3817 {
3818  size_ = 0UL;
3819  capacity_ = 0UL;
3820  v_ = nullptr;
3821 }
3823 //*************************************************************************************************
3824 
3825 
3826 //*************************************************************************************************
3833 template< typename Type // Data type of the vector
3834  , bool AF // Alignment flag
3835  , bool TF > // Transpose flag
3836 inline void CustomVector<Type,AF,padded,TF>::swap( CustomVector& v ) noexcept
3837 {
3838  using std::swap;
3839 
3840  swap( size_, v.size_ );
3841  swap( capacity_, v.capacity_ );
3842  swap( v_, v.v_ );
3843 }
3845 //*************************************************************************************************
3846 
3847 
3848 
3849 
3850 //=================================================================================================
3851 //
3852 // NUMERIC FUNCTIONS
3853 //
3854 //=================================================================================================
3855 
3856 //*************************************************************************************************
3878 template< typename Type // Data type of the vector
3879  , bool AF // Alignment flag
3880  , bool TF > // Transpose flag
3881 template< typename Other > // Data type of the scalar value
3883  CustomVector<Type,AF,padded,TF>::scale( const Other& scalar )
3884 {
3885  for( size_t i=0UL; i<size_; ++i )
3886  v_[i] *= scalar;
3887  return *this;
3888 }
3890 //*************************************************************************************************
3891 
3892 
3893 
3894 
3895 //=================================================================================================
3896 //
3897 // RESOURCE MANAGEMENT FUNCTIONS
3898 //
3899 //=================================================================================================
3900 
3901 //*************************************************************************************************
3924 template< typename Type // Data type of the vector
3925  , bool AF // Alignment flag
3926  , bool TF > // Transpose flag
3927 inline void CustomVector<Type,AF,padded,TF>::reset( Type* ptr, size_t n, size_t nn )
3928 {
3929  CustomVector tmp( ptr, n, nn );
3930  swap( tmp );
3931 }
3933 //*************************************************************************************************
3934 
3935 
3936 
3937 
3938 //=================================================================================================
3939 //
3940 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3941 //
3942 //=================================================================================================
3943 
3944 //*************************************************************************************************
3955 template< typename Type // Data type of the vector
3956  , bool AF // Alignment flag
3957  , bool TF > // Transpose flag
3958 template< typename Other > // Data type of the foreign expression
3959 inline bool CustomVector<Type,AF,padded,TF>::canAlias( const Other* alias ) const noexcept
3960 {
3961  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3962 }
3964 //*************************************************************************************************
3965 
3966 
3967 //*************************************************************************************************
3978 template< typename Type // Data type of the vector
3979  , bool AF // Alignment flag
3980  , bool TF > // Transpose flag
3981 template< typename Other > // Data type of the foreign expression
3982 inline bool CustomVector<Type,AF,padded,TF>::isAliased( const Other* alias ) const noexcept
3983 {
3984  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3985 }
3987 //*************************************************************************************************
3988 
3989 
3990 //*************************************************************************************************
4000 template< typename Type // Data type of the vector
4001  , bool AF // Alignment flag
4002  , bool TF > // Transpose flag
4003 inline bool CustomVector<Type,AF,padded,TF>::isAligned() const noexcept
4004 {
4005  return ( AF || checkAlignment( v_ ) );
4006 }
4008 //*************************************************************************************************
4009 
4010 
4011 //*************************************************************************************************
4022 template< typename Type // Data type of the vector
4023  , bool AF // Alignment flag
4024  , bool TF > // Transpose flag
4025 inline bool CustomVector<Type,AF,padded,TF>::canSMPAssign() const noexcept
4026 {
4027  return ( size() > SMP_DVECASSIGN_THRESHOLD );
4028 }
4030 //*************************************************************************************************
4031 
4032 
4033 //*************************************************************************************************
4046 template< typename Type // Data type of the vector
4047  , bool AF // Alignment flag
4048  , bool TF > // Transpose flag
4050  CustomVector<Type,AF,padded,TF>::load( size_t index ) const noexcept
4051 {
4052  if( AF )
4053  return loada( index );
4054  else
4055  return loadu( index );
4056 }
4058 //*************************************************************************************************
4059 
4060 
4061 //*************************************************************************************************
4075 template< typename Type // Data type of the vector
4076  , bool AF // Alignment flag
4077  , bool TF > // Transpose flag
4079  CustomVector<Type,AF,padded,TF>::loada( size_t index ) const noexcept
4080 {
4081  using blaze::loada;
4082 
4084 
4085  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4086  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4087  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
4088  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
4089 
4090  return loada( v_+index );
4091 }
4093 //*************************************************************************************************
4094 
4095 
4096 //*************************************************************************************************
4110 template< typename Type // Data type of the vector
4111  , bool AF // Alignment flag
4112  , bool TF > // Transpose flag
4114  CustomVector<Type,AF,padded,TF>::loadu( size_t index ) const noexcept
4115 {
4116  using blaze::loadu;
4117 
4119 
4120  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4121  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4122 
4123  return loadu( v_+index );
4124 }
4126 //*************************************************************************************************
4127 
4128 
4129 //*************************************************************************************************
4143 template< typename Type // Data type of the vector
4144  , bool AF // Alignment flag
4145  , bool TF > // Transpose flag
4147  CustomVector<Type,AF,padded,TF>::store( size_t index, const SIMDType& value ) noexcept
4148 {
4149  if( AF )
4150  storea( index, value );
4151  else
4152  storeu( index, value );
4153 }
4155 //*************************************************************************************************
4156 
4157 
4158 //*************************************************************************************************
4172 template< typename Type // Data type of the vector
4173  , bool AF // Alignment flag
4174  , bool TF > // Transpose flag
4176  CustomVector<Type,AF,padded,TF>::storea( size_t index, const SIMDType& value ) noexcept
4177 {
4178  using blaze::storea;
4179 
4181 
4182  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4183  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4184  BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
4185  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
4186 
4187  storea( v_+index, value );
4188 }
4190 //*************************************************************************************************
4191 
4192 
4193 //*************************************************************************************************
4207 template< typename Type // Data type of the vector
4208  , bool AF // Alignment flag
4209  , bool TF > // Transpose flag
4211  CustomVector<Type,AF,padded,TF>::storeu( size_t index, const SIMDType& value ) noexcept
4212 {
4213  using blaze::storeu;
4214 
4216 
4217  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4218  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4219 
4220  storeu( v_+index, value );
4221 }
4223 //*************************************************************************************************
4224 
4225 
4226 //*************************************************************************************************
4241 template< typename Type // Data type of the vector
4242  , bool AF // Alignment flag
4243  , bool TF > // Transpose flag
4245  CustomVector<Type,AF,padded,TF>::stream( size_t index, const SIMDType& value ) noexcept
4246 {
4247  using blaze::stream;
4248 
4250 
4251  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4252  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4253  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
4254 
4255  stream( v_+index, value );
4256 }
4258 //*************************************************************************************************
4259 
4260 
4261 //*************************************************************************************************
4273 template< typename Type // Data type of the vector
4274  , bool AF // Alignment flag
4275  , bool TF > // Transpose flag
4276 template< typename VT > // Type of the right-hand side dense vector
4279 {
4280  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4281 
4282  const size_t ipos( size_ & size_t(-2) );
4283  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4284 
4285  for( size_t i=0UL; i<ipos; i+=2UL ) {
4286  v_[i ] = (~rhs)[i ];
4287  v_[i+1UL] = (~rhs)[i+1UL];
4288  }
4289  if( ipos < (~rhs).size() )
4290  v_[ipos] = (~rhs)[ipos];
4291 }
4293 //*************************************************************************************************
4294 
4295 
4296 //*************************************************************************************************
4308 template< typename Type // Data type of the vector
4309  , bool AF // Alignment flag
4310  , bool TF > // Transpose flag
4311 template< typename VT > // Type of the right-hand side dense vector
4314 {
4316 
4317  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4318 
4319  constexpr bool remainder( !IsPadded<VT>::value );
4320 
4321  const size_t ipos( ( remainder )?( size_ & size_t(-SIMDSIZE) ):( size_ ) );
4322  BLAZE_INTERNAL_ASSERT( !remainder || ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4323 
4324  if( AF && useStreaming && size_ > ( cacheSize/( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
4325  {
4326  size_t i( 0UL );
4327 
4328  for( ; i<ipos; i+=SIMDSIZE ) {
4329  stream( i, (~rhs).load(i) );
4330  }
4331  for( ; remainder && i<size_; ++i ) {
4332  v_[i] = (~rhs)[i];
4333  }
4334  }
4335  else
4336  {
4337  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
4338  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4339  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4340 
4341  size_t i( 0UL );
4342  ConstIterator_<VT> it( (~rhs).begin() );
4343 
4344  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4345  store( i , it.load() ); it += SIMDSIZE;
4346  store( i+SIMDSIZE , it.load() ); it += SIMDSIZE;
4347  store( i+SIMDSIZE*2UL, it.load() ); it += SIMDSIZE;
4348  store( i+SIMDSIZE*3UL, it.load() ); it += SIMDSIZE;
4349  }
4350  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4351  store( i, it.load() );
4352  }
4353  for( ; remainder && i<size_; ++i, ++it ) {
4354  v_[i] = *it;
4355  }
4356  }
4357 }
4359 //*************************************************************************************************
4360 
4361 
4362 //*************************************************************************************************
4374 template< typename Type // Data type of the vector
4375  , bool AF // Alignment flag
4376  , bool TF > // Transpose flag
4377 template< typename VT > // Type of the right-hand side sparse vector
4379 {
4380  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4381 
4382  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4383  v_[element->index()] = element->value();
4384 }
4386 //*************************************************************************************************
4387 
4388 
4389 //*************************************************************************************************
4401 template< typename Type // Data type of the vector
4402  , bool AF // Alignment flag
4403  , bool TF > // Transpose flag
4404 template< typename VT > // Type of the right-hand side dense vector
4407 {
4408  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4409 
4410  const size_t ipos( size_ & size_t(-2) );
4411  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4412 
4413  for( size_t i=0UL; i<ipos; i+=2UL ) {
4414  v_[i ] += (~rhs)[i ];
4415  v_[i+1UL] += (~rhs)[i+1UL];
4416  }
4417  if( ipos < (~rhs).size() )
4418  v_[ipos] += (~rhs)[ipos];
4419 }
4421 //*************************************************************************************************
4422 
4423 
4424 //*************************************************************************************************
4436 template< typename Type // Data type of the vector
4437  , bool AF // Alignment flag
4438  , bool TF > // Transpose flag
4439 template< typename VT > // Type of the right-hand side dense vector
4442 {
4444 
4445  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4446 
4447  constexpr bool remainder( !IsPadded<VT>::value );
4448 
4449  const size_t ipos( ( remainder )?( size_ & size_t(-SIMDSIZE) ):( size_ ) );
4450  BLAZE_INTERNAL_ASSERT( !remainder || ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4451 
4452  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
4453  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4454  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4455 
4456  size_t i( 0UL );
4457  ConstIterator_<VT> it( (~rhs).begin() );
4458 
4459  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4460  store( i , load(i ) + it.load() ); it += SIMDSIZE;
4461  store( i+SIMDSIZE , load(i+SIMDSIZE ) + it.load() ); it += SIMDSIZE;
4462  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) + it.load() ); it += SIMDSIZE;
4463  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) + it.load() ); it += SIMDSIZE;
4464  }
4465  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4466  store( i, load(i) + it.load() );
4467  }
4468  for( ; remainder && i<size_; ++i, ++it ) {
4469  v_[i] += *it;
4470  }
4471 }
4473 //*************************************************************************************************
4474 
4475 
4476 //*************************************************************************************************
4488 template< typename Type // Data type of the vector
4489  , bool AF // Alignment flag
4490  , bool TF > // Transpose flag
4491 template< typename VT > // Type of the right-hand side sparse vector
4493 {
4494  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4495 
4496  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4497  v_[element->index()] += element->value();
4498 }
4500 //*************************************************************************************************
4501 
4502 
4503 //*************************************************************************************************
4515 template< typename Type // Data type of the vector
4516  , bool AF // Alignment flag
4517  , bool TF > // Transpose flag
4518 template< typename VT > // Type of the right-hand side dense vector
4521 {
4522  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4523 
4524  const size_t ipos( size_ & size_t(-2) );
4525  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4526 
4527  for( size_t i=0UL; i<ipos; i+=2UL ) {
4528  v_[i ] -= (~rhs)[i ];
4529  v_[i+1UL] -= (~rhs)[i+1UL];
4530  }
4531  if( ipos < (~rhs).size() )
4532  v_[ipos] -= (~rhs)[ipos];
4533 }
4535 //*************************************************************************************************
4536 
4537 
4538 //*************************************************************************************************
4550 template< typename Type // Data type of the vector
4551  , bool AF // Alignment flag
4552  , bool TF > // Transpose flag
4553 template< typename VT > // Type of the right-hand side dense vector
4556 {
4558 
4559  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4560 
4561  constexpr bool remainder( !IsPadded<VT>::value );
4562 
4563  const size_t ipos( ( remainder )?( size_ & size_t(-SIMDSIZE) ):( size_ ) );
4564  BLAZE_INTERNAL_ASSERT( !remainder || ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4565 
4566  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
4567  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4568  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4569 
4570  size_t i( 0UL );
4571  ConstIterator_<VT> it( (~rhs).begin() );
4572 
4573  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4574  store( i , load(i ) - it.load() ); it += SIMDSIZE;
4575  store( i+SIMDSIZE , load(i+SIMDSIZE ) - it.load() ); it += SIMDSIZE;
4576  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) - it.load() ); it += SIMDSIZE;
4577  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) - it.load() ); it += SIMDSIZE;
4578  }
4579  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4580  store( i, load(i) - it.load() );
4581  }
4582  for( ; remainder && i<size_; ++i, ++it ) {
4583  v_[i] -= *it;
4584  }
4585 }
4587 //*************************************************************************************************
4588 
4589 
4590 //*************************************************************************************************
4602 template< typename Type // Data type of the vector
4603  , bool AF // Alignment flag
4604  , bool TF > // Transpose flag
4605 template< typename VT > // Type of the right-hand side sparse vector
4607 {
4608  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4609 
4610  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4611  v_[element->index()] -= element->value();
4612 }
4614 //*************************************************************************************************
4615 
4616 
4617 //*************************************************************************************************
4629 template< typename Type // Data type of the vector
4630  , bool AF // Alignment flag
4631  , bool TF > // Transpose flag
4632 template< typename VT > // Type of the right-hand side dense vector
4635 {
4636  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4637 
4638  const size_t ipos( size_ & size_t(-2) );
4639  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4640 
4641  for( size_t i=0UL; i<ipos; i+=2UL ) {
4642  v_[i ] *= (~rhs)[i ];
4643  v_[i+1UL] *= (~rhs)[i+1UL];
4644  }
4645  if( ipos < (~rhs).size() )
4646  v_[ipos] *= (~rhs)[ipos];
4647 }
4649 //*************************************************************************************************
4650 
4651 
4652 //*************************************************************************************************
4664 template< typename Type // Data type of the vector
4665  , bool AF // Alignment flag
4666  , bool TF > // Transpose flag
4667 template< typename VT > // Type of the right-hand side dense vector
4670 {
4672 
4673  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4674 
4675  constexpr bool remainder( !IsPadded<VT>::value );
4676 
4677  const size_t ipos( ( remainder )?( size_ & size_t(-SIMDSIZE) ):( size_ ) );
4678  BLAZE_INTERNAL_ASSERT( !remainder || ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4679 
4680  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
4681  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4682  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4683 
4684  size_t i( 0UL );
4685  ConstIterator_<VT> it( (~rhs).begin() );
4686 
4687  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4688  store( i , load(i ) * it.load() ); it += SIMDSIZE;
4689  store( i+SIMDSIZE , load(i+SIMDSIZE ) * it.load() ); it += SIMDSIZE;
4690  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) * it.load() ); it += SIMDSIZE;
4691  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) * it.load() ); it += SIMDSIZE;
4692  }
4693  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4694  store( i, load(i) * it.load() );
4695  }
4696  for( ; remainder && i<size_; ++i, ++it ) {
4697  v_[i] *= *it;
4698  }
4699 }
4701 //*************************************************************************************************
4702 
4703 
4704 //*************************************************************************************************
4716 template< typename Type // Data type of the vector
4717  , bool AF // Alignment flag
4718  , bool TF > // Transpose flag
4719 template< typename VT > // Type of the right-hand side sparse vector
4721 {
4722  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4723 
4724  const ResultType tmp( serial( *this ) );
4725 
4726  reset();
4727 
4728  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4729  v_[element->index()] = tmp[element->index()] * element->value();
4730 }
4732 //*************************************************************************************************
4733 
4734 
4735 //*************************************************************************************************
4747 template< typename Type // Data type of the vector
4748  , bool AF // Alignment flag
4749  , bool TF > // Transpose flag
4750 template< typename VT > // Type of the right-hand side dense vector
4753 {
4754  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4755 
4756  const size_t ipos( size_ & size_t(-2) );
4757  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % 2UL ) ) == ipos, "Invalid end calculation" );
4758 
4759  for( size_t i=0UL; i<ipos; i+=2UL ) {
4760  v_[i ] /= (~rhs)[i ];
4761  v_[i+1UL] /= (~rhs)[i+1UL];
4762  }
4763  if( ipos < (~rhs).size() )
4764  v_[ipos] /= (~rhs)[ipos];
4765 }
4767 //*************************************************************************************************
4768 
4769 
4770 //*************************************************************************************************
4782 template< typename Type // Data type of the vector
4783  , bool AF // Alignment flag
4784  , bool TF > // Transpose flag
4785 template< typename VT > // Type of the right-hand side dense vector
4788 {
4790 
4791  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
4792 
4793  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4794  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
4795 
4796  const size_t i4way( size_ & size_t(-SIMDSIZE*4) );
4797  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE*4UL) ) ) == i4way, "Invalid end calculation" );
4798  BLAZE_INTERNAL_ASSERT( i4way <= ipos, "Invalid end calculation" );
4799 
4800  size_t i( 0UL );
4801  ConstIterator_<VT> it( (~rhs).begin() );
4802 
4803  for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4804  store( i , load(i ) / it.load() ); it += SIMDSIZE;
4805  store( i+SIMDSIZE , load(i+SIMDSIZE ) / it.load() ); it += SIMDSIZE;
4806  store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) / it.load() ); it += SIMDSIZE;
4807  store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) / it.load() ); it += SIMDSIZE;
4808  }
4809  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4810  store( i, load(i) / it.load() );
4811  }
4812  for( ; i<size_; ++i, ++it ) {
4813  v_[i] /= *it;
4814  }
4815 }
4817 //*************************************************************************************************
4818 
4819 
4820 
4821 
4822 
4823 
4824 
4825 
4826 //=================================================================================================
4827 //
4828 // CUSTOMVECTOR OPERATORS
4829 //
4830 //=================================================================================================
4831 
4832 //*************************************************************************************************
4835 template< typename Type, bool AF, bool PF, bool TF >
4836 inline void reset( CustomVector<Type,AF,PF,TF>& v );
4837 
4838 template< typename Type, bool AF, bool PF, bool TF >
4839 inline void clear( CustomVector<Type,AF,PF,TF>& v );
4840 
4841 template< bool RF, typename Type, bool AF, bool PF, bool TF >
4842 inline bool isDefault( const CustomVector<Type,AF,PF,TF>& v );
4843 
4844 template< typename Type, bool AF, bool PF, bool TF >
4845 inline bool isIntact( const CustomVector<Type,AF,PF,TF>& v ) noexcept;
4846 
4847 template< typename Type, bool AF, bool PF, bool TF >
4848 inline void swap( CustomVector<Type,AF,PF,TF>& a, CustomVector<Type,AF,PF,TF>& b ) noexcept;
4850 //*************************************************************************************************
4851 
4852 
4853 //*************************************************************************************************
4860 template< typename Type // Data type of the vector
4861  , bool AF // Alignment flag
4862  , bool PF // Padding flag
4863  , bool TF > // Transpose flag
4865 {
4866  v.reset();
4867 }
4868 //*************************************************************************************************
4869 
4870 
4871 //*************************************************************************************************
4878 template< typename Type // Data type of the vector
4879  , bool AF // Alignment flag
4880  , bool PF // Padding flag
4881  , bool TF > // Transpose flag
4883 {
4884  v.clear();
4885 }
4886 //*************************************************************************************************
4887 
4888 
4889 //*************************************************************************************************
4917 template< bool RF // Relaxation flag
4918  , typename Type // Data type of the vector
4919  , bool AF // Alignment flag
4920  , bool PF // Padding flag
4921  , bool TF > // Transpose flag
4923 {
4924  return ( v.size() == 0UL );
4925 }
4926 //*************************************************************************************************
4927 
4928 
4929 //*************************************************************************************************
4950 template< typename Type // Data type of the vector
4951  , bool AF // Alignment flag
4952  , bool PF // Padding flag
4953  , bool TF > // Transpose flag
4954 inline bool isIntact( const CustomVector<Type,AF,PF,TF>& v ) noexcept
4955 {
4956  return ( v.size() <= v.capacity() );
4957 }
4958 //*************************************************************************************************
4959 
4960 
4961 //*************************************************************************************************
4969 template< typename Type // Data type of the vector
4970  , bool AF // Alignment flag
4971  , bool PF // Padding flag
4972  , bool TF > // Transpose flag
4974 {
4975  a.swap( b );
4976 }
4977 //*************************************************************************************************
4978 
4979 
4980 
4981 
4982 //=================================================================================================
4983 //
4984 // HASCONSTDATAACCESS SPECIALIZATIONS
4985 //
4986 //=================================================================================================
4987 
4988 //*************************************************************************************************
4990 template< typename T, bool AF, bool PF, bool TF >
4991 struct HasConstDataAccess< CustomVector<T,AF,PF,TF> >
4992  : public TrueType
4993 {};
4995 //*************************************************************************************************
4996 
4997 
4998 
4999 
5000 //=================================================================================================
5001 //
5002 // HASMUTABLEDATAACCESS SPECIALIZATIONS
5003 //
5004 //=================================================================================================
5005 
5006 //*************************************************************************************************
5008 template< typename T, bool AF, bool PF, bool TF >
5009 struct HasMutableDataAccess< CustomVector<T,AF,PF,TF> >
5010  : public TrueType
5011 {};
5013 //*************************************************************************************************
5014 
5015 
5016 
5017 
5018 //=================================================================================================
5019 //
5020 // ISCUSTOM SPECIALIZATIONS
5021 //
5022 //=================================================================================================
5023 
5024 //*************************************************************************************************
5026 template< typename T, bool AF, bool PF, bool TF >
5027 struct IsCustom< CustomVector<T,AF,PF,TF> >
5028  : public TrueType
5029 {};
5031 //*************************************************************************************************
5032 
5033 
5034 
5035 
5036 //=================================================================================================
5037 //
5038 // ISALIGNED SPECIALIZATIONS
5039 //
5040 //=================================================================================================
5041 
5042 //*************************************************************************************************
5044 template< typename T, bool PF, bool TF >
5045 struct IsAligned< CustomVector<T,aligned,PF,TF> >
5046  : public TrueType
5047 {};
5049 //*************************************************************************************************
5050 
5051 
5052 
5053 
5054 //=================================================================================================
5055 //
5056 // ISALIGNED SPECIALIZATIONS
5057 //
5058 //=================================================================================================
5059 
5060 //*************************************************************************************************
5062 template< typename T, bool PF, bool TF >
5063 struct IsContiguous< CustomVector<T,aligned,PF,TF> >
5064  : public TrueType
5065 {};
5067 //*************************************************************************************************
5068 
5069 
5070 
5071 
5072 //=================================================================================================
5073 //
5074 // ISPADDED SPECIALIZATIONS
5075 //
5076 //=================================================================================================
5077 
5078 //*************************************************************************************************
5080 template< typename T, bool AF, bool TF >
5081 struct IsPadded< CustomVector<T,AF,padded,TF> >
5082  : public TrueType
5083 {};
5085 //*************************************************************************************************
5086 
5087 
5088 
5089 
5090 //=================================================================================================
5091 //
5092 // UNARYMAPTRAIT SPECIALIZATIONS
5093 //
5094 //=================================================================================================
5095 
5096 //*************************************************************************************************
5098 template< typename T, bool AF, bool PF, bool TF, typename OP >
5099 struct UnaryMapTrait< CustomVector<T,AF,PF,TF>, OP >
5100 {
5101  using Type = DynamicVector< UnaryMapTrait_<T,OP>, TF >;
5102 };
5104 //*************************************************************************************************
5105 
5106 
5107 
5108 
5109 //=================================================================================================
5110 //
5111 // BINARYMAPTRAIT SPECIALIZATIONS
5112 //
5113 //=================================================================================================
5114 
5115 //*************************************************************************************************
5117 template< typename T1, bool AF, bool PF, bool TF, typename T2, size_t N, typename OP >
5118 struct BinaryMapTrait< CustomVector<T1,AF,PF,TF>, StaticVector<T2,N,TF>, OP >
5119 {
5120  using Type = StaticVector< BinaryMapTrait_<T1,T2,OP>, N, TF >;
5121 };
5122 
5123 template< typename T1, size_t N, bool TF, typename T2, bool AF, bool PF, typename OP >
5124 struct BinaryMapTrait< StaticVector<T1,N,TF>, CustomVector<T2,AF,PF,TF>, OP >
5125 {
5126  using Type = StaticVector< BinaryMapTrait_<T1,T2,OP>, N, TF >;
5127 };
5128 
5129 template< typename T1, bool AF, bool PF, bool TF, typename T2, size_t N, typename OP >
5130 struct BinaryMapTrait< CustomVector<T1,AF,PF,TF>, HybridVector<T2,N,TF>, OP >
5131 {
5132  using Type = HybridVector< BinaryMapTrait_<T1,T2,OP>, N, TF >;
5133 };
5134 
5135 template< typename T1, size_t N, bool TF, typename T2, bool AF, bool PF, typename OP >
5136 struct BinaryMapTrait< HybridVector<T1,N,TF>, CustomVector<T2,AF,PF,TF>, OP >
5137 {
5138  using Type = HybridVector< BinaryMapTrait_<T1,T2,OP>, N, TF >;
5139 };
5140 
5141 template< typename T1, bool AF, bool PF, bool TF, typename T2, typename OP >
5142 struct BinaryMapTrait< CustomVector<T1,AF,PF,TF>, DynamicVector<T2,TF>, OP >
5143 {
5144  using Type = DynamicVector< BinaryMapTrait_<T1,T2,OP>, TF >;
5145 };
5146 
5147 template< typename T1, bool TF, typename T2, bool AF, bool PF, typename OP >
5148 struct BinaryMapTrait< DynamicVector<T1,TF>, CustomVector<T2,AF,PF,TF>, OP >
5149 {
5150  using Type = DynamicVector< BinaryMapTrait_<T1,T2,OP>, TF >;
5151 };
5152 
5153 template< typename T1, bool AF1, bool PF1, bool TF, typename T2, bool AF2, bool PF2, typename OP >
5154 struct BinaryMapTrait< CustomVector<T1,AF1,PF1,TF>, CustomVector<T2,AF2,PF2,TF>, OP >
5155 {
5156  using Type = DynamicVector< BinaryMapTrait_<T1,T2,OP>, TF >;
5157 };
5159 //*************************************************************************************************
5160 
5161 
5162 
5163 
5164 //=================================================================================================
5165 //
5166 // SUBVECTORTRAIT SPECIALIZATIONS
5167 //
5168 //=================================================================================================
5169 
5170 //*************************************************************************************************
5172 template< typename T, bool AF, bool PF, bool TF, size_t I, size_t N >
5173 struct SubvectorTrait< CustomVector<T,AF,PF,TF>, I, N >
5174 {
5175  using Type = StaticVector<RemoveConst_<T>,N,TF>;
5176 };
5177 
5178 template< typename T, bool AF, bool PF, bool TF >
5179 struct SubvectorTrait< CustomVector<T,AF,PF,TF> >
5180 {
5181  using Type = DynamicVector<RemoveConst_<T>,TF>;
5182 };
5184 //*************************************************************************************************
5185 
5186 
5187 
5188 
5189 //=================================================================================================
5190 //
5191 // ELEMENTSTRAIT SPECIALIZATIONS
5192 //
5193 //=================================================================================================
5194 
5195 //*************************************************************************************************
5197 template< typename T, bool AF, bool PF, bool TF, size_t... CEAs >
5198 struct ElementsTrait< CustomVector<T,AF,PF,TF>, CEAs... >
5199 {
5200  using Type = StaticVector<RemoveConst_<T>,sizeof...(CEAs),TF>;
5201 };
5202 
5203 template< typename T, bool AF, bool PF, bool TF >
5204 struct ElementsTrait< CustomVector<T,AF,PF,TF> >
5205 {
5206  using Type = DynamicVector<RemoveConst_<T>,TF>;
5207 };
5209 //*************************************************************************************************
5210 
5211 } // namespace blaze
5212 
5213 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:135
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.
Availability of a SIMD subtraction for the given data types.Depending on the available instruction se...
Definition: HasSIMDSub.h:171
Header file for mathematical functions.
Compile time check for low-level access to constant data.This type trait tests whether the given data...
Definition: HasConstDataAccess.h:75
#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
const Type & ConstReference
Reference to a constant vector value.
Definition: CustomVector.h:417
Header file for the alignment flag values.
Header file for the UNUSED_PARAMETER function template.
CustomVector()
The default constructor for CustomVector.
Definition: CustomVector.h:710
Iterator begin() noexcept
Returns an iterator to the first element of the custom vector.
Definition: CustomVector.h:980
Header file for basic type definitions.
Header file for the SparseVector base class.
size_t size_
The size/dimension of the custom vector.
Definition: CustomVector.h:674
Type * v_
The custom array of elements.
Definition: CustomVector.h:675
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the serial shim.
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
BLAZE_ALWAYS_INLINE SIMDType load(size_t index) const noexcept
Load of a SIMD element of the vector.
Definition: CustomVector.h:1851
Iterator end() noexcept
Returns an iterator just past the last element of the custom vector.
Definition: CustomVector.h:1031
void swap(CustomVector &v) noexcept
Swapping the contents of two vectors.
Definition: CustomVector.h:1608
CustomVector & operator=(const Type &rhs)
Homogenous assignment to all vector elements.
Definition: CustomVector.h:1090
Availability of a SIMD multiplication for the given data types.Depending on the available instruction...
Definition: HasSIMDMult.h:172
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:316
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Header file for the IsIntegral type trait.
Header file for the DenseVector base class.
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:171
#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
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:291
Efficient implementation of an arbitrary sized vector.The DynamicVector class template is the represe...
Definition: DynamicVector.h:185
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
Compile time check for data types.This type trait tests whether or not the given types can be combine...
Definition: IsSIMDCombinable.h:120
SIMDTrait_< ElementType > SIMDType
SIMD type of the vector elements.
Definition: CustomVector.h:412
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
BLAZE_ALWAYS_INLINE void storeu(size_t index, const SIMDType &value) noexcept
Unaligned store of a SIMD element of the vector.
Definition: CustomVector.h:2004
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
Header file for the implementation of an arbitrarily sized vector.
Header file for the elements trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CustomVector.h:413
Constraint on the data type.
Efficient implementation of a fixed-sized vector.The StaticVector class template is the representatio...
Definition: Forward.h:61
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:3290
Base template for the SubvectorTrait class.
Definition: SubvectorTrait.h:109
Efficient implementation of a dynamically sized vector with static memory.The HybridVector class temp...
Definition: Forward.h:59
Compile time check for low-level access to mutable data.This type trait tests whether the given data ...
Definition: HasMutableDataAccess.h:75
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
Compile time check for the memory layout of data types.This type trait tests whether the given data t...
Definition: IsContiguous.h:86
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t index) const noexcept
Unaligned load of a SIMD element of the vector.
Definition: CustomVector.h:1913
Header file for the DisableIf class template.
size_t size() const noexcept
Returns the size/dimension of the vector.
Definition: CustomVector.h:1492
Header file for the IsCustom type trait.
Header file for the multiplication trait.
Header file for the unary map trait.
Header file for the clear shim.
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
Header file for nested template disabiguation.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5908
Compile time assertion.
Header file for all forward declarations of the math module.
#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.
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:76
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
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:2036
#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.
Header file for the DenseIterator class template.
void clear()
Clearing the vector to its default state.
Definition: CustomVector.h:1590
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: CustomVector.h:422
Header file for the subvector trait.
const Type * ConstPointer
Pointer to a constant vector value.
Definition: CustomVector.h:419
Header file for all SIMD functionality.
Constraint on the data type.
Availability of a SIMD division for the given data types.Depending on the available instruction set (...
Definition: HasSIMDDiv.h:150
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
Compile time check for sparse vector types.This type trait tests whether or not the given template pa...
Definition: IsSparseVector.h:103
Header file for the IsAligned type trait.
Constraint on the data type.
Efficient implementation of a customizable vector.
Definition: CustomVector.h:397
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Compile time check for custom data types.This type trait tests whether the given data type is a custo...
Definition: IsCustom.h:87
void reset()
Reset to the default initial values.
Definition: CustomVector.h:1569
ConstIterator cbegin() const noexcept
Returns an iterator to the first element of the custom vector.
Definition: CustomVector.h:1014
#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
Type & Reference
Reference to a non-constant vector value.
Definition: CustomVector.h:416
Constraint on the data type.
BLAZE_ALWAYS_INLINE void storea(size_t index, const SIMDType &value) noexcept
Aligned store of a SIMD element of the vector.
Definition: CustomVector.h:1971
Header file for the exception macros of the math module.
ConstIterator cend() const noexcept
Returns an iterator just past the last element of the custom vector.
Definition: CustomVector.h:1065
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsSMPAssignable.h:123
Base template for the ElementsTrait class.
Definition: ElementsTrait.h:108
typename CrossTrait< T1, T2 >::Type CrossTrait_
Auxiliary alias declaration for the CrossTrait class template.The CrossTrait_ alias declaration provi...
Definition: CrossTrait.h:209
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:608
Header file for the IsPadded type trait.
typename DivTrait< T1, T2 >::Type DivTrait_
Auxiliary alias declaration for the DivTrait class template.The DivTrait_ alias declaration provides ...
Definition: DivTrait.h:292
Header file for the IsVectorizable type trait.
Resize mechanism to obtain a CustomVector with a different fixed number of elements.
Definition: CustomVector.h:438
bool canSMPAssign() const noexcept
Returns whether the vector can be used in SMP assignments.
Definition: CustomVector.h:1827
Header file for the HasConstDataAccess type trait.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< 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:75
Header file for the RemoveConst type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
size_t capacity() const noexcept
Returns the maximum capacity of the vector.
Definition: CustomVector.h:1527
Header file for the HasSIMDMult type trait.
Header file for the binary map trait.
Rebind mechanism to obtain a CustomVector with different data/element type.
Definition: CustomVector.h:429
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Pointer data() noexcept
Low-level data access to the vector elements.
Definition: CustomVector.h:944
bool isAliased(const Other *alias) const noexcept
Returns whether the vector is aliased with the given address alias.
Definition: CustomVector.h:1786
Header file for the cross product trait.
Header file for the division trait.
Header file for the IsContiguous type trait.
size_t spacing() const noexcept
Returns the minimum capacity of the vector.
Definition: CustomVector.h:1511
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:296
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
Reference at(size_t index)
Checked access to the vector elements.
Definition: CustomVector.h:897
Header file for the isDefault shim.
BLAZE_ALWAYS_INLINE void store(size_t index, const SIMDType &value) noexcept
Store of a SIMD element of the vector.
Definition: CustomVector.h:1944
Constraint on the data type.
Header file for the HasSIMDSub type trait.
bool isAligned() const noexcept
Returns whether the vector is properly aligned in memory.
Definition: CustomVector.h:1806
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:816
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
bool canAlias(const Other *alias) const noexcept
Returns whether the vector can alias with the given address alias.
Definition: CustomVector.h:1764
Reference operator[](size_t index) noexcept
Subscript operator for the direct access to the vector elements.
Definition: CustomVector.h:852
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
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
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
BLAZE_ALWAYS_INLINE SIMDType loada(size_t index) const noexcept
Aligned load of a SIMD element of the vector.
Definition: CustomVector.h:1879
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
#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
Type * Pointer
Pointer to a non-constant vector value.
Definition: CustomVector.h:418
EnableIf_< IsNumeric< ST >, MT &> operator/=(DenseMatrix< MT, SO > &mat, ST scalar)
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:655
Header file for the HasSIMDDiv type trait.
Base class for N-dimensional vectors.The Vector class is a base class for all arbitrarily sized (N-di...
Definition: Forward.h:177
Header file for the default transpose flag for all vectors of the Blaze library.
Header file for the alignment check function.
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:130
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
Type ElementType
Type of the vector elements.
Definition: CustomVector.h:411
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
#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
EnableIf_< IsNumeric< ST >, MT &> operator*=(DenseMatrix< MT, SO > &mat, ST scalar)
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:593
DenseIterator< Type, AF > Iterator
Iterator over non-constant elements.
Definition: CustomVector.h:421
Base template for the BinaryMapTrait class.
Definition: BinaryMapTrait.h:97
Base template for the UnaryMapTrait class.
Definition: UnaryMapTrait.h:95
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
size_t nonZeros() const
Returns the number of non-zero elements in the vector.
Definition: CustomVector.h:1546
#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
Header file for the TrueType type/value trait base class.