Blaze 3.9
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 <array>
45#include <utility>
46#include <blaze/math/Aliases.h>
57#include <blaze/math/Forward.h>
66#include <blaze/math/SIMD.h>
85#include <blaze/system/Inline.h>
89#include <blaze/util/Assert.h>
95#include <blaze/util/EnableIf.h>
99#include <blaze/util/Types.h>
102
103
104namespace blaze {
105
106//=================================================================================================
107//
108// CLASS DEFINITION
109//
110//=================================================================================================
111
112//*************************************************************************************************
399template< typename Type // Data type of the vector
400 , AlignmentFlag AF // Alignment flag
401 , PaddingFlag PF // Padding flag
402 , bool TF // Transpose flag
403 , typename Tag // Type tag
404 , typename RT > // Result type
406 : public DenseVector< CustomVector<Type,AF,PF,TF,Tag,RT>, TF >
407{
408 public:
409 //**Type definitions****************************************************************************
412
414 using ResultType = RT;
415
418
419 using ElementType = Type;
421 using TagType = Tag;
422 using ReturnType = const Type&;
424
425 using Reference = Type&;
426 using ConstReference = const Type&;
427 using Pointer = Type*;
428 using ConstPointer = const Type*;
429
432 //**********************************************************************************************
433
434 //**Rebind struct definition********************************************************************
437 template< typename NewType > // Data type of the other vector
438 struct Rebind {
441 };
442 //**********************************************************************************************
443
444 //**Resize struct definition********************************************************************
447 template< size_t NewN > // Number of elements of the other vector
448 struct Resize {
451 };
452 //**********************************************************************************************
453
454 //**Compilation flags***************************************************************************
456
460 static constexpr bool simdEnabled = IsVectorizable_v<Type>;
461
463
466 static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
467 //**********************************************************************************************
468
469 //**Constructors********************************************************************************
472 inline CustomVector();
473 inline CustomVector( Type* ptr, size_t n );
474 inline CustomVector( Type* ptr, size_t n, size_t nn );
475 inline CustomVector( const CustomVector& v );
476 inline CustomVector( CustomVector&& v ) noexcept;
478 //**********************************************************************************************
479
480 //**Destructor**********************************************************************************
483 inline ~CustomVector();
485 //**********************************************************************************************
486
487 //**Data access functions***********************************************************************
490 inline Reference operator[]( size_t index ) noexcept;
491 inline ConstReference operator[]( size_t index ) const noexcept;
492 inline Reference at( size_t index );
493 inline ConstReference at( size_t index ) const;
494 inline Pointer data () noexcept;
495 inline ConstPointer data () const noexcept;
496 inline Iterator begin () noexcept;
497 inline ConstIterator begin () const noexcept;
498 inline ConstIterator cbegin() const noexcept;
499 inline Iterator end () noexcept;
500 inline ConstIterator end () const noexcept;
501 inline ConstIterator cend () const noexcept;
503 //**********************************************************************************************
504
505 //**Assignment operators************************************************************************
508 inline CustomVector& operator=( const Type& rhs );
509 inline CustomVector& operator=( initializer_list<Type> list );
510
511 template< typename Other, size_t Dim >
512 inline CustomVector& operator=( const Other (&array)[Dim] );
513
514 template< typename Other, size_t Dim >
515 inline CustomVector& operator=( const std::array<Other,Dim>& array );
516
517 inline CustomVector& operator=( const CustomVector& rhs );
518 inline CustomVector& operator=( CustomVector&& rhs ) noexcept;
519
520 template< typename VT > inline CustomVector& operator= ( const Vector<VT,TF>& rhs );
521 template< typename VT > inline CustomVector& operator+=( const Vector<VT,TF>& rhs );
522 template< typename VT > inline CustomVector& operator-=( const Vector<VT,TF>& rhs );
523 template< typename VT > inline CustomVector& operator*=( const Vector<VT,TF>& rhs );
524 template< typename VT > inline CustomVector& operator/=( const DenseVector<VT,TF>& rhs );
525 template< typename VT > inline CustomVector& operator%=( const Vector<VT,TF>& rhs );
527 //**********************************************************************************************
528
529 //**Utility functions***************************************************************************
532 inline size_t size() const noexcept;
533 inline size_t spacing() const noexcept;
534 inline size_t capacity() const noexcept;
535 inline size_t nonZeros() const;
536 inline void reset();
537 inline void clear();
538 inline void swap( CustomVector& v ) noexcept;
540 //**********************************************************************************************
541
542 //**Numeric functions***************************************************************************
545 template< typename Other > inline CustomVector& scale( const Other& scalar );
547 //**********************************************************************************************
548
549 //**Resource management functions***************************************************************
552 inline void reset( Type* ptr, size_t n );
553 inline void reset( Type* ptr, size_t n, size_t nn );
555 //**********************************************************************************************
556
557 private:
558 //**********************************************************************************************
560
561 template< typename VT >
562 static constexpr bool VectorizedAssign_v =
563 ( useOptimizedKernels &&
564 simdEnabled && VT::simdEnabled &&
565 IsSIMDCombinable_v< Type, ElementType_t<VT> > );
567 //**********************************************************************************************
568
569 //**********************************************************************************************
571
572 template< typename VT >
573 static constexpr bool VectorizedAddAssign_v =
574 ( VectorizedAssign_v<VT> &&
575 HasSIMDAdd_v< Type, ElementType_t<VT> > );
577 //**********************************************************************************************
578
579 //**********************************************************************************************
581
582 template< typename VT >
583 static constexpr bool VectorizedSubAssign_v =
584 ( VectorizedAssign_v<VT> &&
585 HasSIMDSub_v< Type, ElementType_t<VT> > );
587 //**********************************************************************************************
588
589 //**********************************************************************************************
591
592 template< typename VT >
593 static constexpr bool VectorizedMultAssign_v =
594 ( VectorizedAssign_v<VT> &&
595 HasSIMDMult_v< Type, ElementType_t<VT> > );
597 //**********************************************************************************************
598
599 //**********************************************************************************************
601
602 template< typename VT >
603 static constexpr bool VectorizedDivAssign_v =
604 ( VectorizedAssign_v<VT> &&
605 HasSIMDDiv_v< Type, ElementType_t<VT> > );
607 //**********************************************************************************************
608
609 //**SIMD properties*****************************************************************************
611 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
612 //**********************************************************************************************
613
614 public:
615 //**Expression template evaluation functions****************************************************
618 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
619 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
620
621 inline bool isAligned () const noexcept;
622 inline bool canSMPAssign() const noexcept;
623
624 BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
625 BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
626 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
627
628 BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
629 BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
630 BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
631 BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
632
633 template< typename VT >
634 inline auto assign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
635
636 template< typename VT >
637 inline auto assign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
638
639 template< typename VT > inline void assign( const SparseVector<VT,TF>& rhs );
640
641 template< typename VT >
642 inline auto addAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
643
644 template< typename VT >
645 inline auto addAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
646
647 template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
648
649 template< typename VT >
650 inline auto subAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
651
652 template< typename VT >
653 inline auto subAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
654
655 template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
656
657 template< typename VT >
658 inline auto multAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
659
660 template< typename VT >
661 inline auto multAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
662
663 template< typename VT > inline void multAssign( const SparseVector<VT,TF>& rhs );
664
665 template< typename VT >
666 inline auto divAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
667
668 template< typename VT >
669 inline auto divAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT> >;
671 //**********************************************************************************************
672
673 private:
674 //**Member variables****************************************************************************
677 size_t size_;
678 Type* v_;
685 //**********************************************************************************************
686
687 //**Compile time checks*************************************************************************
693 //**********************************************************************************************
694};
695//*************************************************************************************************
696
697
698
699
700//=================================================================================================
701//
702// CONSTRUCTORS
703//
704//=================================================================================================
705
706//*************************************************************************************************
709template< typename Type // Data type of the vector
710 , AlignmentFlag AF // Alignment flag
711 , PaddingFlag PF // Padding flag
712 , bool TF // Transpose flag
713 , typename Tag // Type tag
714 , typename RT > // Result type
715inline CustomVector<Type,AF,PF,TF,Tag,RT>::CustomVector()
716 : size_( 0UL ) // The size/dimension of the vector
717 , v_ ( nullptr ) // The custom array of elements
718{}
719//*************************************************************************************************
720
721
722//*************************************************************************************************
740template< typename Type // Data type of the vector
741 , AlignmentFlag AF // Alignment flag
742 , PaddingFlag PF // Padding flag
743 , bool TF // Transpose flag
744 , typename Tag // Type tag
745 , typename RT > // Result type
747 : size_( n ) // The size/dimension of the vector
748 , v_ ( ptr ) // The custom array of elements
749{
750 if( ptr == nullptr ) {
751 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
752 }
753
754 if( AF && !checkAlignment( ptr ) ) {
755 BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
756 }
757}
758//*************************************************************************************************
759
760
761//*************************************************************************************************
783template< typename Type // Data type of the vector
784 , AlignmentFlag AF // Alignment flag
785 , PaddingFlag PF // Padding flag
786 , bool TF // Transpose flag
787 , typename Tag // Type tag
788 , typename RT > // Result type
789inline CustomVector<Type,AF,PF,TF,Tag,RT>::CustomVector( Type* ptr, size_t n, size_t nn )
790 : size_( 0UL ) // The size/dimension of the vector
791 , v_ ( nullptr ) // The custom array of elements
792{
794
795 MAYBE_UNUSED( ptr, n, nn );
796}
797//*************************************************************************************************
798
799
800//*************************************************************************************************
807template< typename Type // Data type of the vector
808 , AlignmentFlag AF // Alignment flag
809 , PaddingFlag PF // Padding flag
810 , bool TF // Transpose flag
811 , typename Tag // Type tag
812 , typename RT > // Result type
814 : size_( v.size_ ) // The size/dimension of the vector
815 , v_ ( v.v_ ) // The custom array of elements
816{}
817//*************************************************************************************************
818
819
820//*************************************************************************************************
825template< typename Type // Data type of the vector
826 , AlignmentFlag AF // Alignment flag
827 , PaddingFlag PF // Padding flag
828 , bool TF // Transpose flag
829 , typename Tag // Type tag
830 , typename RT > // Result type
832 : size_( v.size_ ) // The size/dimension of the vector
833 , v_ ( v.v_ ) // The custom array of elements
834{
835 v.size_ = 0UL;
836 v.v_ = nullptr;
837
838 BLAZE_INTERNAL_ASSERT( v.data() == nullptr, "Invalid data reference detected" );
839}
840//*************************************************************************************************
841
842
843
844
845//=================================================================================================
846//
847// DESTRUCTOR
848//
849//=================================================================================================
850
851//*************************************************************************************************
854template< typename Type // Data type of the vector
855 , AlignmentFlag AF // Alignment flag
856 , PaddingFlag PF // Padding flag
857 , bool TF // Transpose flag
858 , typename Tag // Type tag
859 , typename RT > // Result type
861{
867}
868//*************************************************************************************************
869
870
871
872
873//=================================================================================================
874//
875// DATA ACCESS FUNCTIONS
876//
877//=================================================================================================
878
879//*************************************************************************************************
888template< typename Type // Data type of the vector
889 , AlignmentFlag AF // Alignment flag
890 , PaddingFlag PF // Padding flag
891 , bool TF // Transpose flag
892 , typename Tag // Type tag
893 , typename RT > // Result type
896{
897 BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
898 return v_[index];
899}
900//*************************************************************************************************
901
902
903//*************************************************************************************************
912template< typename Type // Data type of the vector
913 , AlignmentFlag AF // Alignment flag
914 , PaddingFlag PF // Padding flag
915 , bool TF // Transpose flag
916 , typename Tag // Type tag
917 , typename RT > // Result type
920{
921 BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
922 return v_[index];
923}
924//*************************************************************************************************
925
926
927//*************************************************************************************************
937template< typename Type // Data type of the vector
938 , AlignmentFlag AF // Alignment flag
939 , PaddingFlag PF // Padding flag
940 , bool TF // Transpose flag
941 , typename Tag // Type tag
942 , typename RT > // Result type
945{
946 if( index >= size_ ) {
947 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
948 }
949 return (*this)[index];
950}
951//*************************************************************************************************
952
953
954//*************************************************************************************************
964template< typename Type // Data type of the vector
965 , AlignmentFlag AF // Alignment flag
966 , PaddingFlag PF // Padding flag
967 , bool TF // Transpose flag
968 , typename Tag // Type tag
969 , typename RT > // Result type
972{
973 if( index >= size_ ) {
974 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
975 }
976 return (*this)[index];
977}
978//*************************************************************************************************
979
980
981//*************************************************************************************************
988template< typename Type // Data type of the vector
989 , AlignmentFlag AF // Alignment flag
990 , PaddingFlag PF // Padding flag
991 , bool TF // Transpose flag
992 , typename Tag // Type tag
993 , typename RT > // Result type
996{
997 return v_;
998}
999//*************************************************************************************************
1000
1001
1002//*************************************************************************************************
1009template< typename Type // Data type of the vector
1010 , AlignmentFlag AF // Alignment flag
1011 , PaddingFlag PF // Padding flag
1012 , bool TF // Transpose flag
1013 , typename Tag // Type tag
1014 , typename RT > // Result type
1017{
1018 return v_;
1019}
1020//*************************************************************************************************
1021
1022
1023//*************************************************************************************************
1028template< typename Type // Data type of the vector
1029 , AlignmentFlag AF // Alignment flag
1030 , PaddingFlag PF // Padding flag
1031 , bool TF // Transpose flag
1032 , typename Tag // Type tag
1033 , typename RT > // Result type
1036{
1037 return Iterator( v_ );
1038}
1039//*************************************************************************************************
1040
1041
1042//*************************************************************************************************
1047template< typename Type // Data type of the vector
1048 , AlignmentFlag AF // Alignment flag
1049 , PaddingFlag PF // Padding flag
1050 , bool TF // Transpose flag
1051 , typename Tag // Type tag
1052 , typename RT > // Result type
1055{
1056 return ConstIterator( v_ );
1057}
1058//*************************************************************************************************
1059
1060
1061//*************************************************************************************************
1066template< typename Type // Data type of the vector
1067 , AlignmentFlag AF // Alignment flag
1068 , PaddingFlag PF // Padding flag
1069 , bool TF // Transpose flag
1070 , typename Tag // Type tag
1071 , typename RT > // Result type
1074{
1075 return ConstIterator( v_ );
1076}
1077//*************************************************************************************************
1078
1079
1080//*************************************************************************************************
1085template< typename Type // Data type of the vector
1086 , AlignmentFlag AF // Alignment flag
1087 , PaddingFlag PF // Padding flag
1088 , bool TF // Transpose flag
1089 , typename Tag // Type tag
1090 , typename RT > // Result type
1093{
1094 return Iterator( v_+size_ );
1095}
1096//*************************************************************************************************
1097
1098
1099//*************************************************************************************************
1104template< typename Type // Data type of the vector
1105 , AlignmentFlag AF // Alignment flag
1106 , PaddingFlag PF // Padding flag
1107 , bool TF // Transpose flag
1108 , typename Tag // Type tag
1109 , typename RT > // Result type
1112{
1113 return ConstIterator( v_+size_ );
1114}
1115//*************************************************************************************************
1116
1117
1118//*************************************************************************************************
1123template< typename Type // Data type of the vector
1124 , AlignmentFlag AF // Alignment flag
1125 , PaddingFlag PF // Padding flag
1126 , bool TF // Transpose flag
1127 , typename Tag // Type tag
1128 , typename RT > // Result type
1131{
1132 return ConstIterator( v_+size_ );
1133}
1134//*************************************************************************************************
1135
1136
1137
1138
1139//=================================================================================================
1140//
1141// ASSIGNMENT OPERATORS
1142//
1143//=================================================================================================
1144
1145//*************************************************************************************************
1151template< typename Type // Data type of the vector
1152 , AlignmentFlag AF // Alignment flag
1153 , PaddingFlag PF // Padding flag
1154 , bool TF // Transpose flag
1155 , typename Tag // Type tag
1156 , typename RT > // Result type
1159{
1160 for( size_t i=0UL; i<size_; ++i )
1161 v_[i] = rhs;
1162 return *this;
1163}
1164//*************************************************************************************************
1165
1166
1167//*************************************************************************************************
1191template< typename Type // Data type of the vector
1192 , AlignmentFlag AF // Alignment flag
1193 , PaddingFlag PF // Padding flag
1194 , bool TF // Transpose flag
1195 , typename Tag // Type tag
1196 , typename RT > // Result type
1199{
1200 if( list.size() > size_ ) {
1201 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom vector" );
1202 }
1203
1204 std::fill( std::copy( list.begin(), list.end(), v_ ), v_+size_, Type() );
1205
1206 return *this;
1207}
1208//*************************************************************************************************
1209
1210
1211//*************************************************************************************************
1239template< typename Type // Data type of the vector
1240 , AlignmentFlag AF // Alignment flag
1241 , PaddingFlag PF // Padding flag
1242 , bool TF // Transpose flag
1243 , typename Tag // Type tag
1244 , typename RT > // Result type
1245template< typename Other // Data type of the static array
1246 , size_t Dim > // Dimension of the static array
1249{
1250 if( size_ != Dim ) {
1251 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1252 }
1253
1254 for( size_t i=0UL; i<Dim; ++i )
1255 v_[i] = array[i];
1256
1257 return *this;
1258}
1259//*************************************************************************************************
1260
1261
1262//*************************************************************************************************
1290template< typename Type // Data type of the vector
1291 , AlignmentFlag AF // Alignment flag
1292 , PaddingFlag PF // Padding flag
1293 , bool TF // Transpose flag
1294 , typename Tag // Type tag
1295 , typename RT > // Result type
1296template< typename Other // Data type of the std::array
1297 , size_t Dim > // Dimension of the std::array
1299 CustomVector<Type,AF,PF,TF,Tag,RT>::operator=( const std::array<Other,Dim>& array )
1300{
1301 if( size_ != Dim ) {
1302 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1303 }
1304
1305 for( size_t i=0UL; i<Dim; ++i )
1306 v_[i] = array[i];
1307
1308 return *this;
1309}
1310//*************************************************************************************************
1311
1312
1313//*************************************************************************************************
1323template< typename Type // Data type of the vector
1324 , AlignmentFlag AF // Alignment flag
1325 , PaddingFlag PF // Padding flag
1326 , bool TF // Transpose flag
1327 , typename Tag // Type tag
1328 , typename RT > // Result type
1331{
1332 if( rhs.size() != size_ ) {
1333 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1334 }
1335
1336 smpAssign( *this, *rhs );
1337
1338 return *this;
1339}
1340//*************************************************************************************************
1341
1342
1343//*************************************************************************************************
1349template< typename Type // Data type of the vector
1350 , AlignmentFlag AF // Alignment flag
1351 , PaddingFlag PF // Padding flag
1352 , bool TF // Transpose flag
1353 , typename Tag // Type tag
1354 , typename RT > // Result type
1357{
1358 size_ = rhs.size_;
1359 v_ = rhs.v_;
1360
1361 rhs.size_ = 0UL;
1362 rhs.v_ = nullptr;
1363
1364 BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
1365
1366 return *this;
1367}
1368//*************************************************************************************************
1369
1370
1371//*************************************************************************************************
1381template< typename Type // Data type of the vector
1382 , AlignmentFlag AF // Alignment flag
1383 , PaddingFlag PF // Padding flag
1384 , bool TF // Transpose flag
1385 , typename Tag // Type tag
1386 , typename RT > // Result type
1387template< typename VT > // Type of the right-hand side vector
1390{
1392
1393 if( (*rhs).size() != size_ ) {
1394 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1395 }
1396
1397 if( (*rhs).canAlias( this ) ) {
1398 const ResultType_t<VT> tmp( *rhs );
1399 smpAssign( *this, tmp );
1400 }
1401 else {
1402 if( IsSparseVector_v<VT> )
1403 reset();
1404 smpAssign( *this, *rhs );
1405 }
1406
1407 return *this;
1408}
1409//*************************************************************************************************
1410
1411
1412//*************************************************************************************************
1422template< typename Type // Data type of the vector
1423 , AlignmentFlag AF // Alignment flag
1424 , PaddingFlag PF // Padding flag
1425 , bool TF // Transpose flag
1426 , typename Tag // Type tag
1427 , typename RT > // Result type
1428template< typename VT > // Type of the right-hand side vector
1431{
1433
1434 if( (*rhs).size() != size_ ) {
1435 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1436 }
1437
1438 if( (*rhs).canAlias( this ) ) {
1439 const ResultType_t<VT> tmp( *rhs );
1440 smpAddAssign( *this, tmp );
1441 }
1442 else {
1443 smpAddAssign( *this, *rhs );
1444 }
1445
1446 return *this;
1447}
1448//*************************************************************************************************
1449
1450
1451//*************************************************************************************************
1462template< typename Type // Data type of the vector
1463 , AlignmentFlag AF // Alignment flag
1464 , PaddingFlag PF // Padding flag
1465 , bool TF // Transpose flag
1466 , typename Tag // Type tag
1467 , typename RT > // Result type
1468template< typename VT > // Type of the right-hand side vector
1471{
1473
1474 if( (*rhs).size() != size_ ) {
1475 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1476 }
1477
1478 if( (*rhs).canAlias( this ) ) {
1479 const ResultType_t<VT> tmp( *rhs );
1480 smpSubAssign( *this, tmp );
1481 }
1482 else {
1483 smpSubAssign( *this, *rhs );
1484 }
1485
1486 return *this;
1487}
1488//*************************************************************************************************
1489
1490
1491//*************************************************************************************************
1502template< typename Type // Data type of the vector
1503 , AlignmentFlag AF // Alignment flag
1504 , PaddingFlag PF // Padding flag
1505 , bool TF // Transpose flag
1506 , typename Tag // Type tag
1507 , typename RT > // Result type
1508template< typename VT > // Type of the right-hand side vector
1511{
1513
1516
1518
1521
1522 if( (*rhs).size() != size_ ) {
1523 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1524 }
1525
1526 if( IsSparseVector_v<VT> || (*rhs).canAlias( this ) ) {
1527 const MultType tmp( *this * (*rhs) );
1528 if( IsSparseVector_v<MultType> )
1529 reset();
1530 smpAssign( *this, tmp );
1531 }
1532 else {
1533 smpMultAssign( *this, *rhs );
1534 }
1535
1536 return *this;
1537}
1538//*************************************************************************************************
1539
1540
1541//*************************************************************************************************
1551template< typename Type // Data type of the vector
1552 , AlignmentFlag AF // Alignment flag
1553 , PaddingFlag PF // Padding flag
1554 , bool TF // Transpose flag
1555 , typename Tag // Type tag
1556 , typename RT > // Result type
1557template< typename VT > // Type of the right-hand side vector
1560{
1562
1565
1567
1571
1572 if( (*rhs).size() != size_ ) {
1573 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1574 }
1575
1576 if( (*rhs).canAlias( this ) ) {
1577 const DivType tmp( *this / (*rhs) );
1578 smpAssign( *this, tmp );
1579 }
1580 else {
1581 smpDivAssign( *this, *rhs );
1582 }
1583
1584 return *this;
1585}
1586//*************************************************************************************************
1587
1588
1589//*************************************************************************************************
1600template< typename Type // Data type of the vector
1601 , AlignmentFlag AF // Alignment flag
1602 , PaddingFlag PF // Padding flag
1603 , bool TF // Transpose flag
1604 , typename Tag // Type tag
1605 , typename RT > // Result type
1606template< typename VT > // Type of the right-hand side vector
1609{
1610 using blaze::assign;
1611
1613
1616
1618
1622
1623 if( size_ != 3UL || (*rhs).size() != 3UL ) {
1624 BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1625 }
1626
1627 const CrossType tmp( *this % (*rhs) );
1628 assign( *this, tmp );
1629
1630 return *this;
1631}
1632//*************************************************************************************************
1633
1634
1635
1636
1637//=================================================================================================
1638//
1639// UTILITY FUNCTIONS
1640//
1641//=================================================================================================
1642
1643//*************************************************************************************************
1648template< typename Type // Data type of the vector
1649 , AlignmentFlag AF // Alignment flag
1650 , PaddingFlag PF // Padding flag
1651 , bool TF // Transpose flag
1652 , typename Tag // Type tag
1653 , typename RT > // Result type
1654inline size_t CustomVector<Type,AF,PF,TF,Tag,RT>::size() const noexcept
1655{
1656 return size_;
1657}
1658//*************************************************************************************************
1659
1660
1661//*************************************************************************************************
1669template< typename Type // Data type of the vector
1670 , AlignmentFlag AF // Alignment flag
1671 , PaddingFlag PF // Padding flag
1672 , bool TF // Transpose flag
1673 , typename Tag // Type tag
1674 , typename RT > // Result type
1676{
1677 return size_;
1678}
1679//*************************************************************************************************
1680
1681
1682//*************************************************************************************************
1687template< typename Type // Data type of the vector
1688 , AlignmentFlag AF // Alignment flag
1689 , PaddingFlag PF // Padding flag
1690 , bool TF // Transpose flag
1691 , typename Tag // Type tag
1692 , typename RT > // Result type
1694{
1695 return size_;
1696}
1697//*************************************************************************************************
1698
1699
1700//*************************************************************************************************
1709template< typename Type // Data type of the vector
1710 , AlignmentFlag AF // Alignment flag
1711 , PaddingFlag PF // Padding flag
1712 , bool TF // Transpose flag
1713 , typename Tag // Type tag
1714 , typename RT > // Result type
1716{
1717 size_t nonzeros( 0 );
1718
1719 for( size_t i=0UL; i<size_; ++i ) {
1720 if( !isDefault<strict>( v_[i] ) )
1721 ++nonzeros;
1722 }
1723
1724 return nonzeros;
1725}
1726//*************************************************************************************************
1727
1728
1729//*************************************************************************************************
1734template< typename Type // Data type of the vector
1735 , AlignmentFlag AF // Alignment flag
1736 , PaddingFlag PF // Padding flag
1737 , bool TF // Transpose flag
1738 , typename Tag // Type tag
1739 , typename RT > // Result type
1741{
1742 using blaze::clear;
1743 for( size_t i=0UL; i<size_; ++i )
1744 clear( v_[i] );
1745}
1746//*************************************************************************************************
1747
1748
1749//*************************************************************************************************
1757template< typename Type // Data type of the vector
1758 , AlignmentFlag AF // Alignment flag
1759 , PaddingFlag PF // Padding flag
1760 , bool TF // Transpose flag
1761 , typename Tag // Type tag
1762 , typename RT > // Result type
1764{
1765 size_ = 0UL;
1766 v_ = nullptr;
1767}
1768//*************************************************************************************************
1769
1770
1771//*************************************************************************************************
1777template< typename Type // Data type of the vector
1778 , AlignmentFlag AF // Alignment flag
1779 , PaddingFlag PF // Padding flag
1780 , bool TF // Transpose flag
1781 , typename Tag // Type tag
1782 , typename RT > // Result type
1784{
1785 using std::swap;
1786
1787 swap( size_, v.size_ );
1788 swap( v_, v.v_ );
1789}
1790//*************************************************************************************************
1791
1792
1793
1794
1795//=================================================================================================
1796//
1797// NUMERIC FUNCTIONS
1798//
1799//=================================================================================================
1800
1801//*************************************************************************************************
1822template< typename Type // Data type of the vector
1823 , AlignmentFlag AF // Alignment flag
1824 , PaddingFlag PF // Padding flag
1825 , bool TF // Transpose flag
1826 , typename Tag // Type tag
1827 , typename RT > // Result type
1828template< typename Other > // Data type of the scalar value
1831{
1832 for( size_t i=0UL; i<size_; ++i )
1833 v_[i] *= scalar;
1834 return *this;
1835}
1836//*************************************************************************************************
1837
1838
1839
1840
1841//=================================================================================================
1842//
1843// RESOURCE MANAGEMENT FUNCTIONS
1844//
1845//=================================================================================================
1846
1847//*************************************************************************************************
1869template< typename Type // Data type of the vector
1870 , AlignmentFlag AF // Alignment flag
1871 , PaddingFlag PF // Padding flag
1872 , bool TF // Transpose flag
1873 , typename Tag // Type tag
1874 , typename RT > // Result type
1875inline void CustomVector<Type,AF,PF,TF,Tag,RT>::reset( Type* ptr, size_t n )
1876{
1877 CustomVector tmp( ptr, n );
1878 swap( tmp );
1879}
1880//*************************************************************************************************
1881
1882
1883//*************************************************************************************************
1908template< typename Type // Data type of the vector
1909 , AlignmentFlag AF // Alignment flag
1910 , PaddingFlag PF // Padding flag
1911 , bool TF // Transpose flag
1912 , typename Tag // Type tag
1913 , typename RT > // Result type
1914inline void CustomVector<Type,AF,PF,TF,Tag,RT>::reset( Type* ptr, size_t n, size_t nn )
1915{
1916 BLAZE_STATIC_ASSERT( PF == padded );
1917
1918 MAYBE_UNUSED( ptr, n, nn );
1919}
1920//*************************************************************************************************
1921
1922
1923
1924
1925//=================================================================================================
1926//
1927// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1928//
1929//=================================================================================================
1930
1931//*************************************************************************************************
1941template< typename Type // Data type of the vector
1942 , AlignmentFlag AF // Alignment flag
1943 , PaddingFlag PF // Padding flag
1944 , bool TF // Transpose flag
1945 , typename Tag // Type tag
1946 , typename RT > // Result type
1947template< typename Other > // Data type of the foreign expression
1948inline bool CustomVector<Type,AF,PF,TF,Tag,RT>::canAlias( const Other* alias ) const noexcept
1949{
1950 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1951}
1952//*************************************************************************************************
1953
1954
1955//*************************************************************************************************
1965template< typename Type // Data type of the vector
1966 , AlignmentFlag AF // Alignment flag
1967 , PaddingFlag PF // Padding flag
1968 , bool TF // Transpose flag
1969 , typename Tag // Type tag
1970 , typename RT > // Result type
1971template< typename Other > // Data type of the foreign expression
1972inline bool CustomVector<Type,AF,PF,TF,Tag,RT>::isAliased( const Other* alias ) const noexcept
1973{
1974 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1975}
1976//*************************************************************************************************
1977
1978
1979//*************************************************************************************************
1988template< typename Type // Data type of the vector
1989 , AlignmentFlag AF // Alignment flag
1990 , PaddingFlag PF // Padding flag
1991 , bool TF // Transpose flag
1992 , typename Tag // Type tag
1993 , typename RT > // Result type
1995{
1996 return ( AF || checkAlignment( v_ ) );
1997}
1998//*************************************************************************************************
1999
2000
2001//*************************************************************************************************
2011template< typename Type // Data type of the vector
2012 , AlignmentFlag AF // Alignment flag
2013 , PaddingFlag PF // Padding flag
2014 , bool TF // Transpose flag
2015 , typename Tag // Type tag
2016 , typename RT > // Result type
2018{
2019 return ( size() > SMP_DVECASSIGN_THRESHOLD );
2020}
2021//*************************************************************************************************
2022
2023
2024//*************************************************************************************************
2036template< typename Type // Data type of the vector
2037 , AlignmentFlag AF // Alignment flag
2038 , PaddingFlag PF // Padding flag
2039 , bool TF // Transpose flag
2040 , typename Tag // Type tag
2041 , typename RT > // Result type
2043 CustomVector<Type,AF,PF,TF,Tag,RT>::load( size_t index ) const noexcept
2044{
2045 if( AF )
2046 return loada( index );
2047 else
2048 return loadu( index );
2049}
2050//*************************************************************************************************
2051
2052
2053//*************************************************************************************************
2066template< typename Type // Data type of the vector
2067 , AlignmentFlag AF // Alignment flag
2068 , PaddingFlag PF // Padding flag
2069 , bool TF // Transpose flag
2070 , typename Tag // Type tag
2071 , typename RT > // Result type
2073 CustomVector<Type,AF,PF,TF,Tag,RT>::loada( size_t index ) const noexcept
2074{
2075 using blaze::loada;
2076
2078
2079 BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
2080 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2081 BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
2082 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
2083
2084 return loada( v_+index );
2085}
2086//*************************************************************************************************
2087
2088
2089//*************************************************************************************************
2102template< typename Type // Data type of the vector
2103 , AlignmentFlag AF // Alignment flag
2104 , PaddingFlag PF // Padding flag
2105 , bool TF // Transpose flag
2106 , typename Tag // Type tag
2107 , typename RT > // Result type
2109 CustomVector<Type,AF,PF,TF,Tag,RT>::loadu( size_t index ) const noexcept
2110{
2111 using blaze::loadu;
2112
2114
2115 BLAZE_INTERNAL_ASSERT( index< size_, "Invalid vector access index" );
2116 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2117
2118 return loadu( v_+index );
2119}
2120//*************************************************************************************************
2121
2122
2123//*************************************************************************************************
2136template< typename Type // Data type of the vector
2137 , AlignmentFlag AF // Alignment flag
2138 , PaddingFlag PF // Padding flag
2139 , bool TF // Transpose flag
2140 , typename Tag // Type tag
2141 , typename RT > // Result type
2143 CustomVector<Type,AF,PF,TF,Tag,RT>::store( size_t index, const SIMDType& value ) noexcept
2144{
2145 if( AF )
2146 storea( index, value );
2147 else
2148 storeu( index, value );
2149}
2150//*************************************************************************************************
2151
2152
2153//*************************************************************************************************
2166template< typename Type // Data type of the vector
2167 , AlignmentFlag AF // Alignment flag
2168 , PaddingFlag PF // Padding flag
2169 , bool TF // Transpose flag
2170 , typename Tag // Type tag
2171 , typename RT > // Result type
2173 CustomVector<Type,AF,PF,TF,Tag,RT>::storea( size_t index, const SIMDType& value ) noexcept
2174{
2175 using blaze::storea;
2176
2178
2179 BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
2180 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2181 BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
2182 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
2183
2184 storea( v_+index, value );
2185}
2186//*************************************************************************************************
2187
2188
2189//*************************************************************************************************
2202template< typename Type // Data type of the vector
2203 , AlignmentFlag AF // Alignment flag
2204 , PaddingFlag PF // Padding flag
2205 , bool TF // Transpose flag
2206 , typename Tag // Type tag
2207 , typename RT > // Result type
2209 CustomVector<Type,AF,PF,TF,Tag,RT>::storeu( size_t index, const SIMDType& value ) noexcept
2210{
2211 using blaze::storeu;
2212
2214
2215 BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
2216 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2217
2218 storeu( v_+index, value );
2219}
2220//*************************************************************************************************
2221
2222
2223//*************************************************************************************************
2237template< typename Type // Data type of the vector
2238 , AlignmentFlag AF // Alignment flag
2239 , PaddingFlag PF // Padding flag
2240 , bool TF // Transpose flag
2241 , typename Tag // Type tag
2242 , typename RT > // Result type
2244 CustomVector<Type,AF,PF,TF,Tag,RT>::stream( size_t index, const SIMDType& value ) noexcept
2245{
2246 using blaze::stream;
2247
2249
2250 BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
2251 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size_, "Invalid vector access index" );
2252 BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
2253 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
2254
2255 stream( v_+index, value );
2256}
2257//*************************************************************************************************
2258
2259
2260//*************************************************************************************************
2271template< typename Type // Data type of the vector
2272 , AlignmentFlag AF // Alignment flag
2273 , PaddingFlag PF // Padding flag
2274 , bool TF // Transpose flag
2275 , typename Tag // Type tag
2276 , typename RT > // Result type
2277template< typename VT > // Type of the right-hand side dense vector
2280{
2281 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2282
2283 const size_t ipos( prevMultiple( size_, 2UL ) );
2284 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2285
2286 for( size_t i=0UL; i<ipos; i+=2UL ) {
2287 v_[i ] = (*rhs)[i ];
2288 v_[i+1UL] = (*rhs)[i+1UL];
2289 }
2290 if( ipos < (*rhs).size() )
2291 v_[ipos] = (*rhs)[ipos];
2292}
2293//*************************************************************************************************
2294
2295
2296//*************************************************************************************************
2307template< typename Type // Data type of the vector
2308 , AlignmentFlag AF // Alignment flag
2309 , PaddingFlag PF // Padding flag
2310 , bool TF // Transpose flag
2311 , typename Tag // Type tag
2312 , typename RT > // Result type
2313template< typename VT > // Type of the right-hand side dense vector
2316{
2318
2319 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2320
2321 const size_t ipos( prevMultiple( size_, SIMDSIZE ) );
2322 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2323
2324 if( AF && useStreaming && size_ > ( cacheSize/( sizeof(Type) * 3UL ) ) && !(*rhs).isAliased( this ) )
2325 {
2326 size_t i( 0UL );
2327
2328 for( ; i<ipos; i+=SIMDSIZE ) {
2329 stream( i, (*rhs).load(i) );
2330 }
2331 for( ; i<size_; ++i ) {
2332 v_[i] = (*rhs)[i];
2333 }
2334 }
2335 else
2336 {
2337 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
2338 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
2339
2340 size_t i( 0UL );
2341 ConstIterator_t<VT> it( (*rhs).begin() );
2342
2343 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2344 store( i , it.load() ); it += SIMDSIZE;
2345 store( i+SIMDSIZE , it.load() ); it += SIMDSIZE;
2346 store( i+SIMDSIZE*2UL, it.load() ); it += SIMDSIZE;
2347 store( i+SIMDSIZE*3UL, it.load() ); it += SIMDSIZE;
2348 }
2349 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2350 store( i, it.load() );
2351 }
2352 for( ; i<size_; ++i, ++it ) {
2353 v_[i] = *it;
2354 }
2355 }
2356}
2357//*************************************************************************************************
2358
2359
2360//*************************************************************************************************
2371template< typename Type // Data type of the vector
2372 , AlignmentFlag AF // Alignment flag
2373 , PaddingFlag PF // Padding flag
2374 , bool TF // Transpose flag
2375 , typename Tag // Type tag
2376 , typename RT > // Result type
2377template< typename VT > // Type of the right-hand side sparse vector
2379{
2380 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2381
2382 for( auto element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2383 v_[element->index()] = element->value();
2384}
2385//*************************************************************************************************
2386
2387
2388//*************************************************************************************************
2399template< typename Type // Data type of the vector
2400 , AlignmentFlag AF // Alignment flag
2401 , PaddingFlag PF // Padding flag
2402 , bool TF // Transpose flag
2403 , typename Tag // Type tag
2404 , typename RT > // Result type
2405template< typename VT > // Type of the right-hand side dense vector
2408{
2409 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2410
2411 const size_t ipos( prevMultiple( size_, 2UL ) );
2412 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2413
2414 for( size_t i=0UL; i<ipos; i+=2UL ) {
2415 v_[i ] += (*rhs)[i ];
2416 v_[i+1UL] += (*rhs)[i+1UL];
2417 }
2418 if( ipos < (*rhs).size() )
2419 v_[ipos] += (*rhs)[ipos];
2420}
2421//*************************************************************************************************
2422
2423
2424//*************************************************************************************************
2435template< typename Type // Data type of the vector
2436 , AlignmentFlag AF // Alignment flag
2437 , PaddingFlag PF // Padding flag
2438 , bool TF // Transpose flag
2439 , typename Tag // Type tag
2440 , typename RT > // Result type
2441template< typename VT > // Type of the right-hand side dense vector
2444{
2446
2447 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2448
2449 const size_t ipos( prevMultiple( size_, SIMDSIZE ) );
2450 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2451
2452 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
2453 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
2454
2455 size_t i( 0UL );
2456 ConstIterator_t<VT> it( (*rhs).begin() );
2457
2458 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2459 store( i , load(i ) + it.load() ); it += SIMDSIZE;
2460 store( i+SIMDSIZE , load(i+SIMDSIZE ) + it.load() ); it += SIMDSIZE;
2461 store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) + it.load() ); it += SIMDSIZE;
2462 store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) + it.load() ); it += SIMDSIZE;
2463 }
2464 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2465 store( i, load(i) + it.load() );
2466 }
2467 for( ; i<size_; ++i, ++it ) {
2468 v_[i] += *it;
2469 }
2470}
2471//*************************************************************************************************
2472
2473
2474//*************************************************************************************************
2485template< typename Type // Data type of the vector
2486 , AlignmentFlag AF // Alignment flag
2487 , PaddingFlag PF // Padding flag
2488 , bool TF // Transpose flag
2489 , typename Tag // Type tag
2490 , typename RT > // Result type
2491template< typename VT > // Type of the right-hand side sparse vector
2493{
2494 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2495
2496 for( auto element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2497 v_[element->index()] += element->value();
2498}
2499//*************************************************************************************************
2500
2501
2502//*************************************************************************************************
2513template< typename Type // Data type of the vector
2514 , AlignmentFlag AF // Alignment flag
2515 , PaddingFlag PF // Padding flag
2516 , bool TF // Transpose flag
2517 , typename Tag // Type tag
2518 , typename RT > // Result type
2519template< typename VT > // Type of the right-hand side dense vector
2522{
2523 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2524
2525 const size_t ipos( prevMultiple( size_, 2UL ) );
2526 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2527
2528 for( size_t i=0UL; i<ipos; i+=2UL ) {
2529 v_[i ] -= (*rhs)[i ];
2530 v_[i+1UL] -= (*rhs)[i+1UL];
2531 }
2532 if( ipos < (*rhs).size() )
2533 v_[ipos] -= (*rhs)[ipos];
2534}
2535//*************************************************************************************************
2536
2537
2538//*************************************************************************************************
2549template< typename Type // Data type of the vector
2550 , AlignmentFlag AF // Alignment flag
2551 , PaddingFlag PF // Padding flag
2552 , bool TF // Transpose flag
2553 , typename Tag // Type tag
2554 , typename RT > // Result type
2555template< 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( prevMultiple( size_, SIMDSIZE ) );
2564 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2565
2566 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
2567 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
2568
2569 size_t i( 0UL );
2570 ConstIterator_t<VT> it( (*rhs).begin() );
2571
2572 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2573 store( i , load(i ) - it.load() ); it += SIMDSIZE;
2574 store( i+SIMDSIZE , load(i+SIMDSIZE ) - it.load() ); it += SIMDSIZE;
2575 store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) - it.load() ); it += SIMDSIZE;
2576 store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) - it.load() ); it += SIMDSIZE;
2577 }
2578 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2579 store( i, load(i) - it.load() );
2580 }
2581 for( ; i<size_; ++i, ++it ) {
2582 v_[i] -= *it;
2583 }
2584}
2585//*************************************************************************************************
2586
2587
2588//*************************************************************************************************
2599template< typename Type // Data type of the vector
2600 , AlignmentFlag AF // Alignment flag
2601 , PaddingFlag PF // Padding flag
2602 , bool TF // Transpose flag
2603 , typename Tag // Type tag
2604 , typename RT > // Result type
2605template< typename VT > // Type of the right-hand side sparse vector
2607{
2608 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2609
2610 for( auto element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2611 v_[element->index()] -= element->value();
2612}
2613//*************************************************************************************************
2614
2615
2616//*************************************************************************************************
2627template< typename Type // Data type of the vector
2628 , AlignmentFlag AF // Alignment flag
2629 , PaddingFlag PF // Padding flag
2630 , bool TF // Transpose flag
2631 , typename Tag // Type tag
2632 , typename RT > // Result type
2633template< typename VT > // Type of the right-hand side dense vector
2636{
2637 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2638
2639 const size_t ipos( prevMultiple( size_, 2UL ) );
2640 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2641
2642 for( size_t i=0UL; i<ipos; i+=2UL ) {
2643 v_[i ] *= (*rhs)[i ];
2644 v_[i+1UL] *= (*rhs)[i+1UL];
2645 }
2646 if( ipos < (*rhs).size() )
2647 v_[ipos] *= (*rhs)[ipos];
2648}
2649//*************************************************************************************************
2650
2651
2652//*************************************************************************************************
2663template< typename Type // Data type of the vector
2664 , AlignmentFlag AF // Alignment flag
2665 , PaddingFlag PF // Padding flag
2666 , bool TF // Transpose flag
2667 , typename Tag // Type tag
2668 , typename RT > // Result type
2669template< typename VT > // Type of the right-hand side dense vector
2672{
2674
2675 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2676
2677 const size_t ipos( prevMultiple( size_, SIMDSIZE ) );
2678 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2679
2680 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
2681 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
2682
2683 size_t i( 0UL );
2684 ConstIterator_t<VT> it( (*rhs).begin() );
2685
2686 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2687 store( i , load(i ) * it.load() ); it += SIMDSIZE;
2688 store( i+SIMDSIZE , load(i+SIMDSIZE ) * it.load() ); it += SIMDSIZE;
2689 store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) * it.load() ); it += SIMDSIZE;
2690 store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) * it.load() ); it += SIMDSIZE;
2691 }
2692 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2693 store( i, load(i) * it.load() );
2694 }
2695 for( ; i<size_; ++i, ++it ) {
2696 v_[i] *= *it;
2697 }
2698}
2699//*************************************************************************************************
2700
2701
2702//*************************************************************************************************
2713template< typename Type // Data type of the vector
2714 , AlignmentFlag AF // Alignment flag
2715 , PaddingFlag PF // Padding flag
2716 , bool TF // Transpose flag
2717 , typename Tag // Type tag
2718 , typename RT > // Result type
2719template< typename VT > // Type of the right-hand side sparse vector
2721{
2722 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2723
2724 const ResultType tmp( serial( *this ) );
2725
2726 reset();
2727
2728 for( auto element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2729 v_[element->index()] = tmp[element->index()] * element->value();
2730}
2731//*************************************************************************************************
2732
2733
2734//*************************************************************************************************
2745template< typename Type // Data type of the vector
2746 , AlignmentFlag AF // Alignment flag
2747 , PaddingFlag PF // Padding flag
2748 , bool TF // Transpose flag
2749 , typename Tag // Type tag
2750 , typename RT > // Result type
2751template< typename VT > // Type of the right-hand side dense vector
2754{
2755 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2756
2757 const size_t ipos( prevMultiple( size_, 2UL ) );
2758 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2759
2760 for( size_t i=0UL; i<ipos; i+=2UL ) {
2761 v_[i ] /= (*rhs)[i ];
2762 v_[i+1UL] /= (*rhs)[i+1UL];
2763 }
2764 if( ipos < (*rhs).size() )
2765 v_[ipos] /= (*rhs)[ipos];
2766}
2767//*************************************************************************************************
2768
2769
2770//*************************************************************************************************
2781template< typename Type // Data type of the vector
2782 , AlignmentFlag AF // Alignment flag
2783 , PaddingFlag PF // Padding flag
2784 , bool TF // Transpose flag
2785 , typename Tag // Type tag
2786 , typename RT > // Result type
2787template< typename VT > // Type of the right-hand side dense vector
2790{
2792
2793 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
2794
2795 const size_t ipos( prevMultiple( size_, SIMDSIZE ) );
2796 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
2797
2798 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
2799 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
2800
2801 size_t i( 0UL );
2802 ConstIterator_t<VT> it( (*rhs).begin() );
2803
2804 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
2805 store( i , load(i ) / it.load() ); it += SIMDSIZE;
2806 store( i+SIMDSIZE , load(i+SIMDSIZE ) / it.load() ); it += SIMDSIZE;
2807 store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) / it.load() ); it += SIMDSIZE;
2808 store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) / it.load() ); it += SIMDSIZE;
2809 }
2810 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
2811 store( i, load(i) / it.load() );
2812 }
2813 for( ; i<size_; ++i, ++it ) {
2814 v_[i] /= *it;
2815 }
2816}
2817//*************************************************************************************************
2818
2819
2820
2821
2822
2823
2824
2825
2826//=================================================================================================
2827//
2828// CLASS TEMPLATE SPECIALIZATION FOR PADDED VECTORS
2829//
2830//=================================================================================================
2831
2832//*************************************************************************************************
2840template< typename Type // Data type of the vector
2841 , AlignmentFlag AF // Alignment flag
2842 , bool TF // Transpose flag
2843 , typename Tag // Type tag
2844 , typename RT > // Result type
2845class CustomVector<Type,AF,padded,TF,Tag,RT>
2846 : public DenseVector< CustomVector<Type,AF,padded,TF,Tag,RT>, TF >
2847{
2848 public:
2849 //**Type definitions****************************************************************************
2850 using This = CustomVector<Type,AF,padded,TF,Tag,RT>;
2851 using BaseType = DenseVector<This,TF>;
2852
2854 using ResultType = RT;
2855
2857 using TransposeType = CustomTransposeType_t<RT>;
2858
2859 using ElementType = Type;
2860 using SIMDType = SIMDTrait_t<ElementType>;
2861 using TagType = Tag;
2862 using ReturnType = const Type&;
2863 using CompositeType = const CustomVector&;
2864
2865 using Reference = Type&;
2866 using ConstReference = const Type&;
2867 using Pointer = Type*;
2868 using ConstPointer = const Type*;
2869
2870 using Iterator = DenseIterator<Type,AF>;
2871 using ConstIterator = DenseIterator<const Type,AF>;
2872 //**********************************************************************************************
2873
2874 //**Rebind struct definition********************************************************************
2877 template< typename NewType > // Data type of the other vector
2878 struct Rebind {
2879 using RRT = Rebind_t< RT, RemoveConst_t<NewType> >;
2880 using Other = CustomVector<NewType,AF,padded,TF,Tag,RRT>;
2881 };
2882 //**********************************************************************************************
2883
2884 //**Resize struct definition********************************************************************
2887 template< size_t NewN > // Number of elements of the other vector
2888 struct Resize {
2889 using RRT = Resize_t<RT,NewN>;
2890 using Other = CustomVector<Type,AF,padded,TF,Tag,RRT>;
2891 };
2892 //**********************************************************************************************
2893
2894 //**Compilation flags***************************************************************************
2896
2900 static constexpr bool simdEnabled = IsVectorizable_v<Type>;
2901
2903
2906 static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
2907 //**********************************************************************************************
2908
2909 //**Constructors********************************************************************************
2912 inline CustomVector();
2913 inline CustomVector( Type* ptr, size_t n, size_t nn );
2914 inline CustomVector( const CustomVector& v );
2915 inline CustomVector( CustomVector&& v ) noexcept;
2917 //**********************************************************************************************
2918
2919 //**Destructor**********************************************************************************
2922 inline ~CustomVector();
2924 //**********************************************************************************************
2925
2926 //**Data access functions***********************************************************************
2929 inline Reference operator[]( size_t index ) noexcept;
2930 inline ConstReference operator[]( size_t index ) const noexcept;
2931 inline Reference at( size_t index );
2932 inline ConstReference at( size_t index ) const;
2933 inline Pointer data () noexcept;
2934 inline ConstPointer data () const noexcept;
2935 inline Iterator begin () noexcept;
2936 inline ConstIterator begin () const noexcept;
2937 inline ConstIterator cbegin() const noexcept;
2938 inline Iterator end () noexcept;
2939 inline ConstIterator end () const noexcept;
2940 inline ConstIterator cend () const noexcept;
2942 //**********************************************************************************************
2943
2944 //**Assignment operators************************************************************************
2947 inline CustomVector& operator=( const Type& rhs );
2948 inline CustomVector& operator=( initializer_list<Type> list );
2949
2950 template< typename Other, size_t Dim >
2951 inline CustomVector& operator=( const Other (&array)[Dim] );
2952
2953 template< typename Other, size_t Dim >
2954 inline CustomVector& operator=( const std::array<Other,Dim>& array );
2955
2956 inline CustomVector& operator=( const CustomVector& rhs );
2957 inline CustomVector& operator=( CustomVector&& rhs ) noexcept;
2958
2959 template< typename VT > inline CustomVector& operator= ( const Vector<VT,TF>& rhs );
2960 template< typename VT > inline CustomVector& operator+=( const Vector<VT,TF>& rhs );
2961 template< typename VT > inline CustomVector& operator-=( const Vector<VT,TF>& rhs );
2962 template< typename VT > inline CustomVector& operator*=( const Vector<VT,TF>& rhs );
2963 template< typename VT > inline CustomVector& operator/=( const DenseVector<VT,TF>& rhs );
2964 template< typename VT > inline CustomVector& operator%=( const Vector<VT,TF>& rhs );
2966 //**********************************************************************************************
2967
2968 //**Utility functions***************************************************************************
2971 inline size_t size() const noexcept;
2972 inline size_t spacing() const noexcept;
2973 inline size_t capacity() const noexcept;
2974 inline size_t nonZeros() const;
2975 inline void reset();
2976 inline void clear();
2977 inline void swap( CustomVector& v ) noexcept;
2979 //**********************************************************************************************
2980
2981 //**Numeric functions***************************************************************************
2984 template< typename Other > inline CustomVector& scale( const Other& scalar );
2986 //**********************************************************************************************
2987
2988 //**Resource management functions***************************************************************
2991 inline void reset( Type* ptr, size_t n, size_t nn );
2993 //**********************************************************************************************
2994
2995 private:
2996 //**********************************************************************************************
2998 template< typename VT >
2999 static constexpr bool VectorizedAssign_v =
3000 ( useOptimizedKernels &&
3001 simdEnabled && VT::simdEnabled &&
3002 IsSIMDCombinable_v< Type, ElementType_t<VT> > );
3003 //**********************************************************************************************
3004
3005 //**********************************************************************************************
3007 template< typename VT >
3008 static constexpr bool VectorizedAddAssign_v =
3009 ( VectorizedAssign_v<VT> &&
3010 HasSIMDAdd_v< Type, ElementType_t<VT> > );
3011 //**********************************************************************************************
3012
3013 //**********************************************************************************************
3015 template< typename VT >
3016 static constexpr bool VectorizedSubAssign_v =
3017 ( VectorizedAssign_v<VT> &&
3018 HasSIMDSub_v< Type, ElementType_t<VT> > );
3019 //**********************************************************************************************
3020
3021 //**********************************************************************************************
3023 template< typename VT >
3024 static constexpr bool VectorizedMultAssign_v =
3025 ( VectorizedAssign_v<VT> &&
3026 HasSIMDMult_v< Type, ElementType_t<VT> > );
3027 //**********************************************************************************************
3028
3029 //**********************************************************************************************
3031 template< typename VT >
3032 static constexpr bool VectorizedDivAssign_v =
3033 ( VectorizedAssign_v<VT> &&
3034 HasSIMDDiv_v< Type, ElementType_t<VT> > );
3035 //**********************************************************************************************
3036
3037 //**SIMD properties*****************************************************************************
3039 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
3040 //**********************************************************************************************
3041
3042 public:
3043 //**Expression template evaluation functions****************************************************
3046 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3047 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3048
3049 inline bool isAligned () const noexcept;
3050 inline bool canSMPAssign() const noexcept;
3051
3052 BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
3053 BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
3054 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
3055
3056 BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
3057 BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
3058 BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
3059 BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
3060
3061 template< typename VT >
3062 inline auto assign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
3063
3064 template< typename VT >
3065 inline auto assign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
3066
3067 template< typename VT > inline void assign( const SparseVector<VT,TF>& rhs );
3068
3069 template< typename VT >
3070 inline auto addAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
3071
3072 template< typename VT >
3073 inline auto addAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
3074
3075 template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
3076
3077 template< typename VT >
3078 inline auto subAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
3079
3080 template< typename VT >
3081 inline auto subAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
3082
3083 template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
3084
3085 template< typename VT >
3086 inline auto multAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
3087
3088 template< typename VT >
3089 inline auto multAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
3090
3091 template< typename VT > inline void multAssign( const SparseVector<VT,TF>& rhs );
3092
3093 template< typename VT >
3094 inline auto divAssign( const DenseVector<VT,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
3095
3096 template< typename VT >
3097 inline auto divAssign( const DenseVector<VT,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT> >;
3099 //**********************************************************************************************
3100
3101 private:
3102 //**Member variables****************************************************************************
3105 size_t size_;
3106 size_t capacity_;
3107 Type* v_;
3114 //**********************************************************************************************
3115
3116 //**Compile time checks*************************************************************************
3120 //**********************************************************************************************
3121};
3123//*************************************************************************************************
3124
3125
3126
3127
3128//=================================================================================================
3129//
3130// CONSTRUCTORS
3131//
3132//=================================================================================================
3133
3134//*************************************************************************************************
3138template< typename Type // Data type of the vector
3139 , AlignmentFlag AF // Alignment flag
3140 , bool TF // Transpose flag
3141 , typename Tag // Type tag
3142 , typename RT > // Result type
3143inline CustomVector<Type,AF,padded,TF,Tag,RT>::CustomVector()
3144 : size_ ( 0UL ) // The size/dimension of the vector
3145 , capacity_( 0UL ) // The maximum capacity of the vector
3146 , v_ ( nullptr ) // The custom array of elements
3147{}
3149//*************************************************************************************************
3150
3151
3152//*************************************************************************************************
3174template< typename Type // Data type of the vector
3175 , AlignmentFlag AF // Alignment flag
3176 , bool TF // Transpose flag
3177 , typename Tag // Type tag
3178 , typename RT > // Result type
3179inline CustomVector<Type,AF,padded,TF,Tag,RT>::CustomVector( Type* ptr, size_t n, size_t nn )
3180 : size_ ( n ) // The size/dimension of the vector
3181 , capacity_( nn ) // The maximum capacity of the vector
3182 , v_ ( ptr ) // The custom array of elements
3183{
3184 using blaze::clear;
3185
3186 if( ptr == nullptr ) {
3187 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3188 }
3189
3190 if( AF && !checkAlignment( ptr ) ) {
3191 BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3192 }
3193
3194 if( IsVectorizable_v<Type> && capacity_ < nextMultiple<size_t>( size_, SIMDSIZE ) ) {
3195 BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded vector" );
3196 }
3197
3198 if( IsVectorizable_v<Type> ) {
3199 for( size_t i=size_; i<capacity_; ++i )
3200 clear( v_[i] );
3201 }
3202}
3204//*************************************************************************************************
3205
3206
3207//*************************************************************************************************
3215template< typename Type // Data type of the vector
3216 , AlignmentFlag AF // Alignment flag
3217 , bool TF // Transpose flag
3218 , typename Tag // Type tag
3219 , typename RT > // Result type
3220inline CustomVector<Type,AF,padded,TF,Tag,RT>::CustomVector( const CustomVector& v )
3221 : size_ ( v.size_ ) // The size/dimension of the vector
3222 , capacity_( v.capacity_ ) // The maximum capacity of the vector
3223 , v_ ( v.v_ ) // The custom array of elements
3224{}
3226//*************************************************************************************************
3227
3228
3229//*************************************************************************************************
3235template< typename Type // Data type of the vector
3236 , AlignmentFlag AF // Alignment flag
3237 , bool TF // Transpose flag
3238 , typename Tag // Type tag
3239 , typename RT > // Result type
3240inline CustomVector<Type,AF,padded,TF,Tag,RT>::CustomVector( CustomVector&& v ) noexcept
3241 : size_ ( v.size_ ) // The size/dimension of the vector
3242 , capacity_( v.capacity_ ) // The maximum capacity of the vector
3243 , v_ ( v.v_ ) // The custom array of elements
3244{
3245 v.size_ = 0UL;
3246 v.capacity_ = 0UL;
3247 v.v_ = nullptr;
3248
3249 BLAZE_INTERNAL_ASSERT( v.data() == nullptr, "Invalid data reference detected" );
3250}
3252//*************************************************************************************************
3253
3254
3255
3256
3257//=================================================================================================
3258//
3259// DESTRUCTOR
3260//
3261//=================================================================================================
3262
3263//*************************************************************************************************
3267template< typename Type // Data type of the vector
3268 , AlignmentFlag AF // Alignment flag
3269 , bool TF // Transpose flag
3270 , typename Tag // Type tag
3271 , typename RT > // Result type
3273{
3276 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<RT> );
3279}
3281//*************************************************************************************************
3282
3283
3284
3285
3286//=================================================================================================
3287//
3288// DATA ACCESS FUNCTIONS
3289//
3290//=================================================================================================
3291
3292//*************************************************************************************************
3302template< typename Type // Data type of the vector
3303 , AlignmentFlag AF // Alignment flag
3304 , bool TF // Transpose flag
3305 , typename Tag // Type tag
3306 , typename RT > // Result type
3309{
3310 BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
3311 return v_[index];
3312}
3314//*************************************************************************************************
3315
3316
3317//*************************************************************************************************
3327template< typename Type // Data type of the vector
3328 , AlignmentFlag AF // Alignment flag
3329 , bool TF // Transpose flag
3330 , typename Tag // Type tag
3331 , typename RT > // Result type
3333 CustomVector<Type,AF,padded,TF,Tag,RT>::operator[]( size_t index ) const noexcept
3334{
3335 BLAZE_USER_ASSERT( index < size_, "Invalid vector access index" );
3336 return v_[index];
3337}
3339//*************************************************************************************************
3340
3341
3342//*************************************************************************************************
3353template< typename Type // Data type of the vector
3354 , AlignmentFlag AF // Alignment flag
3355 , bool TF // Transpose flag
3356 , typename Tag // Type tag
3357 , typename RT > // Result type
3360{
3361 if( index >= size_ ) {
3362 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
3363 }
3364 return (*this)[index];
3365}
3367//*************************************************************************************************
3368
3369
3370//*************************************************************************************************
3381template< typename Type // Data type of the vector
3382 , AlignmentFlag AF // Alignment flag
3383 , bool TF // Transpose flag
3384 , typename Tag // Type tag
3385 , typename RT > // Result type
3387 CustomVector<Type,AF,padded,TF,Tag,RT>::at( size_t index ) const
3388{
3389 if( index >= size_ ) {
3390 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
3391 }
3392 return (*this)[index];
3393}
3395//*************************************************************************************************
3396
3397
3398//*************************************************************************************************
3406template< typename Type // Data type of the vector
3407 , AlignmentFlag AF // Alignment flag
3408 , bool TF // Transpose flag
3409 , typename Tag // Type tag
3410 , typename RT > // Result type
3413{
3414 return v_;
3415}
3417//*************************************************************************************************
3418
3419
3420//*************************************************************************************************
3428template< typename Type // Data type of the vector
3429 , AlignmentFlag AF // Alignment flag
3430 , bool TF // Transpose flag
3431 , typename Tag // Type tag
3432 , typename RT > // Result type
3435{
3436 return v_;
3437}
3439//*************************************************************************************************
3440
3441
3442//*************************************************************************************************
3448template< typename Type // Data type of the vector
3449 , AlignmentFlag AF // Alignment flag
3450 , bool TF // Transpose flag
3451 , typename Tag // Type tag
3452 , typename RT > // Result type
3455{
3456 return Iterator( v_ );
3457}
3459//*************************************************************************************************
3460
3461
3462//*************************************************************************************************
3468template< typename Type // Data type of the vector
3469 , AlignmentFlag AF // Alignment flag
3470 , bool TF // Transpose flag
3471 , typename Tag // Type tag
3472 , typename RT > // Result type
3475{
3476 return ConstIterator( v_ );
3477}
3479//*************************************************************************************************
3480
3481
3482//*************************************************************************************************
3488template< typename Type // Data type of the vector
3489 , AlignmentFlag AF // Alignment flag
3490 , bool TF // Transpose flag
3491 , typename Tag // Type tag
3492 , typename RT > // Result type
3495{
3496 return ConstIterator( v_ );
3497}
3499//*************************************************************************************************
3500
3501
3502//*************************************************************************************************
3508template< typename Type // Data type of the vector
3509 , AlignmentFlag AF // Alignment flag
3510 , bool TF // Transpose flag
3511 , typename Tag // Type tag
3512 , typename RT > // Result type
3515{
3516 return Iterator( v_+size_ );
3517}
3519//*************************************************************************************************
3520
3521
3522//*************************************************************************************************
3528template< typename Type // Data type of the vector
3529 , AlignmentFlag AF // Alignment flag
3530 , bool TF // Transpose flag
3531 , typename Tag // Type tag
3532 , typename RT > // Result type
3535{
3536 return ConstIterator( v_+size_ );
3537}
3539//*************************************************************************************************
3540
3541
3542//*************************************************************************************************
3548template< typename Type // Data type of the vector
3549 , AlignmentFlag AF // Alignment flag
3550 , bool TF // Transpose flag
3551 , typename Tag // Type tag
3552 , typename RT > // Result type
3555{
3556 return ConstIterator( v_+size_ );
3557}
3559//*************************************************************************************************
3560
3561
3562
3563
3564//=================================================================================================
3565//
3566// ASSIGNMENT OPERATORS
3567//
3568//=================================================================================================
3569
3570//*************************************************************************************************
3577template< typename Type // Data type of the vector
3578 , AlignmentFlag AF // Alignment flag
3579 , bool TF // Transpose flag
3580 , typename Tag // Type tag
3581 , typename RT > // Result type
3582inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3584{
3585 for( size_t i=0UL; i<size_; ++i )
3586 v_[i] = rhs;
3587 return *this;
3588}
3590//*************************************************************************************************
3591
3592
3593//*************************************************************************************************
3618template< typename Type // Data type of the vector
3619 , AlignmentFlag AF // Alignment flag
3620 , bool TF // Transpose flag
3621 , typename Tag // Type tag
3622 , typename RT > // Result type
3623inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3625{
3626 if( list.size() > size_ ) {
3627 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom vector" );
3628 }
3629
3630 std::fill( std::copy( list.begin(), list.end(), v_ ), v_+capacity_, Type() );
3631
3632 return *this;
3633}
3635//*************************************************************************************************
3636
3637
3638//*************************************************************************************************
3667template< typename Type // Data type of the vector
3668 , AlignmentFlag AF // Alignment flag
3669 , bool TF // Transpose flag
3670 , typename Tag // Type tag
3671 , typename RT > // Result type
3672template< typename Other // Data type of the static array
3673 , size_t Dim > // Dimension of the static array
3674inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3675 CustomVector<Type,AF,padded,TF,Tag,RT>::operator=( const Other (&array)[Dim] )
3676{
3677 if( size_ != Dim ) {
3678 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
3679 }
3680
3681 for( size_t i=0UL; i<Dim; ++i )
3682 v_[i] = array[i];
3683
3684 return *this;
3685}
3687//*************************************************************************************************
3688
3689
3690//*************************************************************************************************
3719template< typename Type // Data type of the vector
3720 , AlignmentFlag AF // Alignment flag
3721 , bool TF // Transpose flag
3722 , typename Tag // Type tag
3723 , typename RT > // Result type
3724template< typename Other // Data type of the std::array
3725 , size_t Dim > // Dimension of the std::array
3726inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3727 CustomVector<Type,AF,padded,TF,Tag,RT>::operator=( const std::array<Other,Dim>& array )
3728{
3729 if( size_ != Dim ) {
3730 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
3731 }
3732
3733 for( size_t i=0UL; i<Dim; ++i )
3734 v_[i] = array[i];
3735
3736 return *this;
3737}
3739//*************************************************************************************************
3740
3741
3742//*************************************************************************************************
3753template< typename Type // Data type of the vector
3754 , AlignmentFlag AF // Alignment flag
3755 , bool TF // Transpose flag
3756 , typename Tag // Type tag
3757 , typename RT > // Result type
3758inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3759 CustomVector<Type,AF,padded,TF,Tag,RT>::operator=( const CustomVector& rhs )
3760{
3761 if( rhs.size() != size_ ) {
3762 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3763 }
3764
3765 smpAssign( *this, *rhs );
3766
3767 return *this;
3768}
3770//*************************************************************************************************
3771
3772
3773//*************************************************************************************************
3780template< typename Type // Data type of the vector
3781 , AlignmentFlag AF // Alignment flag
3782 , bool TF // Transpose flag
3783 , typename Tag // Type tag
3784 , typename RT > // Result type
3785inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3786 CustomVector<Type,AF,padded,TF,Tag,RT>::operator=( CustomVector&& rhs ) noexcept
3787{
3788 size_ = rhs.size_;
3789 capacity_ = rhs.capacity_;
3790 v_ = rhs.v_;
3791
3792 rhs.size_ = 0UL;
3793 rhs.capacity_ = 0UL;
3794 rhs.v_ = nullptr;
3795
3796 BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
3797
3798 return *this;
3799}
3801//*************************************************************************************************
3802
3803
3804//*************************************************************************************************
3815template< typename Type // Data type of the vector
3816 , AlignmentFlag AF // Alignment flag
3817 , bool TF // Transpose flag
3818 , typename Tag // Type tag
3819 , typename RT > // Result type
3820template< typename VT > // Type of the right-hand side vector
3821inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3822 CustomVector<Type,AF,padded,TF,Tag,RT>::operator=( const Vector<VT,TF>& rhs )
3823{
3824 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<VT> );
3825
3826 if( (*rhs).size() != size_ ) {
3827 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3828 }
3829
3830 if( (*rhs).canAlias( this ) ) {
3831 const ResultType_t<VT> tmp( *rhs );
3832 smpAssign( *this, tmp );
3833 }
3834 else {
3835 if( IsSparseVector_v<VT> )
3836 reset();
3837 smpAssign( *this, *rhs );
3838 }
3839
3840 return *this;
3841}
3843//*************************************************************************************************
3844
3845
3846//*************************************************************************************************
3857template< typename Type // Data type of the vector
3858 , AlignmentFlag AF // Alignment flag
3859 , bool TF // Transpose flag
3860 , typename Tag // Type tag
3861 , typename RT > // Result type
3862template< typename VT > // Type of the right-hand side vector
3863inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3864 CustomVector<Type,AF,padded,TF,Tag,RT>::operator+=( const Vector<VT,TF>& rhs )
3865{
3866 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<VT> );
3867
3868 if( (*rhs).size() != size_ ) {
3869 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3870 }
3871
3872 if( (*rhs).canAlias( this ) ) {
3873 const ResultType_t<VT> tmp( *rhs );
3874 smpAddAssign( *this, tmp );
3875 }
3876 else {
3877 smpAddAssign( *this, *rhs );
3878 }
3879
3880 return *this;
3881}
3883//*************************************************************************************************
3884
3885
3886//*************************************************************************************************
3898template< typename Type // Data type of the vector
3899 , AlignmentFlag AF // Alignment flag
3900 , bool TF // Transpose flag
3901 , typename Tag // Type tag
3902 , typename RT > // Result type
3903template< typename VT > // Type of the right-hand side vector
3904inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3905 CustomVector<Type,AF,padded,TF,Tag,RT>::operator-=( const Vector<VT,TF>& rhs )
3906{
3907 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<VT> );
3908
3909 if( (*rhs).size() != size_ ) {
3910 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3911 }
3912
3913 if( (*rhs).canAlias( this ) ) {
3914 const ResultType_t<VT> tmp( *rhs );
3915 smpSubAssign( *this, tmp );
3916 }
3917 else {
3918 smpSubAssign( *this, *rhs );
3919 }
3920
3921 return *this;
3922}
3924//*************************************************************************************************
3925
3926
3927//*************************************************************************************************
3939template< typename Type // Data type of the vector
3940 , AlignmentFlag AF // Alignment flag
3941 , bool TF // Transpose flag
3942 , typename Tag // Type tag
3943 , typename RT > // Result type
3944template< typename VT > // Type of the right-hand side vector
3945inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3946 CustomVector<Type,AF,padded,TF,Tag,RT>::operator*=( const Vector<VT,TF>& rhs )
3947{
3948 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<VT> );
3949
3952
3953 using MultType = MultTrait_t< ResultType, ResultType_t<VT> >;
3954
3957
3958 if( (*rhs).size() != size_ ) {
3959 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3960 }
3961
3962 if( IsSparseVector_v<VT> || (*rhs).canAlias( this ) ) {
3963 const MultType tmp( *this * (*rhs) );
3964 if( IsSparseVector_v<MultType> )
3965 reset();
3966 smpAssign( *this, tmp );
3967 }
3968 else {
3969 smpMultAssign( *this, *rhs );
3970 }
3971
3972 return *this;
3973}
3975//*************************************************************************************************
3976
3977
3978//*************************************************************************************************
3989template< typename Type // Data type of the vector
3990 , AlignmentFlag AF // Alignment flag
3991 , bool TF // Transpose flag
3992 , typename Tag // Type tag
3993 , typename RT > // Result type
3994template< typename VT > // Type of the right-hand side vector
3995inline CustomVector<Type,AF,padded,TF,Tag,RT>&
3996 CustomVector<Type,AF,padded,TF,Tag,RT>::operator/=( const DenseVector<VT,TF>& rhs )
3997{
3998 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<VT> );
3999
4002
4003 using DivType = DivTrait_t< ResultType, ResultType_t<VT> >;
4004
4008
4009 if( (*rhs).size() != size_ ) {
4010 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4011 }
4012
4013 if( (*rhs).canAlias( this ) ) {
4014 const DivType tmp( *this / (*rhs) );
4015 smpAssign( *this, tmp );
4016 }
4017 else {
4018 smpDivAssign( *this, *rhs );
4019 }
4020
4021 return *this;
4022}
4024//*************************************************************************************************
4025
4026
4027//*************************************************************************************************
4039template< typename Type // Data type of the vector
4040 , AlignmentFlag AF // Alignment flag
4041 , bool TF // Transpose flag
4042 , typename Tag // Type tag
4043 , typename RT > // Result type
4044template< typename VT > // Type of the right-hand side vector
4045inline CustomVector<Type,AF,padded,TF,Tag,RT>&
4046 CustomVector<Type,AF,padded,TF,Tag,RT>::operator%=( const Vector<VT,TF>& rhs )
4047{
4048 using blaze::assign;
4049
4050 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<VT> );
4051
4054
4055 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
4056
4060
4061 if( size_ != 3UL || (*rhs).size() != 3UL ) {
4062 BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
4063 }
4064
4065 const CrossType tmp( *this % (*rhs) );
4066 assign( *this, tmp );
4067
4068 return *this;
4069}
4071//*************************************************************************************************
4072
4073
4074
4075
4076//=================================================================================================
4077//
4078// UTILITY FUNCTIONS
4079//
4080//=================================================================================================
4081
4082//*************************************************************************************************
4088template< typename Type // Data type of the vector
4089 , AlignmentFlag AF // Alignment flag
4090 , bool TF // Transpose flag
4091 , typename Tag // Type tag
4092 , typename RT > // Result type
4093inline size_t CustomVector<Type,AF,padded,TF,Tag,RT>::size() const noexcept
4094{
4095 return size_;
4096}
4098//*************************************************************************************************
4099
4100
4101//*************************************************************************************************
4110template< typename Type // Data type of the vector
4111 , AlignmentFlag AF // Alignment flag
4112 , bool TF // Transpose flag
4113 , typename Tag // Type tag
4114 , typename RT > // Result type
4115inline size_t CustomVector<Type,AF,padded,TF,Tag,RT>::spacing() const noexcept
4116{
4117 return capacity_;
4118}
4120//*************************************************************************************************
4121
4122
4123//*************************************************************************************************
4129template< typename Type // Data type of the vector
4130 , AlignmentFlag AF // Alignment flag
4131 , bool TF // Transpose flag
4132 , typename Tag // Type tag
4133 , typename RT > // Result type
4134inline size_t CustomVector<Type,AF,padded,TF,Tag,RT>::capacity() const noexcept
4135{
4136 return capacity_;
4137}
4139//*************************************************************************************************
4140
4141
4142//*************************************************************************************************
4152template< typename Type // Data type of the vector
4153 , AlignmentFlag AF // Alignment flag
4154 , bool TF // Transpose flag
4155 , typename Tag // Type tag
4156 , typename RT > // Result type
4158{
4159 size_t nonzeros( 0 );
4160
4161 for( size_t i=0UL; i<size_; ++i ) {
4162 if( !isDefault<strict>( v_[i] ) )
4163 ++nonzeros;
4164 }
4165
4166 return nonzeros;
4167}
4169//*************************************************************************************************
4170
4171
4172//*************************************************************************************************
4178template< typename Type // Data type of the vector
4179 , AlignmentFlag AF // Alignment flag
4180 , bool TF // Transpose flag
4181 , typename Tag // Type tag
4182 , typename RT > // Result type
4184{
4185 using blaze::clear;
4186 for( size_t i=0UL; i<size_; ++i )
4187 clear( v_[i] );
4188}
4190//*************************************************************************************************
4191
4192
4193//*************************************************************************************************
4202template< typename Type // Data type of the vector
4203 , AlignmentFlag AF // Alignment flag
4204 , bool TF // Transpose flag
4205 , typename Tag // Type tag
4206 , typename RT > // Result type
4208{
4209 size_ = 0UL;
4210 capacity_ = 0UL;
4211 v_ = nullptr;
4212}
4214//*************************************************************************************************
4215
4216
4217//*************************************************************************************************
4224template< typename Type // Data type of the vector
4225 , AlignmentFlag AF // Alignment flag
4226 , bool TF // Transpose flag
4227 , typename Tag // Type tag
4228 , typename RT > // Result type
4229inline void CustomVector<Type,AF,padded,TF,Tag,RT>::swap( CustomVector& v ) noexcept
4230{
4231 using std::swap;
4232
4233 swap( size_, v.size_ );
4234 swap( capacity_, v.capacity_ );
4235 swap( v_, v.v_ );
4236}
4238//*************************************************************************************************
4239
4240
4241
4242
4243//=================================================================================================
4244//
4245// NUMERIC FUNCTIONS
4246//
4247//=================================================================================================
4248
4249//*************************************************************************************************
4271template< typename Type // Data type of the vector
4272 , AlignmentFlag AF // Alignment flag
4273 , bool TF // Transpose flag
4274 , typename Tag // Type tag
4275 , typename RT > // Result type
4276template< typename Other > // Data type of the scalar value
4277inline CustomVector<Type,AF,padded,TF,Tag,RT>&
4278 CustomVector<Type,AF,padded,TF,Tag,RT>::scale( const Other& scalar )
4279{
4280 for( size_t i=0UL; i<size_; ++i )
4281 v_[i] *= scalar;
4282 return *this;
4283}
4285//*************************************************************************************************
4286
4287
4288
4289
4290//=================================================================================================
4291//
4292// RESOURCE MANAGEMENT FUNCTIONS
4293//
4294//=================================================================================================
4295
4296//*************************************************************************************************
4319template< typename Type // Data type of the vector
4320 , AlignmentFlag AF // Alignment flag
4321 , bool TF // Transpose flag
4322 , typename Tag // Type tag
4323 , typename RT > // Result type
4324inline void CustomVector<Type,AF,padded,TF,Tag,RT>::reset( Type* ptr, size_t n, size_t nn )
4325{
4326 CustomVector tmp( ptr, n, nn );
4327 swap( tmp );
4328}
4330//*************************************************************************************************
4331
4332
4333
4334
4335//=================================================================================================
4336//
4337// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4338//
4339//=================================================================================================
4340
4341//*************************************************************************************************
4352template< typename Type // Data type of the vector
4353 , AlignmentFlag AF // Alignment flag
4354 , bool TF // Transpose flag
4355 , typename Tag // Type tag
4356 , typename RT > // Result type
4357template< typename Other > // Data type of the foreign expression
4358inline bool CustomVector<Type,AF,padded,TF,Tag,RT>::canAlias( const Other* alias ) const noexcept
4359{
4360 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4361}
4363//*************************************************************************************************
4364
4365
4366//*************************************************************************************************
4377template< typename Type // Data type of the vector
4378 , AlignmentFlag AF // Alignment flag
4379 , bool TF // Transpose flag
4380 , typename Tag // Type tag
4381 , typename RT > // Result type
4382template< typename Other > // Data type of the foreign expression
4383inline bool CustomVector<Type,AF,padded,TF,Tag,RT>::isAliased( const Other* alias ) const noexcept
4384{
4385 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4386}
4388//*************************************************************************************************
4389
4390
4391//*************************************************************************************************
4401template< typename Type // Data type of the vector
4402 , AlignmentFlag AF // Alignment flag
4403 , bool TF // Transpose flag
4404 , typename Tag // Type tag
4405 , typename RT > // Result type
4406inline bool CustomVector<Type,AF,padded,TF,Tag,RT>::isAligned() const noexcept
4407{
4408 return ( AF || checkAlignment( v_ ) );
4409}
4411//*************************************************************************************************
4412
4413
4414//*************************************************************************************************
4425template< typename Type // Data type of the vector
4426 , AlignmentFlag AF // Alignment flag
4427 , bool TF // Transpose flag
4428 , typename Tag // Type tag
4429 , typename RT > // Result type
4431{
4432 return ( size() > SMP_DVECASSIGN_THRESHOLD );
4433}
4435//*************************************************************************************************
4436
4437
4438//*************************************************************************************************
4451template< typename Type // Data type of the vector
4452 , AlignmentFlag AF // Alignment flag
4453 , bool TF // Transpose flag
4454 , typename Tag // Type tag
4455 , typename RT > // Result type
4457 CustomVector<Type,AF,padded,TF,Tag,RT>::load( size_t index ) const noexcept
4458{
4459 if( AF )
4460 return loada( index );
4461 else
4462 return loadu( index );
4463}
4465//*************************************************************************************************
4466
4467
4468//*************************************************************************************************
4482template< typename Type // Data type of the vector
4483 , AlignmentFlag AF // Alignment flag
4484 , bool TF // Transpose flag
4485 , typename Tag // Type tag
4486 , typename RT > // Result type
4488 CustomVector<Type,AF,padded,TF,Tag,RT>::loada( size_t index ) const noexcept
4489{
4490 using blaze::loada;
4491
4493
4494 BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4495 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4496 BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
4497 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
4498
4499 return loada( v_+index );
4500}
4502//*************************************************************************************************
4503
4504
4505//*************************************************************************************************
4519template< typename Type // Data type of the vector
4520 , AlignmentFlag AF // Alignment flag
4521 , bool TF // Transpose flag
4522 , typename Tag // Type tag
4523 , typename RT > // Result type
4525 CustomVector<Type,AF,padded,TF,Tag,RT>::loadu( size_t index ) const noexcept
4526{
4527 using blaze::loadu;
4528
4530
4531 BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4532 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4533
4534 return loadu( v_+index );
4535}
4537//*************************************************************************************************
4538
4539
4540//*************************************************************************************************
4554template< typename Type // Data type of the vector
4555 , AlignmentFlag AF // Alignment flag
4556 , bool TF // Transpose flag
4557 , typename Tag // Type tag
4558 , typename RT > // Result type
4560 CustomVector<Type,AF,padded,TF,Tag,RT>::store( size_t index, const SIMDType& value ) noexcept
4561{
4562 if( AF )
4563 storea( index, value );
4564 else
4565 storeu( index, value );
4566}
4568//*************************************************************************************************
4569
4570
4571//*************************************************************************************************
4585template< typename Type // Data type of the vector
4586 , AlignmentFlag AF // Alignment flag
4587 , bool TF // Transpose flag
4588 , typename Tag // Type tag
4589 , typename RT > // Result type
4591 CustomVector<Type,AF,padded,TF,Tag,RT>::storea( size_t index, const SIMDType& value ) noexcept
4592{
4593 using blaze::storea;
4594
4596
4597 BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4598 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4599 BLAZE_INTERNAL_ASSERT( !AF || index % SIMDSIZE == 0UL, "Invalid vector access index" );
4600 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
4601
4602 storea( v_+index, value );
4603}
4605//*************************************************************************************************
4606
4607
4608//*************************************************************************************************
4622template< typename Type // Data type of the vector
4623 , AlignmentFlag AF // Alignment flag
4624 , bool TF // Transpose flag
4625 , typename Tag // Type tag
4626 , typename RT > // Result type
4628 CustomVector<Type,AF,padded,TF,Tag,RT>::storeu( size_t index, const SIMDType& value ) noexcept
4629{
4630 using blaze::storeu;
4631
4633
4634 BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4635 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4636
4637 storeu( v_+index, value );
4638}
4640//*************************************************************************************************
4641
4642
4643//*************************************************************************************************
4658template< typename Type // Data type of the vector
4659 , AlignmentFlag AF // Alignment flag
4660 , bool TF // Transpose flag
4661 , typename Tag // Type tag
4662 , typename RT > // Result type
4664 CustomVector<Type,AF,padded,TF,Tag,RT>::stream( size_t index, const SIMDType& value ) noexcept
4665{
4666 using blaze::stream;
4667
4669
4670 BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4671 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= capacity_, "Invalid vector access index" );
4672 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+index ), "Invalid vector access index" );
4673
4674 stream( v_+index, value );
4675}
4677//*************************************************************************************************
4678
4679
4680//*************************************************************************************************
4692template< typename Type // Data type of the vector
4693 , AlignmentFlag AF // Alignment flag
4694 , bool TF // Transpose flag
4695 , typename Tag // Type tag
4696 , typename RT > // Result type
4697template< typename VT > // Type of the right-hand side dense vector
4698inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::assign( const DenseVector<VT,TF>& rhs )
4699 -> DisableIf_t< VectorizedAssign_v<VT> >
4700{
4701 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
4702
4703 const size_t ipos( prevMultiple( size_, 2UL ) );
4704 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
4705
4706 for( size_t i=0UL; i<ipos; i+=2UL ) {
4707 v_[i ] = (*rhs)[i ];
4708 v_[i+1UL] = (*rhs)[i+1UL];
4709 }
4710 if( ipos < (*rhs).size() )
4711 v_[ipos] = (*rhs)[ipos];
4712}
4714//*************************************************************************************************
4715
4716
4717//*************************************************************************************************
4729template< typename Type // Data type of the vector
4730 , AlignmentFlag AF // Alignment flag
4731 , bool TF // Transpose flag
4732 , typename Tag // Type tag
4733 , typename RT > // Result type
4734template< typename VT > // Type of the right-hand side dense vector
4735inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::assign( const DenseVector<VT,TF>& rhs )
4736 -> EnableIf_t< VectorizedAssign_v<VT> >
4737{
4739
4740 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
4741
4742 constexpr bool remainder( !IsPadded_v<VT> );
4743
4744 const size_t ipos( remainder ? prevMultiple( size_, SIMDSIZE ) : size_ );
4745 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
4746
4747 if( AF && useStreaming && size_ > ( cacheSize/( sizeof(Type) * 3UL ) ) && !(*rhs).isAliased( this ) )
4748 {
4749 size_t i( 0UL );
4750
4751 for( ; i<ipos; i+=SIMDSIZE ) {
4752 stream( i, (*rhs).load(i) );
4753 }
4754 for( ; remainder && i<size_; ++i ) {
4755 v_[i] = (*rhs)[i];
4756 }
4757 }
4758 else
4759 {
4760 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
4761 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
4762
4763 size_t i( 0UL );
4764 ConstIterator_t<VT> it( (*rhs).begin() );
4765
4766 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4767 store( i , it.load() ); it += SIMDSIZE;
4768 store( i+SIMDSIZE , it.load() ); it += SIMDSIZE;
4769 store( i+SIMDSIZE*2UL, it.load() ); it += SIMDSIZE;
4770 store( i+SIMDSIZE*3UL, it.load() ); it += SIMDSIZE;
4771 }
4772 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4773 store( i, it.load() );
4774 }
4775 for( ; remainder && i<size_; ++i, ++it ) {
4776 v_[i] = *it;
4777 }
4778 }
4779}
4781//*************************************************************************************************
4782
4783
4784//*************************************************************************************************
4796template< typename Type // Data type of the vector
4797 , AlignmentFlag AF // Alignment flag
4798 , bool TF // Transpose flag
4799 , typename Tag // Type tag
4800 , typename RT > // Result type
4801template< typename VT > // Type of the right-hand side sparse vector
4802inline void CustomVector<Type,AF,padded,TF,Tag,RT>::assign( const SparseVector<VT,TF>& rhs )
4803{
4804 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
4805
4806 for( auto element=(*rhs).begin(); element!=(*rhs).end(); ++element )
4807 v_[element->index()] = element->value();
4808}
4810//*************************************************************************************************
4811
4812
4813//*************************************************************************************************
4825template< typename Type // Data type of the vector
4826 , AlignmentFlag AF // Alignment flag
4827 , bool TF // Transpose flag
4828 , typename Tag // Type tag
4829 , typename RT > // Result type
4830template< typename VT > // Type of the right-hand side dense vector
4831inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::addAssign( const DenseVector<VT,TF>& rhs )
4832 -> DisableIf_t< VectorizedAddAssign_v<VT> >
4833{
4834 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
4835
4836 const size_t ipos( prevMultiple( size_, 2UL ) );
4837 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
4838
4839 for( size_t i=0UL; i<ipos; i+=2UL ) {
4840 v_[i ] += (*rhs)[i ];
4841 v_[i+1UL] += (*rhs)[i+1UL];
4842 }
4843 if( ipos < (*rhs).size() )
4844 v_[ipos] += (*rhs)[ipos];
4845}
4847//*************************************************************************************************
4848
4849
4850//*************************************************************************************************
4862template< typename Type // Data type of the vector
4863 , AlignmentFlag AF // Alignment flag
4864 , bool TF // Transpose flag
4865 , typename Tag // Type tag
4866 , typename RT > // Result type
4867template< typename VT > // Type of the right-hand side dense vector
4868inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::addAssign( const DenseVector<VT,TF>& rhs )
4869 -> EnableIf_t< VectorizedAddAssign_v<VT> >
4870{
4872
4873 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
4874
4875 constexpr bool remainder( !IsPadded_v<VT> );
4876
4877 const size_t ipos( remainder ? prevMultiple( size_, SIMDSIZE ) : size_ );
4878 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
4879
4880 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
4881 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
4882
4883 size_t i( 0UL );
4884 ConstIterator_t<VT> it( (*rhs).begin() );
4885
4886 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
4887 store( i , load(i ) + it.load() ); it += SIMDSIZE;
4888 store( i+SIMDSIZE , load(i+SIMDSIZE ) + it.load() ); it += SIMDSIZE;
4889 store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) + it.load() ); it += SIMDSIZE;
4890 store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) + it.load() ); it += SIMDSIZE;
4891 }
4892 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
4893 store( i, load(i) + it.load() );
4894 }
4895 for( ; remainder && i<size_; ++i, ++it ) {
4896 v_[i] += *it;
4897 }
4898}
4900//*************************************************************************************************
4901
4902
4903//*************************************************************************************************
4915template< typename Type // Data type of the vector
4916 , AlignmentFlag AF // Alignment flag
4917 , bool TF // Transpose flag
4918 , typename Tag // Type tag
4919 , typename RT > // Result type
4920template< typename VT > // Type of the right-hand side sparse vector
4921inline void CustomVector<Type,AF,padded,TF,Tag,RT>::addAssign( const SparseVector<VT,TF>& rhs )
4922{
4923 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
4924
4925 for( auto element=(*rhs).begin(); element!=(*rhs).end(); ++element )
4926 v_[element->index()] += element->value();
4927}
4929//*************************************************************************************************
4930
4931
4932//*************************************************************************************************
4944template< typename Type // Data type of the vector
4945 , AlignmentFlag AF // Alignment flag
4946 , bool TF // Transpose flag
4947 , typename Tag // Type tag
4948 , typename RT > // Result type
4949template< typename VT > // Type of the right-hand side dense vector
4950inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::subAssign( const DenseVector<VT,TF>& rhs )
4951 -> DisableIf_t< VectorizedSubAssign_v<VT> >
4952{
4953 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
4954
4955 const size_t ipos( prevMultiple( size_, 2UL ) );
4956 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
4957
4958 for( size_t i=0UL; i<ipos; i+=2UL ) {
4959 v_[i ] -= (*rhs)[i ];
4960 v_[i+1UL] -= (*rhs)[i+1UL];
4961 }
4962 if( ipos < (*rhs).size() )
4963 v_[ipos] -= (*rhs)[ipos];
4964}
4966//*************************************************************************************************
4967
4968
4969//*************************************************************************************************
4981template< typename Type // Data type of the vector
4982 , AlignmentFlag AF // Alignment flag
4983 , bool TF // Transpose flag
4984 , typename Tag // Type tag
4985 , typename RT > // Result type
4986template< typename VT > // Type of the right-hand side dense vector
4987inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::subAssign( const DenseVector<VT,TF>& rhs )
4988 -> EnableIf_t< VectorizedSubAssign_v<VT> >
4989{
4991
4992 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
4993
4994 constexpr bool remainder( !IsPadded_v<VT> );
4995
4996 const size_t ipos( remainder ? prevMultiple( size_, SIMDSIZE ) : size_ );
4997 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
4998
4999 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
5000 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
5001
5002 size_t i( 0UL );
5003 ConstIterator_t<VT> it( (*rhs).begin() );
5004
5005 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
5006 store( i , load(i ) - it.load() ); it += SIMDSIZE;
5007 store( i+SIMDSIZE , load(i+SIMDSIZE ) - it.load() ); it += SIMDSIZE;
5008 store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) - it.load() ); it += SIMDSIZE;
5009 store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) - it.load() ); it += SIMDSIZE;
5010 }
5011 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
5012 store( i, load(i) - it.load() );
5013 }
5014 for( ; remainder && i<size_; ++i, ++it ) {
5015 v_[i] -= *it;
5016 }
5017}
5019//*************************************************************************************************
5020
5021
5022//*************************************************************************************************
5034template< typename Type // Data type of the vector
5035 , AlignmentFlag AF // Alignment flag
5036 , bool TF // Transpose flag
5037 , typename Tag // Type tag
5038 , typename RT > // Result type
5039template< typename VT > // Type of the right-hand side sparse vector
5040inline void CustomVector<Type,AF,padded,TF,Tag,RT>::subAssign( const SparseVector<VT,TF>& rhs )
5041{
5042 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
5043
5044 for( auto element=(*rhs).begin(); element!=(*rhs).end(); ++element )
5045 v_[element->index()] -= element->value();
5046}
5048//*************************************************************************************************
5049
5050
5051//*************************************************************************************************
5063template< typename Type // Data type of the vector
5064 , AlignmentFlag AF // Alignment flag
5065 , bool TF // Transpose flag
5066 , typename Tag // Type tag
5067 , typename RT > // Result type
5068template< typename VT > // Type of the right-hand side dense vector
5069inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::multAssign( const DenseVector<VT,TF>& rhs )
5070 -> DisableIf_t< VectorizedMultAssign_v<VT> >
5071{
5072 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
5073
5074 const size_t ipos( prevMultiple( size_, 2UL ) );
5075 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
5076
5077 for( size_t i=0UL; i<ipos; i+=2UL ) {
5078 v_[i ] *= (*rhs)[i ];
5079 v_[i+1UL] *= (*rhs)[i+1UL];
5080 }
5081 if( ipos < (*rhs).size() )
5082 v_[ipos] *= (*rhs)[ipos];
5083}
5085//*************************************************************************************************
5086
5087
5088//*************************************************************************************************
5100template< typename Type // Data type of the vector
5101 , AlignmentFlag AF // Alignment flag
5102 , bool TF // Transpose flag
5103 , typename Tag // Type tag
5104 , typename RT > // Result type
5105template< typename VT > // Type of the right-hand side dense vector
5106inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::multAssign( const DenseVector<VT,TF>& rhs )
5107 -> EnableIf_t< VectorizedMultAssign_v<VT> >
5108{
5110
5111 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
5112
5113 constexpr bool remainder( !IsPadded_v<VT> );
5114
5115 const size_t ipos( remainder ? prevMultiple( size_, SIMDSIZE ) : size_ );
5116 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
5117
5118 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
5119 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
5120
5121 size_t i( 0UL );
5122 ConstIterator_t<VT> it( (*rhs).begin() );
5123
5124 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
5125 store( i , load(i ) * it.load() ); it += SIMDSIZE;
5126 store( i+SIMDSIZE , load(i+SIMDSIZE ) * it.load() ); it += SIMDSIZE;
5127 store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) * it.load() ); it += SIMDSIZE;
5128 store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) * it.load() ); it += SIMDSIZE;
5129 }
5130 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
5131 store( i, load(i) * it.load() );
5132 }
5133 for( ; remainder && i<size_; ++i, ++it ) {
5134 v_[i] *= *it;
5135 }
5136}
5138//*************************************************************************************************
5139
5140
5141//*************************************************************************************************
5153template< typename Type // Data type of the vector
5154 , AlignmentFlag AF // Alignment flag
5155 , bool TF // Transpose flag
5156 , typename Tag // Type tag
5157 , typename RT > // Result type
5158template< typename VT > // Type of the right-hand side sparse vector
5159inline void CustomVector<Type,AF,padded,TF,Tag,RT>::multAssign( const SparseVector<VT,TF>& rhs )
5160{
5161 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
5162
5163 const ResultType tmp( serial( *this ) );
5164
5165 reset();
5166
5167 for( auto element=(*rhs).begin(); element!=(*rhs).end(); ++element )
5168 v_[element->index()] = tmp[element->index()] * element->value();
5169}
5171//*************************************************************************************************
5172
5173
5174//*************************************************************************************************
5186template< typename Type // Data type of the vector
5187 , AlignmentFlag AF // Alignment flag
5188 , bool TF // Transpose flag
5189 , typename Tag // Type tag
5190 , typename RT > // Result type
5191template< typename VT > // Type of the right-hand side dense vector
5192inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::divAssign( const DenseVector<VT,TF>& rhs )
5193 -> DisableIf_t< VectorizedDivAssign_v<VT> >
5194{
5195 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
5196
5197 const size_t ipos( prevMultiple( size_, 2UL ) );
5198 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
5199
5200 for( size_t i=0UL; i<ipos; i+=2UL ) {
5201 v_[i ] /= (*rhs)[i ];
5202 v_[i+1UL] /= (*rhs)[i+1UL];
5203 }
5204 if( ipos < (*rhs).size() )
5205 v_[ipos] /= (*rhs)[ipos];
5206}
5208//*************************************************************************************************
5209
5210
5211//*************************************************************************************************
5223template< typename Type // Data type of the vector
5224 , AlignmentFlag AF // Alignment flag
5225 , bool TF // Transpose flag
5226 , typename Tag // Type tag
5227 , typename RT > // Result type
5228template< typename VT > // Type of the right-hand side dense vector
5229inline auto CustomVector<Type,AF,padded,TF,Tag,RT>::divAssign( const DenseVector<VT,TF>& rhs )
5230 -> EnableIf_t< VectorizedDivAssign_v<VT> >
5231{
5233
5234 BLAZE_INTERNAL_ASSERT( size_ == (*rhs).size(), "Invalid vector sizes" );
5235
5236 const size_t ipos( prevMultiple( size_, SIMDSIZE ) );
5237 BLAZE_INTERNAL_ASSERT( ipos <= size_, "Invalid end calculation" );
5238
5239 const size_t i4way( prevMultiple( size_, SIMDSIZE*4UL ) );
5240 BLAZE_INTERNAL_ASSERT( i4way <= size_, "Invalid end calculation" );
5241
5242 size_t i( 0UL );
5243 ConstIterator_t<VT> it( (*rhs).begin() );
5244
5245 for( ; i<i4way; i+=SIMDSIZE*4UL ) {
5246 store( i , load(i ) / it.load() ); it += SIMDSIZE;
5247 store( i+SIMDSIZE , load(i+SIMDSIZE ) / it.load() ); it += SIMDSIZE;
5248 store( i+SIMDSIZE*2UL, load(i+SIMDSIZE*2UL) / it.load() ); it += SIMDSIZE;
5249 store( i+SIMDSIZE*3UL, load(i+SIMDSIZE*3UL) / it.load() ); it += SIMDSIZE;
5250 }
5251 for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
5252 store( i, load(i) / it.load() );
5253 }
5254 for( ; i<size_; ++i, ++it ) {
5255 v_[i] /= *it;
5256 }
5257}
5259//*************************************************************************************************
5260
5261
5262
5263
5264
5265
5266
5267
5268//=================================================================================================
5269//
5270// CUSTOMVECTOR OPERATORS
5271//
5272//=================================================================================================
5273
5274//*************************************************************************************************
5277template< RelaxationFlag RF, typename Type, AlignmentFlag AF, PaddingFlag PF, bool TF, typename Tag, typename RT >
5278bool isDefault( const CustomVector<Type,AF,PF,TF,Tag,RT>& v );
5279
5280template< typename Type, AlignmentFlag AF, PaddingFlag PF, bool TF, typename Tag, typename RT >
5281bool isIntact( const CustomVector<Type,AF,PF,TF,Tag,RT>& v ) noexcept;
5282
5283template< typename Type, AlignmentFlag AF, PaddingFlag PF, bool TF, typename Tag, typename RT >
5284void swap( CustomVector<Type,AF,PF,TF,Tag,RT>& a, CustomVector<Type,AF,PF,TF,Tag,RT>& b ) noexcept;
5286//*************************************************************************************************
5287
5288
5289//*************************************************************************************************
5317template< RelaxationFlag RF // Relaxation flag
5318 , typename Type // Data type of the vector
5319 , AlignmentFlag AF // Alignment flag
5320 , PaddingFlag PF // Padding flag
5321 , bool TF // Transpose flag
5322 , typename Tag // Type tag
5323 , typename RT > // Result type
5325{
5326 return ( v.size() == 0UL );
5327}
5328//*************************************************************************************************
5329
5330
5331//*************************************************************************************************
5352template< typename Type // Data type of the vector
5353 , AlignmentFlag AF // Alignment flag
5354 , PaddingFlag PF // Padding flag
5355 , bool TF // Transpose flag
5356 , typename Tag // Type tag
5357 , typename RT > // Result type
5358inline bool isIntact( const CustomVector<Type,AF,PF,TF,Tag,RT>& v ) noexcept
5359{
5360 return ( v.size() <= v.capacity() );
5361}
5362//*************************************************************************************************
5363
5364
5365//*************************************************************************************************
5373template< typename Type // Data type of the vector
5374 , AlignmentFlag AF // Alignment flag
5375 , PaddingFlag PF // Padding flag
5376 , bool TF // Transpose flag
5377 , typename Tag // Type tag
5378 , typename RT > // Result type
5380{
5381 a.swap( b );
5382}
5383//*************************************************************************************************
5384
5385
5386
5387
5388//=================================================================================================
5389//
5390// HASCONSTDATAACCESS SPECIALIZATIONS
5391//
5392//=================================================================================================
5393
5394//*************************************************************************************************
5396template< typename T, AlignmentFlag AF, PaddingFlag PF, bool TF, typename Tag, typename RT >
5397struct HasConstDataAccess< CustomVector<T,AF,PF,TF,Tag,RT> >
5398 : public TrueType
5399{};
5401//*************************************************************************************************
5402
5403
5404
5405
5406//=================================================================================================
5407//
5408// HASMUTABLEDATAACCESS SPECIALIZATIONS
5409//
5410//=================================================================================================
5411
5412//*************************************************************************************************
5414template< typename T, AlignmentFlag AF, PaddingFlag PF, bool TF, typename Tag, typename RT >
5415struct HasMutableDataAccess< CustomVector<T,AF,PF,TF,Tag,RT> >
5416 : public TrueType
5417{};
5419//*************************************************************************************************
5420
5421
5422
5423
5424//=================================================================================================
5425//
5426// ISCUSTOM SPECIALIZATIONS
5427//
5428//=================================================================================================
5429
5430//*************************************************************************************************
5432template< typename T, AlignmentFlag AF, PaddingFlag PF, bool TF, typename Tag, typename RT >
5433struct IsCustom< CustomVector<T,AF,PF,TF,Tag,RT> >
5434 : public TrueType
5435{};
5437//*************************************************************************************************
5438
5439
5440
5441
5442//=================================================================================================
5443//
5444// ISALIGNED SPECIALIZATIONS
5445//
5446//=================================================================================================
5447
5448//*************************************************************************************************
5450template< typename T, PaddingFlag PF, bool TF, typename Tag, typename RT >
5451struct IsAligned< CustomVector<T,aligned,PF,TF,Tag,RT> >
5452 : public TrueType
5453{};
5455//*************************************************************************************************
5456
5457
5458
5459
5460//=================================================================================================
5461//
5462// ISALIGNED SPECIALIZATIONS
5463//
5464//=================================================================================================
5465
5466//*************************************************************************************************
5468template< typename T, PaddingFlag PF, bool TF, typename Tag, typename RT >
5469struct IsContiguous< CustomVector<T,aligned,PF,TF,Tag,RT> >
5470 : public TrueType
5471{};
5473//*************************************************************************************************
5474
5475
5476
5477
5478//=================================================================================================
5479//
5480// ISPADDED SPECIALIZATIONS
5481//
5482//=================================================================================================
5483
5484//*************************************************************************************************
5486template< typename T, AlignmentFlag AF, bool TF, typename Tag, typename RT >
5487struct IsPadded< CustomVector<T,AF,padded,TF,Tag,RT> >
5488 : public TrueType
5489{};
5491//*************************************************************************************************
5492
5493} // namespace blaze
5494
5495#endif
Header file for auxiliary alias declarations.
typename ResultType_t< T >::TagType TagType_t
Alias declaration for nested TagType type definitions.
Definition: Aliases.h:530
typename T1::template Rebind< T2 >::Other Rebind_t
Alias declaration for nested Rebind class templates.
Definition: Aliases.h:350
typename T::template Resize< Ns... >::Other Resize_t
Alias declaration for nested Resize class templates.
Definition: Aliases.h:430
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.
Definition: Aliases.h:450
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.
Definition: Aliases.h:130
Header file for the alignment check function.
Header file for the alignment flag enumeration.
Header file for run time assertion macros.
Constraint on the data type.
Header file for the cross product trait.
Header file for the CustomTransposeType type trait.
Header file for the DenseIterator class template.
Header file for the division trait.
Header file for the EnableIf class template.
Header file for the HasConstDataAccess type trait.
Header file for the HasMutableDataAccess type trait.
Header file for the HasSIMDAdd type trait.
Header file for the HasSIMDDiv type trait.
Header file for the HasSIMDMult type trait.
Header file for the HasSIMDSub type trait.
Header file for the IntegralConstant class template.
Header file for the IsAligned type trait.
Header file for the IsContiguous type trait.
Header file for the IsCustom type trait.
Header file for the isDefault shim.
Header file for the IsPadded type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSMPAssignable type trait.
Header file for the IsSparseVector type trait.
Header file for the IsVectorizable type trait.
Header file for the MAYBE_UNUSED function template.
Header file for the multiplication trait.
Header file for the nextMultiple shim.
Header file for the padding flag enumeration.
Constraint on the data type.
Header file for the prevMultiple shim.
Constraint on the data type.
Header file for the relaxation flag enumeration.
Header file for the RemoveConst type trait.
Header file for all SIMD functionality.
Data type constraint.
Compile time assertion.
Constraint on the data type.
Constraint on the data type.
Efficient implementation of a customizable vector.
Definition: CustomVector.h:407
auto divAssign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedDivAssign_v< VT > >
Default implementation of the division assignment of a dense vector.
Definition: CustomVector.h:2752
size_t size() const noexcept
Returns the size/dimension of the vector.
Definition: CustomVector.h:1654
BLAZE_ALWAYS_INLINE void store(size_t index, const SIMDType &value) noexcept
Store of a SIMD element of the vector.
Definition: CustomVector.h:2143
CustomVector & operator=(const Type &rhs)
Homogenous assignment to all vector elements.
Definition: CustomVector.h:1158
CustomVector< Type, AF, PF, TF, Tag, RT > This
Type of this CustomVector instance.
Definition: CustomVector.h:410
SIMDTrait_t< ElementType > SIMDType
SIMD type of the vector elements.
Definition: CustomVector.h:420
bool canSMPAssign() const noexcept
Returns whether the vector can be used in SMP assignments.
Definition: CustomVector.h:2017
const Type & ReturnType
Return type for expression template evaluations.
Definition: CustomVector.h:422
Type ElementType
Type of the vector elements.
Definition: CustomVector.h:419
ConstIterator cbegin() const noexcept
Returns an iterator to the first element of the custom vector.
Definition: CustomVector.h:1073
bool isAligned() const noexcept
Returns whether the vector is properly aligned in memory.
Definition: CustomVector.h:1994
bool isAliased(const Other *alias) const noexcept
Returns whether the vector is aliased with the given address alias.
Definition: CustomVector.h:1972
Iterator begin() noexcept
Returns an iterator to the first element of the custom vector.
Definition: CustomVector.h:1035
Reference at(size_t index)
Checked access to the vector elements.
Definition: CustomVector.h:944
CustomVector()
The default constructor for CustomVector.
Definition: CustomVector.h:715
CustomTransposeType_t< RT > TransposeType
Transpose type for expression template evaluations.
Definition: CustomVector.h:417
BLAZE_ALWAYS_INLINE void storeu(size_t index, const SIMDType &value) noexcept
Unaligned store of a SIMD element of the vector.
Definition: CustomVector.h:2209
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD element.
Definition: CustomVector.h:611
auto subAssign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedSubAssign_v< VT > >
Default implementation of the subtraction assignment of a dense vector.
Definition: CustomVector.h:2520
const Type & ConstReference
Reference to a constant vector value.
Definition: CustomVector.h:426
Type & Reference
Reference to a non-constant vector value.
Definition: CustomVector.h:425
BLAZE_ALWAYS_INLINE SIMDType load(size_t index) const noexcept
Load of a SIMD element of the vector.
Definition: CustomVector.h:2043
Tag TagType
Tag type of this CustomVector instance.
Definition: CustomVector.h:421
size_t capacity() const noexcept
Returns the maximum capacity of the vector.
Definition: CustomVector.h:1693
const Type * ConstPointer
Pointer to a constant vector value.
Definition: CustomVector.h:428
void reset()
Reset to the default initial values.
Definition: CustomVector.h:1740
size_t size_
The size/dimension of the custom vector.
Definition: CustomVector.h:677
BLAZE_ALWAYS_INLINE SIMDType loada(size_t index) const noexcept
Aligned load of a SIMD element of the vector.
Definition: CustomVector.h:2073
Type * v_
The custom array of elements.
Definition: CustomVector.h:678
bool canAlias(const Other *alias) const noexcept
Returns whether the vector can alias with the given address alias.
Definition: CustomVector.h:1948
RT ResultType
Result type for expression template evaluations.
Definition: CustomVector.h:414
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:2244
static constexpr bool simdEnabled
Compilation flag for SIMD optimization.
Definition: CustomVector.h:460
Iterator end() noexcept
Returns an iterator just past the last element of the custom vector.
Definition: CustomVector.h:1092
DenseVector< This, TF > BaseType
Base type of this CustomVector instance.
Definition: CustomVector.h:411
Reference operator[](size_t index) noexcept
Subscript operator for the direct access to the vector elements.
Definition: CustomVector.h:895
BLAZE_ALWAYS_INLINE void storea(size_t index, const SIMDType &value) noexcept
Aligned store of a SIMD element of the vector.
Definition: CustomVector.h:2173
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t index) const noexcept
Unaligned load of a SIMD element of the vector.
Definition: CustomVector.h:2109
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CustomVector.h:466
void clear()
Clearing the vector to its default state.
Definition: CustomVector.h:1763
auto addAssign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedAddAssign_v< VT > >
Default implementation of the addition assignment of a dense vector.
Definition: CustomVector.h:2406
Type * Pointer
Pointer to a non-constant vector value.
Definition: CustomVector.h:427
void swap(CustomVector &v) noexcept
Swapping the contents of two vectors.
Definition: CustomVector.h:1783
auto assign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedAssign_v< VT > >
Default implementation of the assignment of a dense vector.
Definition: CustomVector.h:2278
size_t nonZeros() const
Returns the number of non-zero elements in the vector.
Definition: CustomVector.h:1715
Pointer data() noexcept
Low-level data access to the vector elements.
Definition: CustomVector.h:995
size_t spacing() const noexcept
Returns the minimum capacity of the vector.
Definition: CustomVector.h:1675
const CustomVector & CompositeType
Data type for composite expression templates.
Definition: CustomVector.h:423
~CustomVector()
The destructor for CustomVector.
Definition: CustomVector.h:860
ConstIterator cend() const noexcept
Returns an iterator just past the last element of the custom vector.
Definition: CustomVector.h:1130
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: CustomVector.h:431
DenseIterator< Type, AF > Iterator
Iterator over non-constant elements.
Definition: CustomVector.h:430
auto multAssign(const DenseVector< VT, TF > &rhs) -> DisableIf_t< VectorizedMultAssign_v< VT > >
Default implementation of the multiplication assignment of a dense vector.
Definition: CustomVector.h:2634
Implementation of a generic iterator for dense vectors and matrices.
Definition: DenseIterator.h:60
Base class for N-dimensional dense vectors.
Definition: DenseVector.h:77
SIMD characteristics of data types.
Definition: SIMDTrait.h:297
Base class for sparse vectors.
Definition: SparseVector.h:72
Base class for N-dimensional vectors.
Definition: Vector.h:82
Initializer list type of the Blaze library.
Constraint on the data type.
Constraint on the data type.
Header file for the DenseVector base class.
Header file for the SparseVector base class.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.
Definition: Volatile.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.
Definition: Vectorizable.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.
Definition: Const.h:79
#define BLAZE_CONSTRAINT_MUST_BE_SAME_TAG(A, B)
Data type constraint.
Definition: SameTag.h:68
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
bool isIntact(const CustomVector< Type, AF, PF, TF, Tag, RT > &v) noexcept
Returns whether the invariants of the given custom vector are intact.
Definition: CustomVector.h:5358
bool isDefault(const CustomVector< Type, AF, PF, TF, Tag, RT > &v)
Returns whether the given custom vector is in default state.
Definition: CustomVector.h:5324
void swap(CustomVector< Type, AF, PF, TF, Tag, RT > &a, CustomVector< Type, AF, PF, TF, Tag, RT > &b) noexcept
Swapping the contents of two vectors.
Definition: CustomVector.h:5379
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.
Definition: TransposeFlag.h:63
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.
Definition: DenseVector.h:61
typename DivTrait< T1, T2 >::Type DivTrait_t
Auxiliary alias declaration for the DivTrait class template.
Definition: DivTrait.h:164
typename CrossTrait< T1, T2 >::Type CrossTrait_t
Auxiliary alias declaration for the CrossTrait class template.
Definition: CrossTrait.h:138
typename MultTrait< T1, T2 >::Type MultTrait_t
Auxiliary alias declaration for the MultTrait class template.
Definition: MultTrait.h:165
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.
Definition: HasSIMDSub.h:187
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.
Definition: IsSIMDCombinable.h:137
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.
Definition: HasSIMDAdd.h:187
constexpr bool HasSIMDDiv_v
Auxiliary variable template for the HasSIMDDiv type trait.
Definition: HasSIMDDiv.h:173
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.
Definition: HasSIMDMult.h:188
typename CustomTransposeType< T >::Type CustomTransposeType_t
Auxiliary alias declaration for the CustomTransposeType type trait.
Definition: CustomTransposeType.h:83
RelaxationFlag
Relaxation flag for strict or relaxed semantics.
Definition: RelaxationFlag.h:66
BLAZE_ALWAYS_INLINE constexpr auto prevMultiple(T1 value, T2 factor) noexcept
Rounds down an integral value to the previous multiple of a given factor.
Definition: PrevMultiple.h:68
PaddingFlag
Padding flag for (un-)padded vectors and matrices.
Definition: PaddingFlag.h:77
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.
Definition: AlignmentFlag.h:63
@ padded
Flag for padded vectors and matrices.
Definition: PaddingFlag.h:79
@ aligned
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
constexpr void clear(Matrix< MT, SO > &matrix)
Clearing the given matrix.
Definition: Matrix.h:960
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
typename SIMDTrait< T >::Type SIMDTrait_t
Auxiliary alias declaration for the SIMDTrait class template.
Definition: SIMDTrait.h:315
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
auto smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:221
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector.
Definition: DenseVector.h:192
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.
Definition: StaticAssert.h:112
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
BoolConstant< true > TrueType
Type traits base class.
Definition: IntegralConstant.h:132
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
Header file for the exception macros of the math module.
Header file for all forward declarations of the math module.
Header file for the extended initializer_list functionality.
Constraint on the data type.
Header file for all forward declarations for dense vectors and matrices.
Header file for the clear shim.
Header file for the serial shim.
Rebind mechanism to obtain a CustomVector with different data/element type.
Definition: CustomVector.h:438
Rebind_t< RT, RemoveConst_t< NewType > > RRT
The rebound result type.
Definition: CustomVector.h:439
CustomVector< NewType, AF, PF, TF, Tag, RRT > Other
The type of the other CustomVector.
Definition: CustomVector.h:440
Resize mechanism to obtain a CustomVector with a different fixed number of elements.
Definition: CustomVector.h:448
CustomVector< Type, AF, PF, TF, Tag, RRT > Other
The type of the other CustomVector.
Definition: CustomVector.h:450
Resize_t< RT, NewN > RRT
The resized result type.
Definition: CustomVector.h:449
Header file for the cache size of the target architecture.
System settings for the inline keywords.
System settings for performance optimizations.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for basic type definitions.