Dense.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SUBVECTOR_DENSE_H_
36 #define _BLAZE_MATH_VIEWS_SUBVECTOR_DENSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <blaze/math/Aliases.h>
53 #include <blaze/math/Exception.h>
60 #include <blaze/math/shims/Clear.h>
62 #include <blaze/math/SIMD.h>
74 #include <blaze/math/views/Check.h>
77 #include <blaze/system/CacheSize.h>
78 #include <blaze/system/Inline.h>
82 #include <blaze/util/Assert.h>
84 #include <blaze/util/DisableIf.h>
85 #include <blaze/util/EnableIf.h>
86 #include <blaze/util/mpl/If.h>
87 #include <blaze/util/mpl/Not.h>
88 #include <blaze/util/mpl/Or.h>
89 #include <blaze/util/Template.h>
90 #include <blaze/util/TypeList.h>
91 #include <blaze/util/Types.h>
93 
94 
95 namespace blaze {
96 
97 //=================================================================================================
98 //
99 // CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED DENSE SUBVECTORS
100 //
101 //=================================================================================================
102 
103 //*************************************************************************************************
111 template< typename VT // Type of the dense vector
112  , bool TF // Transpose flag
113  , size_t... CSAs > // Compile time subvector arguments
114 class Subvector<VT,unaligned,TF,true,CSAs...>
115  : public View< DenseVector< Subvector<VT,unaligned,TF,true,CSAs...>, TF > >
116  , private SubvectorData<CSAs...>
117 {
118  private:
119  //**Type definitions****************************************************************************
120  using DataType = SubvectorData<CSAs...>;
121  using Operand = If_< IsExpression<VT>, VT, VT& >;
122  //**********************************************************************************************
123 
124  public:
125  //**Type definitions****************************************************************************
127  using This = Subvector<VT,unaligned,TF,true,CSAs...>;
128 
129  using BaseType = DenseVector<This,TF>;
130  using ViewedType = VT;
131  using ResultType = SubvectorTrait_<VT,CSAs...>;
132  using TransposeType = TransposeType_<ResultType>;
133  using ElementType = ElementType_<VT>;
134  using SIMDType = SIMDTrait_<ElementType>;
135  using ReturnType = ReturnType_<VT>;
136  using CompositeType = const Subvector&;
137 
139  using ConstReference = ConstReference_<VT>;
140 
142  using Reference = If_< IsConst<VT>, ConstReference, Reference_<VT> >;
143 
145  using ConstPointer = ConstPointer_<VT>;
146 
148  using Pointer = If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, Pointer_<VT> >;
149  //**********************************************************************************************
150 
151  //**SubvectorIterator class definition**********************************************************
154  template< typename IteratorType > // Type of the dense vector iterator
155  class SubvectorIterator
156  {
157  public:
158  //**Type definitions*************************************************************************
160  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
161 
163  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
164 
166  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
167 
169  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
170 
172  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
173 
174  // STL iterator requirements
175  using iterator_category = IteratorCategory;
176  using value_type = ValueType;
177  using pointer = PointerType;
178  using reference = ReferenceType;
179  using difference_type = DifferenceType;
180  //*******************************************************************************************
181 
182  //**Constructor******************************************************************************
185  inline SubvectorIterator()
186  : iterator_ ( ) // Iterator to the current subvector element
187  , isAligned_( false ) // Memory alignment flag
188  {}
189  //*******************************************************************************************
190 
191  //**Constructor******************************************************************************
197  inline SubvectorIterator( IteratorType iterator, bool isMemoryAligned )
198  : iterator_ ( iterator ) // Iterator to the current subvector element
199  , isAligned_( isMemoryAligned ) // Memory alignment flag
200  {}
201  //*******************************************************************************************
202 
203  //**Constructor******************************************************************************
208  template< typename IteratorType2 >
209  inline SubvectorIterator( const SubvectorIterator<IteratorType2>& it )
210  : iterator_ ( it.base() ) // Iterator to the current subvector element
211  , isAligned_( it.isAligned() ) // Memory alignment flag
212  {}
213  //*******************************************************************************************
214 
215  //**Addition assignment operator*************************************************************
221  inline SubvectorIterator& operator+=( size_t inc ) {
222  iterator_ += inc;
223  return *this;
224  }
225  //*******************************************************************************************
226 
227  //**Subtraction assignment operator**********************************************************
233  inline SubvectorIterator& operator-=( size_t dec ) {
234  iterator_ -= dec;
235  return *this;
236  }
237  //*******************************************************************************************
238 
239  //**Prefix increment operator****************************************************************
244  inline SubvectorIterator& operator++() {
245  ++iterator_;
246  return *this;
247  }
248  //*******************************************************************************************
249 
250  //**Postfix increment operator***************************************************************
255  inline const SubvectorIterator operator++( int ) {
256  return SubvectorIterator( iterator_++, isAligned_ );
257  }
258  //*******************************************************************************************
259 
260  //**Prefix decrement operator****************************************************************
265  inline SubvectorIterator& operator--() {
266  --iterator_;
267  return *this;
268  }
269  //*******************************************************************************************
270 
271  //**Postfix decrement operator***************************************************************
276  inline const SubvectorIterator operator--( int ) {
277  return SubvectorIterator( iterator_--, isAligned_ );
278  }
279  //*******************************************************************************************
280 
281  //**Element access operator******************************************************************
286  inline ReferenceType operator*() const {
287  return *iterator_;
288  }
289  //*******************************************************************************************
290 
291  //**Element access operator******************************************************************
296  inline IteratorType operator->() const {
297  return iterator_;
298  }
299  //*******************************************************************************************
300 
301  //**Load function****************************************************************************
311  inline SIMDType load() const {
312  return loadu();
313  }
314  //*******************************************************************************************
315 
316  //**Loada function***************************************************************************
326  inline SIMDType loada() const {
327  return iterator_.loada();
328  }
329  //*******************************************************************************************
330 
331  //**Loadu function***************************************************************************
341  inline SIMDType loadu() const {
342  if( isAligned_ ) {
343  return iterator_.loada();
344  }
345  else {
346  return iterator_.loadu();
347  }
348  }
349  //*******************************************************************************************
350 
351  //**Store function***************************************************************************
362  inline void store( const SIMDType& value ) const {
363  storeu( value );
364  }
365  //*******************************************************************************************
366 
367  //**Storea function**************************************************************************
378  inline void storea( const SIMDType& value ) const {
379  iterator_.storea( value );
380  }
381  //*******************************************************************************************
382 
383  //**Storeu function**************************************************************************
394  inline void storeu( const SIMDType& value ) const {
395  if( isAligned_ ) {
396  iterator_.storea( value );
397  }
398  else {
399  iterator_.storeu( value );
400  }
401  }
402  //*******************************************************************************************
403 
404  //**Stream function**************************************************************************
415  inline void stream( const SIMDType& value ) const {
416  iterator_.stream( value );
417  }
418  //*******************************************************************************************
419 
420  //**Equality operator************************************************************************
426  inline bool operator==( const SubvectorIterator& rhs ) const {
427  return iterator_ == rhs.iterator_;
428  }
429  //*******************************************************************************************
430 
431  //**Inequality operator**********************************************************************
437  inline bool operator!=( const SubvectorIterator& rhs ) const {
438  return iterator_ != rhs.iterator_;
439  }
440  //*******************************************************************************************
441 
442  //**Less-than operator***********************************************************************
448  inline bool operator<( const SubvectorIterator& rhs ) const {
449  return iterator_ < rhs.iterator_;
450  }
451  //*******************************************************************************************
452 
453  //**Greater-than operator********************************************************************
459  inline bool operator>( const SubvectorIterator& rhs ) const {
460  return iterator_ > rhs.iterator_;
461  }
462  //*******************************************************************************************
463 
464  //**Less-or-equal-than operator**************************************************************
470  inline bool operator<=( const SubvectorIterator& rhs ) const {
471  return iterator_ <= rhs.iterator_;
472  }
473  //*******************************************************************************************
474 
475  //**Greater-or-equal-than operator***********************************************************
481  inline bool operator>=( const SubvectorIterator& rhs ) const {
482  return iterator_ >= rhs.iterator_;
483  }
484  //*******************************************************************************************
485 
486  //**Subtraction operator*********************************************************************
492  inline DifferenceType operator-( const SubvectorIterator& rhs ) const {
493  return iterator_ - rhs.iterator_;
494  }
495  //*******************************************************************************************
496 
497  //**Addition operator************************************************************************
504  friend inline const SubvectorIterator operator+( const SubvectorIterator& it, size_t inc ) {
505  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
506  }
507  //*******************************************************************************************
508 
509  //**Addition operator************************************************************************
516  friend inline const SubvectorIterator operator+( size_t inc, const SubvectorIterator& it ) {
517  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
518  }
519  //*******************************************************************************************
520 
521  //**Subtraction operator*********************************************************************
528  friend inline const SubvectorIterator operator-( const SubvectorIterator& it, size_t dec ) {
529  return SubvectorIterator( it.iterator_ - dec, it.isAligned_ );
530  }
531  //*******************************************************************************************
532 
533  //**Base function****************************************************************************
538  inline IteratorType base() const {
539  return iterator_;
540  }
541  //*******************************************************************************************
542 
543  //**IsAligned function***********************************************************************
548  inline bool isAligned() const {
549  return isAligned_;
550  }
551  //*******************************************************************************************
552 
553  private:
554  //**Member variables*************************************************************************
555  IteratorType iterator_;
556  bool isAligned_;
557  //*******************************************************************************************
558  };
559  //**********************************************************************************************
560 
561  //**Type definitions****************************************************************************
563  using ConstIterator = SubvectorIterator< ConstIterator_<VT> >;
564 
566  using Iterator = If_< IsConst<VT>, ConstIterator, SubvectorIterator< Iterator_<VT> > >;
567  //**********************************************************************************************
568 
569  //**Compilation flags***************************************************************************
571  enum : bool { simdEnabled = VT::simdEnabled };
572 
574  enum : bool { smpAssignable = VT::smpAssignable };
575  //**********************************************************************************************
576 
577  //**Constructors********************************************************************************
580  template< typename... RSAs >
581  explicit inline Subvector( VT& vector, RSAs... args );
582  // No explicitly declared copy constructor.
584  //**********************************************************************************************
585 
586  //**Destructor**********************************************************************************
587  // No explicitly declared destructor.
588  //**********************************************************************************************
589 
590  //**Data access functions***********************************************************************
593  inline Reference operator[]( size_t index );
594  inline ConstReference operator[]( size_t index ) const;
595  inline Reference at( size_t index );
596  inline ConstReference at( size_t index ) const;
597  inline Pointer data () noexcept;
598  inline ConstPointer data () const noexcept;
599  inline Iterator begin ();
600  inline ConstIterator begin () const;
601  inline ConstIterator cbegin() const;
602  inline Iterator end ();
603  inline ConstIterator end () const;
604  inline ConstIterator cend () const;
606  //**********************************************************************************************
607 
608  //**Assignment operators************************************************************************
611  inline Subvector& operator= ( const ElementType& rhs );
612  inline Subvector& operator= ( initializer_list<ElementType> list );
613  inline Subvector& operator= ( const Subvector& rhs );
614  template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
615  template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
616  template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
617  template< typename VT2 > inline Subvector& operator*=( const Vector<VT2,TF>& rhs );
618  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
619  template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
621  //**********************************************************************************************
622 
623  //**Utility functions***************************************************************************
626  using DataType::offset;
627  using DataType::size;
628 
629  inline VT& operand() noexcept;
630  inline const VT& operand() const noexcept;
631 
632  inline size_t spacing() const noexcept;
633  inline size_t capacity() const noexcept;
634  inline size_t nonZeros() const;
635  inline void reset();
637  //**********************************************************************************************
638 
639  //**Numeric functions***************************************************************************
642  template< typename Other > inline Subvector& scale( const Other& scalar );
644  //**********************************************************************************************
645 
646  private:
647  //**********************************************************************************************
649  template< typename VT2 >
650  struct VectorizedAssign {
651  enum : bool { value = useOptimizedKernels &&
652  simdEnabled && VT2::simdEnabled &&
653  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
654  };
655  //**********************************************************************************************
656 
657  //**********************************************************************************************
659  template< typename VT2 >
660  struct VectorizedAddAssign {
661  enum : bool { value = useOptimizedKernels &&
662  simdEnabled && VT2::simdEnabled &&
663  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
664  HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
665  };
666  //**********************************************************************************************
667 
668  //**********************************************************************************************
670  template< typename VT2 >
671  struct VectorizedSubAssign {
672  enum : bool { value = useOptimizedKernels &&
673  simdEnabled && VT2::simdEnabled &&
674  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
675  HasSIMDSub< ElementType, ElementType_<VT2> >::value };
676  };
677  //**********************************************************************************************
678 
679  //**********************************************************************************************
681  template< typename VT2 >
682  struct VectorizedMultAssign {
683  enum : bool { value = useOptimizedKernels &&
684  simdEnabled && VT2::simdEnabled &&
685  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
686  HasSIMDMult< ElementType, ElementType_<VT2> >::value };
687  };
688  //**********************************************************************************************
689 
690  //**********************************************************************************************
692  template< typename VT2 >
693  struct VectorizedDivAssign {
694  enum : bool { value = useOptimizedKernels &&
695  simdEnabled && VT2::simdEnabled &&
696  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
697  HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
698  };
699  //**********************************************************************************************
700 
701  //**SIMD properties*****************************************************************************
703  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
704  //**********************************************************************************************
705 
706  public:
707  //**Expression template evaluation functions****************************************************
710  template< typename Other >
711  inline bool canAlias( const Other* alias ) const noexcept;
712 
713  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
714  inline bool canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
715 
716  template< typename Other >
717  inline bool isAliased( const Other* alias ) const noexcept;
718 
719  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
720  inline bool isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
721 
722  inline bool isAligned () const noexcept;
723  inline bool canSMPAssign() const noexcept;
724 
725  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
726  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
727  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
728 
729  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
730  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
731  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
732  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
733 
734  template< typename VT2 >
735  inline DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
736 
737  template< typename VT2 >
738  inline EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
739 
740  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
741 
742  template< typename VT2 >
743  inline DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
744 
745  template< typename VT2 >
746  inline EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
747 
748  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
749 
750  template< typename VT2 >
751  inline DisableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
752 
753  template< typename VT2 >
754  inline EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
755 
756  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
757 
758  template< typename VT2 >
759  inline DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
760 
761  template< typename VT2 >
762  inline EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
763 
764  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
765 
766  template< typename VT2 >
767  inline DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
768 
769  template< typename VT2 >
770  inline EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
772  //**********************************************************************************************
773 
774  private:
775  //**Member variables****************************************************************************
778  Operand vector_;
779  const bool isAligned_;
780 
787  //**********************************************************************************************
788 
789  //**Friend declarations*************************************************************************
790  template< typename VT2, AlignmentFlag AF2, bool TF2, bool DF2, size_t... CSAs2 > friend class Subvector;
791  //**********************************************************************************************
792 
793  //**Compile time checks*************************************************************************
799  //**********************************************************************************************
800 };
802 //*************************************************************************************************
803 
804 
805 
806 
807 //=================================================================================================
808 //
809 // CONSTRUCTORS
810 //
811 //=================================================================================================
812 
813 //*************************************************************************************************
827 template< typename VT // Type of the dense vector
828  , bool TF // Transpose flag
829  , size_t... CSAs > // Compile time subvector arguments
830 template< typename... RSAs > // Runtime subvector arguments
831 inline Subvector<VT,unaligned,TF,true,CSAs...>::Subvector( VT& vector, RSAs... args )
832  : DataType ( args... ) // Base class initialization
833  , vector_ ( vector ) // The vector containing the subvector
834  , isAligned_( simdEnabled && vector.data() != nullptr && checkAlignment( data() ) )
835 {
836  if( !Contains< TypeList<RSAs...>, Unchecked >::value ) {
837  if( offset() + size() > vector.size() ) {
838  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
839  }
840  }
841  else {
842  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
843  }
844 }
846 //*************************************************************************************************
847 
848 
849 
850 
851 //=================================================================================================
852 //
853 // DATA ACCESS FUNCTIONS
854 //
855 //=================================================================================================
856 
857 //*************************************************************************************************
867 template< typename VT // Type of the dense vector
868  , bool TF // Transpose flag
869  , size_t... CSAs > // Compile time subvector arguments
870 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Reference
871  Subvector<VT,unaligned,TF,true,CSAs...>::operator[]( size_t index )
872 {
873  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
874  return vector_[offset()+index];
875 }
877 //*************************************************************************************************
878 
879 
880 //*************************************************************************************************
890 template< typename VT // Type of the dense vector
891  , bool TF // Transpose flag
892  , size_t... CSAs > // Compile time subvector arguments
893 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstReference
894  Subvector<VT,unaligned,TF,true,CSAs...>::operator[]( size_t index ) const
895 {
896  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
897  return const_cast<const VT&>( vector_ )[offset()+index];
898 }
900 //*************************************************************************************************
901 
902 
903 //*************************************************************************************************
914 template< typename VT // Type of the dense vector
915  , bool TF // Transpose flag
916  , size_t... CSAs > // Compile time subvector arguments
917 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Reference
918  Subvector<VT,unaligned,TF,true,CSAs...>::at( size_t index )
919 {
920  if( index >= size() ) {
921  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
922  }
923  return (*this)[index];
924 }
926 //*************************************************************************************************
927 
928 
929 //*************************************************************************************************
940 template< typename VT // Type of the dense vector
941  , bool TF // Transpose flag
942  , size_t... CSAs > // Compile time subvector arguments
943 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstReference
944  Subvector<VT,unaligned,TF,true,CSAs...>::at( size_t index ) const
945 {
946  if( index >= size() ) {
947  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
948  }
949  return (*this)[index];
950 }
952 //*************************************************************************************************
953 
954 
955 //*************************************************************************************************
963 template< typename VT // Type of the dense vector
964  , bool TF // Transpose flag
965  , size_t... CSAs > // Compile time subvector arguments
966 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Pointer
968 {
969  return vector_.data() + offset();
970 }
972 //*************************************************************************************************
973 
974 
975 //*************************************************************************************************
983 template< typename VT // Type of the dense vector
984  , bool TF // Transpose flag
985  , size_t... CSAs > // Compile time subvector arguments
986 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstPointer
988 {
989  return vector_.data() + offset();
990 }
992 //*************************************************************************************************
993 
994 
995 //*************************************************************************************************
1003 template< typename VT // Type of the dense vector
1004  , bool TF // Transpose flag
1005  , size_t... CSAs > // Compile time subvector arguments
1006 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Iterator
1008 {
1009  return Iterator( vector_.begin() + offset(), isAligned_ );
1010 }
1012 //*************************************************************************************************
1013 
1014 
1015 //*************************************************************************************************
1023 template< typename VT // Type of the dense vector
1024  , bool TF // Transpose flag
1025  , size_t... CSAs > // Compile time subvector arguments
1026 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1028 {
1029  return ConstIterator( vector_.cbegin() + offset(), isAligned_ );
1030 }
1032 //*************************************************************************************************
1033 
1034 
1035 //*************************************************************************************************
1043 template< typename VT // Type of the dense vector
1044  , bool TF // Transpose flag
1045  , size_t... CSAs > // Compile time subvector arguments
1046 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1048 {
1049  return ConstIterator( vector_.cbegin() + offset(), isAligned_ );
1050 }
1052 //*************************************************************************************************
1053 
1054 
1055 //*************************************************************************************************
1063 template< typename VT // Type of the dense vector
1064  , bool TF // Transpose flag
1065  , size_t... CSAs > // Compile time subvector arguments
1066 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Iterator
1068 {
1069  return Iterator( vector_.begin() + offset() + size(), isAligned_ );
1070 }
1072 //*************************************************************************************************
1073 
1074 
1075 //*************************************************************************************************
1083 template< typename VT // Type of the dense vector
1084  , bool TF // Transpose flag
1085  , size_t... CSAs > // Compile time subvector arguments
1086 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1088 {
1089  return ConstIterator( vector_.cbegin() + offset() + size(), isAligned_ );
1090 }
1092 //*************************************************************************************************
1093 
1094 
1095 //*************************************************************************************************
1103 template< typename VT // Type of the dense vector
1104  , bool TF // Transpose flag
1105  , size_t... CSAs > // Compile time subvector arguments
1106 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1108 {
1109  return ConstIterator( vector_.cbegin() + offset() + size(), isAligned_ );
1110 }
1112 //*************************************************************************************************
1113 
1114 
1115 
1116 
1117 //=================================================================================================
1118 //
1119 // ASSIGNMENT OPERATORS
1120 //
1121 //=================================================================================================
1122 
1123 //*************************************************************************************************
1130 template< typename VT // Type of the dense vector
1131  , bool TF // Transpose flag
1132  , size_t... CSAs > // Compile time subvector arguments
1133 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1134  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const ElementType& rhs )
1135 {
1136  const size_t iend( offset() + size() );
1137  decltype(auto) left( derestrict( vector_ ) );
1138 
1139  for( size_t i=offset(); i<iend; ++i ) {
1140  if( !IsRestricted<VT>::value || trySet( vector_, i, rhs ) )
1141  left[i] = rhs;
1142  }
1143 
1144  return *this;
1145 }
1147 //*************************************************************************************************
1148 
1149 
1150 //*************************************************************************************************
1166 template< typename VT // Type of the dense vector
1167  , bool TF // Transpose flag
1168  , size_t... CSAs > // Compile time subvector arguments
1169 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1170  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( initializer_list<ElementType> list )
1171 {
1172  if( list.size() > size() ) {
1173  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
1174  }
1175 
1176  if( IsRestricted<VT>::value ) {
1177  const InitializerVector<ElementType,TF> tmp( list, size() );
1178  if( !tryAssign( vector_, tmp, offset() ) ) {
1179  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1180  }
1181  }
1182 
1183  decltype(auto) left( derestrict( *this ) );
1184 
1185  std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
1186 
1187  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1188 
1189  return *this;
1190 }
1192 //*************************************************************************************************
1193 
1194 
1195 //*************************************************************************************************
1207 template< typename VT // Type of the dense vector
1208  , bool TF // Transpose flag
1209  , size_t... CSAs > // Compile time subvector arguments
1210 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1211  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const Subvector& rhs )
1212 {
1215 
1216  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset() == rhs.offset() ) )
1217  return *this;
1218 
1219  if( size() != rhs.size() ) {
1220  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
1221  }
1222 
1223  if( !tryAssign( vector_, rhs, offset() ) ) {
1224  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1225  }
1226 
1227  decltype(auto) left( derestrict( *this ) );
1228 
1229  if( rhs.canAlias( &vector_ ) ) {
1230  const ResultType tmp( rhs );
1231  smpAssign( left, tmp );
1232  }
1233  else {
1234  smpAssign( left, rhs );
1235  }
1236 
1237  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1238 
1239  return *this;
1240 }
1242 //*************************************************************************************************
1243 
1244 
1245 //*************************************************************************************************
1257 template< typename VT // Type of the dense vector
1258  , bool TF // Transpose flag
1259  , size_t... CSAs > // Compile time subvector arguments
1260 template< typename VT2 > // Type of the right-hand side vector
1261 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1262  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const Vector<VT2,TF>& rhs )
1263 {
1266 
1267  if( size() != (~rhs).size() ) {
1268  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1269  }
1270 
1271  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1272  Right right( ~rhs );
1273 
1274  if( !tryAssign( vector_, right, offset() ) ) {
1275  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1276  }
1277 
1278  decltype(auto) left( derestrict( *this ) );
1279 
1280  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1281  const ResultType_<VT2> tmp( right );
1282  smpAssign( left, tmp );
1283  }
1284  else {
1285  if( IsSparseVector<VT2>::value )
1286  reset();
1287  smpAssign( left, right );
1288  }
1289 
1290  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1291 
1292  return *this;
1293 }
1295 //*************************************************************************************************
1296 
1297 
1298 //*************************************************************************************************
1310 template< typename VT // Type of the dense vector
1311  , bool TF // Transpose flag
1312  , size_t... CSAs > // Compile time subvector arguments
1313 template< typename VT2 > // Type of the right-hand side vector
1314 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1315  Subvector<VT,unaligned,TF,true,CSAs...>::operator+=( const Vector<VT2,TF>& rhs )
1316 {
1319 
1320  if( size() != (~rhs).size() ) {
1321  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1322  }
1323 
1324  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1325  Right right( ~rhs );
1326 
1327  if( !tryAddAssign( vector_, right, offset() ) ) {
1328  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1329  }
1330 
1331  decltype(auto) left( derestrict( *this ) );
1332 
1333  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1334  const ResultType_<VT2> tmp( right );
1335  smpAddAssign( left, tmp );
1336  }
1337  else {
1338  smpAddAssign( left, right );
1339  }
1340 
1341  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1342 
1343  return *this;
1344 }
1346 //*************************************************************************************************
1347 
1348 
1349 //*************************************************************************************************
1361 template< typename VT // Type of the dense vector
1362  , bool TF // Transpose flag
1363  , size_t... CSAs > // Compile time subvector arguments
1364 template< typename VT2 > // Type of the right-hand side vector
1365 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1366  Subvector<VT,unaligned,TF,true,CSAs...>::operator-=( const Vector<VT2,TF>& rhs )
1367 {
1370 
1371  if( size() != (~rhs).size() ) {
1372  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1373  }
1374 
1375  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1376  Right right( ~rhs );
1377 
1378  if( !trySubAssign( vector_, right, offset() ) ) {
1379  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1380  }
1381 
1382  decltype(auto) left( derestrict( *this ) );
1383 
1384  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1385  const ResultType_<VT2> tmp( right );
1386  smpSubAssign( left, tmp );
1387  }
1388  else {
1389  smpSubAssign( left, right );
1390  }
1391 
1392  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1393 
1394  return *this;
1395 }
1397 //*************************************************************************************************
1398 
1399 
1400 //*************************************************************************************************
1413 template< typename VT // Type of the dense vector
1414  , bool TF // Transpose flag
1415  , size_t... CSAs > // Compile time subvector arguments
1416 template< typename VT2 > // Type of the right-hand side vector
1417 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1418  Subvector<VT,unaligned,TF,true,CSAs...>::operator*=( const Vector<VT2,TF>& rhs )
1419 {
1422 
1423  if( size() != (~rhs).size() ) {
1424  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1425  }
1426 
1427  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1428  Right right( ~rhs );
1429 
1430  if( !tryMultAssign( vector_, right, offset() ) ) {
1431  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1432  }
1433 
1434  decltype(auto) left( derestrict( *this ) );
1435 
1436  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1437  const ResultType_<VT2> tmp( right );
1438  smpMultAssign( left, tmp );
1439  }
1440  else {
1441  smpMultAssign( left, right );
1442  }
1443 
1444  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1445 
1446  return *this;
1447 }
1449 //*************************************************************************************************
1450 
1451 
1452 //*************************************************************************************************
1464 template< typename VT // Type of the dense vector
1465  , bool TF // Transpose flag
1466  , size_t... CSAs > // Compile time subvector arguments
1467 template< typename VT2 > // Type of the right-hand side dense vector
1468 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1469  Subvector<VT,unaligned,TF,true,CSAs...>::operator/=( const DenseVector<VT2,TF>& rhs )
1470 {
1473 
1474  if( size() != (~rhs).size() ) {
1475  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1476  }
1477 
1478  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1479  Right right( ~rhs );
1480 
1481  if( !tryDivAssign( vector_, right, offset() ) ) {
1482  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1483  }
1484 
1485  decltype(auto) left( derestrict( *this ) );
1486 
1487  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1488  const ResultType_<VT2> tmp( right );
1489  smpDivAssign( left, tmp );
1490  }
1491  else {
1492  smpDivAssign( left, right );
1493  }
1494 
1495  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1496 
1497  return *this;
1498 }
1500 //*************************************************************************************************
1501 
1502 
1503 //*************************************************************************************************
1516 template< typename VT // Type of the dense vector
1517  , bool TF // Transpose flag
1518  , size_t... CSAs > // Compile time subvector arguments
1519 template< typename VT2 > // Type of the right-hand side vector
1520 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1521  Subvector<VT,unaligned,TF,true,CSAs...>::operator%=( const Vector<VT2,TF>& rhs )
1522 {
1523  using blaze::assign;
1524 
1527 
1528  using CrossType = CrossTrait_< ResultType, ResultType_<VT2> >;
1529 
1533 
1534  if( size() != 3UL || (~rhs).size() != 3UL ) {
1535  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1536  }
1537 
1538  const CrossType tmp( *this % (~rhs) );
1539 
1540  if( !tryAssign( vector_, tmp, offset() ) ) {
1541  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1542  }
1543 
1544  decltype(auto) left( derestrict( *this ) );
1545 
1546  assign( left, tmp );
1547 
1548  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1549 
1550  return *this;
1551 }
1553 //*************************************************************************************************
1554 
1555 
1556 
1557 
1558 //=================================================================================================
1559 //
1560 // UTILITY FUNCTIONS
1561 //
1562 //=================================================================================================
1563 
1564 //*************************************************************************************************
1570 template< typename VT // Type of the dense vector
1571  , bool TF // Transpose flag
1572  , size_t... CSAs > // Compile time subvector arguments
1573 inline VT& Subvector<VT,unaligned,TF,true,CSAs...>::operand() noexcept
1574 {
1575  return vector_;
1576 }
1578 //*************************************************************************************************
1579 
1580 
1581 //*************************************************************************************************
1587 template< typename VT // Type of the dense vector
1588  , bool TF // Transpose flag
1589  , size_t... CSAs > // Compile time subvector arguments
1590 inline const VT& Subvector<VT,unaligned,TF,true,CSAs...>::operand() const noexcept
1591 {
1592  return vector_;
1593 }
1595 //*************************************************************************************************
1596 
1597 
1598 //*************************************************************************************************
1607 template< typename VT // Type of the dense vector
1608  , bool TF // Transpose flag
1609  , size_t... CSAs > // Compile time subvector arguments
1610 inline size_t Subvector<VT,unaligned,TF,true,CSAs...>::spacing() const noexcept
1611 {
1612  return vector_.spacing() - offset();
1613 }
1615 //*************************************************************************************************
1616 
1617 
1618 //*************************************************************************************************
1624 template< typename VT // Type of the dense vector
1625  , bool TF // Transpose flag
1626  , size_t... CSAs > // Compile time subvector arguments
1627 inline size_t Subvector<VT,unaligned,TF,true,CSAs...>::capacity() const noexcept
1628 {
1629  return vector_.capacity() - offset();
1630 }
1632 //*************************************************************************************************
1633 
1634 
1635 //*************************************************************************************************
1644 template< typename VT // Type of the dense vector
1645  , bool TF // Transpose flag
1646  , size_t... CSAs > // Compile time subvector arguments
1648 {
1649  size_t nonzeros( 0 );
1650 
1651  const size_t iend( offset() + size() );
1652  for( size_t i=offset(); i<iend; ++i ) {
1653  if( !isDefault( vector_[i] ) )
1654  ++nonzeros;
1655  }
1656 
1657  return nonzeros;
1658 }
1660 //*************************************************************************************************
1661 
1662 
1663 //*************************************************************************************************
1669 template< typename VT // Type of the dense vector
1670  , bool TF // Transpose flag
1671  , size_t... CSAs > // Compile time subvector arguments
1673 {
1674  using blaze::clear;
1675 
1676  const size_t iend( offset() + size() );
1677  for( size_t i=offset(); i<iend; ++i )
1678  clear( vector_[i] );
1679 }
1681 //*************************************************************************************************
1682 
1683 
1684 
1685 
1686 //=================================================================================================
1687 //
1688 // NUMERIC FUNCTIONS
1689 //
1690 //=================================================================================================
1691 
1692 //*************************************************************************************************
1703 template< typename VT // Type of the dense vector
1704  , bool TF // Transpose flag
1705  , size_t... CSAs > // Compile time subvector arguments
1706 template< typename Other > // Data type of the scalar value
1707 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1708  Subvector<VT,unaligned,TF,true,CSAs...>::scale( const Other& scalar )
1709 {
1710  const size_t iend( offset() + size() );
1711  for( size_t i=offset(); i<iend; ++i )
1712  vector_[i] *= scalar;
1713  return *this;
1714 }
1716 //*************************************************************************************************
1717 
1718 
1719 
1720 
1721 //=================================================================================================
1722 //
1723 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1724 //
1725 //=================================================================================================
1726 
1727 //*************************************************************************************************
1738 template< typename VT // Type of the dense vector
1739  , bool TF // Transpose flag
1740  , size_t... CSAs > // Compile time subvector arguments
1741 template< typename Other > // Data type of the foreign expression
1742 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::canAlias( const Other* alias ) const noexcept
1743 {
1744  return vector_.isAliased( alias );
1745 }
1747 //*************************************************************************************************
1748 
1749 
1750 //*************************************************************************************************
1761 template< typename VT // Type of the dense vector
1762  , bool TF // Transpose flag
1763  , size_t... CSAs > // Compile time subvector arguments
1764 template< typename VT2 // Data type of the foreign dense subvector
1765  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
1766  , bool TF2 // Transpose flag of the foreign dense subvector
1767  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
1768 inline bool
1769  Subvector<VT,unaligned,TF,true,CSAs...>::canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
1770 {
1771  return ( vector_.isAliased( &alias->vector_ ) &&
1772  ( offset() + size() > alias->offset() ) &&
1773  ( offset() < alias->offset() + alias->size() ) );
1774 }
1776 //*************************************************************************************************
1777 
1778 
1779 //*************************************************************************************************
1790 template< typename VT // Type of the dense vector
1791  , bool TF // Transpose flag
1792  , size_t... CSAs > // Compile time subvector arguments
1793 template< typename Other > // Data type of the foreign expression
1794 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::isAliased( const Other* alias ) const noexcept
1795 {
1796  return vector_.isAliased( alias );
1797 }
1799 //*************************************************************************************************
1800 
1801 
1802 //*************************************************************************************************
1813 template< typename VT // Type of the dense vector
1814  , bool TF // Transpose flag
1815  , size_t... CSAs > // Compile time subvector arguments
1816 template< typename VT2 // Data type of the foreign dense subvector
1817  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
1818  , bool TF2 // Transpose flag of the foreign dense subvector
1819  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
1820 inline bool
1821  Subvector<VT,unaligned,TF,true,CSAs...>::isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
1822 {
1823  return ( vector_.isAliased( &alias->vector_ ) &&
1824  ( offset() + size() > alias->offset() ) &&
1825  ( offset() < alias->offset() + alias->size() ) );
1826 }
1828 //*************************************************************************************************
1829 
1830 
1831 //*************************************************************************************************
1841 template< typename VT // Type of the dense vector
1842  , bool TF // Transpose flag
1843  , size_t... CSAs > // Compile time subvector arguments
1844 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::isAligned() const noexcept
1845 {
1846  return isAligned_;
1847 }
1849 //*************************************************************************************************
1850 
1851 
1852 //*************************************************************************************************
1863 template< typename VT // Type of the dense vector
1864  , bool TF // Transpose flag
1865  , size_t... CSAs > // Compile time subvector arguments
1866 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::canSMPAssign() const noexcept
1867 {
1868  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1869 }
1871 //*************************************************************************************************
1872 
1873 
1874 //*************************************************************************************************
1888 template< typename VT // Type of the dense vector
1889  , bool TF // Transpose flag
1890  , size_t... CSAs > // Compile time subvector arguments
1891 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1892  Subvector<VT,unaligned,TF,true,CSAs...>::load( size_t index ) const noexcept
1893 {
1894  if( isAligned_ )
1895  return loada( index );
1896  else
1897  return loadu( index );
1898 }
1900 //*************************************************************************************************
1901 
1902 
1903 //*************************************************************************************************
1917 template< typename VT // Type of the dense vector
1918  , bool TF // Transpose flag
1919  , size_t... CSAs > // Compile time subvector arguments
1920 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1921  Subvector<VT,unaligned,TF,true,CSAs...>::loada( size_t index ) const noexcept
1922 {
1924 
1925  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1926  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1927  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1928 
1929  return vector_.loada( offset()+index );
1930 }
1932 //*************************************************************************************************
1933 
1934 
1935 //*************************************************************************************************
1949 template< typename VT // Type of the dense vector
1950  , bool TF // Transpose flag
1951  , size_t... CSAs > // Compile time subvector arguments
1952 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1953  Subvector<VT,unaligned,TF,true,CSAs...>::loadu( size_t index ) const noexcept
1954 {
1956 
1957  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1958  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1959  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1960 
1961  return vector_.loadu( offset()+index );
1962 }
1964 //*************************************************************************************************
1965 
1966 
1967 //*************************************************************************************************
1982 template< typename VT // Type of the dense vector
1983  , bool TF // Transpose flag
1984  , size_t... CSAs > // Compile time subvector arguments
1986  Subvector<VT,unaligned,TF,true,CSAs...>::store( size_t index, const SIMDType& value ) noexcept
1987 {
1988  if( isAligned_ )
1989  storea( index, value );
1990  else
1991  storeu( index, value );
1992 }
1994 //*************************************************************************************************
1995 
1996 
1997 //*************************************************************************************************
2012 template< typename VT // Type of the dense vector
2013  , bool TF // Transpose flag
2014  , size_t... CSAs > // Compile time subvector arguments
2016  Subvector<VT,unaligned,TF,true,CSAs...>::storea( size_t index, const SIMDType& value ) noexcept
2017 {
2019 
2020  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2021  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2022  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2023 
2024  vector_.storea( offset()+index, value );
2025 }
2027 //*************************************************************************************************
2028 
2029 
2030 //*************************************************************************************************
2045 template< typename VT // Type of the dense vector
2046  , bool TF // Transpose flag
2047  , size_t... CSAs > // Compile time subvector arguments
2049  Subvector<VT,unaligned,TF,true,CSAs...>::storeu( size_t index, const SIMDType& value ) noexcept
2050 {
2052 
2053  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2054  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2055  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2056 
2057  vector_.storeu( offset()+index, value );
2058 }
2060 //*************************************************************************************************
2061 
2062 
2063 //*************************************************************************************************
2078 template< typename VT // Type of the dense vector
2079  , bool TF // Transpose flag
2080  , size_t... CSAs > // Compile time subvector arguments
2082  Subvector<VT,unaligned,TF,true,CSAs...>::stream( size_t index, const SIMDType& value ) noexcept
2083 {
2085 
2086  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2087  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2088  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2089 
2090  if( isAligned_ )
2091  vector_.stream( offset()+index, value );
2092  else
2093  vector_.storeu( offset()+index, value );
2094 }
2096 //*************************************************************************************************
2097 
2098 
2099 //*************************************************************************************************
2111 template< typename VT // Type of the dense vector
2112  , bool TF // Transpose flag
2113  , size_t... CSAs > // Compile time subvector arguments
2114 template< typename VT2 > // Type of the right-hand side dense vector
2115 inline DisableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2116  Subvector<VT,unaligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
2117 {
2118  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2119 
2120  const size_t ipos( size() & size_t(-2) );
2121  for( size_t i=0UL; i<ipos; i+=2UL ) {
2122  vector_[offset()+i ] = (~rhs)[i ];
2123  vector_[offset()+i+1UL] = (~rhs)[i+1UL];
2124  }
2125  if( ipos < size() ) {
2126  vector_[offset()+ipos] = (~rhs)[ipos];
2127  }
2128 }
2130 //*************************************************************************************************
2131 
2132 
2133 //*************************************************************************************************
2145 template< typename VT // Type of the dense vector
2146  , bool TF // Transpose flag
2147  , size_t... CSAs > // Compile time subvector arguments
2148 template< typename VT2 > // Type of the right-hand side dense vector
2149 inline EnableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2150  Subvector<VT,unaligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
2151 {
2153 
2154  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2155 
2156  const size_t ipos( size() & size_t(-SIMDSIZE) );
2157  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2158 
2159  size_t i( 0UL );
2160  Iterator left( begin() );
2161  ConstIterator_<VT2> right( (~rhs).begin() );
2162 
2163  if( useStreaming && isAligned_ &&
2164  ( size() > ( cacheSize/( sizeof(ElementType) * 3UL ) ) ) &&
2165  !(~rhs).isAliased( &vector_ ) )
2166  {
2167  for( ; i<ipos; i+=SIMDSIZE ) {
2168  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2169  }
2170  for( ; i<size(); ++i ) {
2171  *left = *right;
2172  }
2173  }
2174  else
2175  {
2176  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2177  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2178  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2179  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2180  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2181  }
2182  for( ; i<ipos; i+=SIMDSIZE ) {
2183  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2184  }
2185  for( ; i<size(); ++i ) {
2186  *left = *right; ++left; ++right;
2187  }
2188  }
2189 }
2191 //*************************************************************************************************
2192 
2193 
2194 //*************************************************************************************************
2206 template< typename VT // Type of the dense vector
2207  , bool TF // Transpose flag
2208  , size_t... CSAs > // Compile time subvector arguments
2209 template< typename VT2 > // Type of the right-hand side sparse vector
2210 inline void Subvector<VT,unaligned,TF,true,CSAs...>::assign( const SparseVector<VT2,TF>& rhs )
2211 {
2212  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2213 
2214  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2215  vector_[offset()+element->index()] = element->value();
2216 }
2218 //*************************************************************************************************
2219 
2220 
2221 //*************************************************************************************************
2233 template< typename VT // Type of the dense vector
2234  , bool TF // Transpose flag
2235  , size_t... CSAs > // Compile time subvector arguments
2236 template< typename VT2 > // Type of the right-hand side dense vector
2237 inline DisableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2238  Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
2239 {
2240  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2241 
2242  const size_t ipos( size() & size_t(-2) );
2243  for( size_t i=0UL; i<ipos; i+=2UL ) {
2244  vector_[offset()+i ] += (~rhs)[i ];
2245  vector_[offset()+i+1UL] += (~rhs)[i+1UL];
2246  }
2247  if( ipos < size() ) {
2248  vector_[offset()+ipos] += (~rhs)[ipos];
2249  }
2250 }
2252 //*************************************************************************************************
2253 
2254 
2255 //*************************************************************************************************
2267 template< typename VT // Type of the dense vector
2268  , bool TF // Transpose flag
2269  , size_t... CSAs > // Compile time subvector arguments
2270 template< typename VT2 > // Type of the right-hand side dense vector
2271 inline EnableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2272  Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
2273 {
2275 
2276  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2277 
2278  const size_t ipos( size() & size_t(-SIMDSIZE) );
2279  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2280 
2281  size_t i( 0UL );
2282  Iterator left( begin() );
2283  ConstIterator_<VT2> right( (~rhs).begin() );
2284 
2285  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2286  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2287  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2288  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2289  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2290  }
2291  for( ; i<ipos; i+=SIMDSIZE ) {
2292  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2293  }
2294  for( ; i<size(); ++i ) {
2295  *left += *right; ++left; ++right;
2296  }
2297 }
2299 //*************************************************************************************************
2300 
2301 
2302 //*************************************************************************************************
2314 template< typename VT // Type of the dense vector
2315  , bool TF // Transpose flag
2316  , size_t... CSAs > // Compile time subvector arguments
2317 template< typename VT2 > // Type of the right-hand side sparse vector
2318 inline void Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const SparseVector<VT2,TF>& rhs )
2319 {
2320  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2321 
2322  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2323  vector_[offset()+element->index()] += element->value();
2324 }
2326 //*************************************************************************************************
2327 
2328 
2329 //*************************************************************************************************
2341 template< typename VT // Type of the dense vector
2342  , bool TF // Transpose flag
2343  , size_t... CSAs > // Compile time subvector arguments
2344 template< typename VT2 > // Type of the right-hand side dense vector
2345 inline DisableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2346  Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
2347 {
2348  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2349 
2350  const size_t ipos( size() & size_t(-2) );
2351  for( size_t i=0UL; i<ipos; i+=2UL ) {
2352  vector_[offset()+i ] -= (~rhs)[i ];
2353  vector_[offset()+i+1UL] -= (~rhs)[i+1UL];
2354  }
2355  if( ipos < size() ) {
2356  vector_[offset()+ipos] -= (~rhs)[ipos];
2357  }
2358 }
2360 //*************************************************************************************************
2361 
2362 
2363 //*************************************************************************************************
2375 template< typename VT // Type of the dense vector
2376  , bool TF // Transpose flag
2377  , size_t... CSAs > // Compile time subvector arguments
2378 template< typename VT2 > // Type of the right-hand side dense vector
2379 inline EnableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2380  Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
2381 {
2383 
2384  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2385 
2386  const size_t ipos( size() & size_t(-SIMDSIZE) );
2387  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2388 
2389  size_t i( 0UL );
2390  Iterator left( begin() );
2391  ConstIterator_<VT2> right( (~rhs).begin() );
2392 
2393  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2394  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2395  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2396  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2397  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2398  }
2399  for( ; i<ipos; i+=SIMDSIZE ) {
2400  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2401  }
2402  for( ; i<size(); ++i ) {
2403  *left -= *right; ++left; ++right;
2404  }
2405 }
2407 //*************************************************************************************************
2408 
2409 
2410 //*************************************************************************************************
2422 template< typename VT // Type of the dense vector
2423  , bool TF // Transpose flag
2424  , size_t... CSAs > // Compile time subvector arguments
2425 template< typename VT2 > // Type of the right-hand side sparse vector
2426 inline void Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const SparseVector<VT2,TF>& rhs )
2427 {
2428  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2429 
2430  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2431  vector_[offset()+element->index()] -= element->value();
2432 }
2434 //*************************************************************************************************
2435 
2436 
2437 //*************************************************************************************************
2449 template< typename VT // Type of the dense vector
2450  , bool TF // Transpose flag
2451  , size_t... CSAs > // Compile time subvector arguments
2452 template< typename VT2 > // Type of the right-hand side dense vector
2453 inline DisableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2454  Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
2455 {
2456  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2457 
2458  const size_t ipos( size() & size_t(-2) );
2459  for( size_t i=0UL; i<ipos; i+=2UL ) {
2460  vector_[offset()+i ] *= (~rhs)[i ];
2461  vector_[offset()+i+1UL] *= (~rhs)[i+1UL];
2462  }
2463  if( ipos < size() ) {
2464  vector_[offset()+ipos] *= (~rhs)[ipos];
2465  }
2466 }
2468 //*************************************************************************************************
2469 
2470 
2471 //*************************************************************************************************
2483 template< typename VT // Type of the dense vector
2484  , bool TF // Transpose flag
2485  , size_t... CSAs > // Compile time subvector arguments
2486 template< typename VT2 > // Type of the right-hand side dense vector
2487 inline EnableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2488  Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
2489 {
2491 
2492  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2493 
2494  const size_t ipos( size() & size_t(-SIMDSIZE) );
2495  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2496 
2497  size_t i( 0UL );
2498  Iterator left( begin() );
2499  ConstIterator_<VT2> right( (~rhs).begin() );
2500 
2501  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2502  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2503  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2504  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2505  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2506  }
2507  for( ; i<ipos; i+=SIMDSIZE ) {
2508  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2509  }
2510  for( ; i<size(); ++i ) {
2511  *left *= *right; ++left; ++right;
2512  }
2513 }
2515 //*************************************************************************************************
2516 
2517 
2518 //*************************************************************************************************
2530 template< typename VT // Type of the dense vector
2531  , bool TF // Transpose flag
2532  , size_t... CSAs > // Compile time subvector arguments
2533 template< typename VT2 > // Type of the right-hand side sparse vector
2534 inline void Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const SparseVector<VT2,TF>& rhs )
2535 {
2536  using blaze::reset;
2537 
2538  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2539 
2540  size_t i( 0UL );
2541 
2542  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2543  const size_t index( element->index() );
2544  for( ; i<index; ++i )
2545  reset( vector_[offset()+i] );
2546  vector_[offset()+i] *= element->value();
2547  ++i;
2548  }
2549 
2550  for( ; i<size(); ++i ) {
2551  reset( vector_[offset()+i] );
2552  }
2553 }
2555 //*************************************************************************************************
2556 
2557 
2558 //*************************************************************************************************
2570 template< typename VT // Type of the dense vector
2571  , bool TF // Transpose flag
2572  , size_t... CSAs > // Compile time subvector arguments
2573 template< typename VT2 > // Type of the right-hand side dense vector
2574 inline DisableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2575  Subvector<VT,unaligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
2576 {
2577  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2578 
2579  const size_t ipos( size() & size_t(-2) );
2580  for( size_t i=0UL; i<ipos; i+=2UL ) {
2581  vector_[offset()+i ] /= (~rhs)[i ];
2582  vector_[offset()+i+1UL] /= (~rhs)[i+1UL];
2583  }
2584  if( ipos < size() ) {
2585  vector_[offset()+ipos] /= (~rhs)[ipos];
2586  }
2587 }
2589 //*************************************************************************************************
2590 
2591 
2592 //*************************************************************************************************
2604 template< typename VT // Type of the dense vector
2605  , bool TF // Transpose flag
2606  , size_t... CSAs > // Compile time subvector arguments
2607 template< typename VT2 > // Type of the right-hand side dense vector
2608 inline EnableIf_< typename Subvector<VT,unaligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2609  Subvector<VT,unaligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
2610 {
2612 
2613  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2614 
2615  const size_t ipos( size() & size_t(-SIMDSIZE) );
2616  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2617 
2618  size_t i( 0UL );
2619  Iterator left( begin() );
2620  ConstIterator_<VT2> right( (~rhs).begin() );
2621 
2622  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2623  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2624  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2625  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2626  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2627  }
2628  for( ; i<ipos; i+=SIMDSIZE ) {
2629  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2630  }
2631  for( ; i<size(); ++i ) {
2632  *left /= *right; ++left; ++right;
2633  }
2634 }
2636 //*************************************************************************************************
2637 
2638 
2639 
2640 
2641 
2642 
2643 
2644 
2645 //=================================================================================================
2646 //
2647 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED DENSE SUBVECTORS
2648 //
2649 //=================================================================================================
2650 
2651 //*************************************************************************************************
2659 template< typename VT // Type of the dense vector
2660  , bool TF // Transpose flag
2661  , size_t... CSAs > // Compile time subvector arguments
2662 class Subvector<VT,aligned,TF,true,CSAs...>
2663  : public View< DenseVector< Subvector<VT,aligned,TF,true,CSAs...>, TF > >
2664  , private SubvectorData<CSAs...>
2665 {
2666  private:
2667  //**Type definitions****************************************************************************
2668  using DataType = SubvectorData<CSAs...>;
2669  using Operand = If_< IsExpression<VT>, VT, VT& >;
2670  //**********************************************************************************************
2671 
2672  public:
2673  //**Type definitions****************************************************************************
2675  using This = Subvector<VT,aligned,TF,true,CSAs...>;
2676 
2677  using BaseType = DenseVector<This,TF>;
2678  using ViewedType = VT;
2679  using ResultType = SubvectorTrait_<VT,CSAs...>;
2680  using TransposeType = TransposeType_<ResultType>;
2681  using ElementType = ElementType_<VT>;
2682  using SIMDType = SIMDTrait_<ElementType>;
2683  using ReturnType = ReturnType_<VT>;
2684  using CompositeType = const Subvector&;
2685 
2687  using ConstReference = ConstReference_<VT>;
2688 
2690  using Reference = If_< IsConst<VT>, ConstReference, Reference_<VT> >;
2691 
2693  using ConstPointer = ConstPointer_<VT>;
2694 
2696  using Pointer = If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, Pointer_<VT> >;
2697 
2699  using ConstIterator = ConstIterator_<VT>;
2700 
2702  using Iterator = If_< IsConst<VT>, ConstIterator, Iterator_<VT> >;
2703  //**********************************************************************************************
2704 
2705  //**Compilation flags***************************************************************************
2707  enum : bool { simdEnabled = VT::simdEnabled };
2708 
2710  enum : bool { smpAssignable = VT::smpAssignable };
2711  //**********************************************************************************************
2712 
2713  //**Constructors********************************************************************************
2716  template< typename... RSAs >
2717  explicit inline Subvector( VT& vector, RSAs... args );
2718  // No explicitly declared copy constructor.
2720  //**********************************************************************************************
2721 
2722  //**Destructor**********************************************************************************
2723  // No explicitly declared destructor.
2724  //**********************************************************************************************
2725 
2726  //**Data access functions***********************************************************************
2729  inline Reference operator[]( size_t index );
2730  inline ConstReference operator[]( size_t index ) const;
2731  inline Reference at( size_t index );
2732  inline ConstReference at( size_t index ) const;
2733  inline Pointer data () noexcept;
2734  inline ConstPointer data () const noexcept;
2735  inline Iterator begin ();
2736  inline ConstIterator begin () const;
2737  inline ConstIterator cbegin() const;
2738  inline Iterator end ();
2739  inline ConstIterator end () const;
2740  inline ConstIterator cend () const;
2742  //**********************************************************************************************
2743 
2744  //**Assignment operators************************************************************************
2747  inline Subvector& operator= ( const ElementType& rhs );
2748  inline Subvector& operator= ( initializer_list<ElementType> list );
2749  inline Subvector& operator= ( const Subvector& rhs );
2750  template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
2751  template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
2752  template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
2753  template< typename VT2 > inline Subvector& operator*=( const Vector<VT2,TF>& rhs );
2754  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2755  template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
2757  //**********************************************************************************************
2758 
2759  //**Utility functions***************************************************************************
2762  using DataType::offset;
2763  using DataType::size;
2764 
2765  inline VT& operand() noexcept;
2766  inline const VT& operand() const noexcept;
2767 
2768  inline size_t spacing() const noexcept;
2769  inline size_t capacity() const noexcept;
2770  inline size_t nonZeros() const;
2771  inline void reset();
2773  //**********************************************************************************************
2774 
2775  //**Numeric functions***************************************************************************
2778  template< typename Other > inline Subvector& scale( const Other& scalar );
2780  //**********************************************************************************************
2781 
2782  private:
2783  //**********************************************************************************************
2785  template< typename VT2 >
2786  struct VectorizedAssign {
2787  enum : bool { value = useOptimizedKernels &&
2788  simdEnabled && VT2::simdEnabled &&
2789  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
2790  };
2791  //**********************************************************************************************
2792 
2793  //**********************************************************************************************
2795  template< typename VT2 >
2796  struct VectorizedAddAssign {
2797  enum : bool { value = useOptimizedKernels &&
2798  simdEnabled && VT2::simdEnabled &&
2799  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2800  HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
2801  };
2802  //**********************************************************************************************
2803 
2804  //**********************************************************************************************
2806  template< typename VT2 >
2807  struct VectorizedSubAssign {
2808  enum : bool { value = useOptimizedKernels &&
2809  simdEnabled && VT2::simdEnabled &&
2810  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2811  HasSIMDSub< ElementType, ElementType_<VT2> >::value };
2812  };
2813  //**********************************************************************************************
2814 
2815  //**********************************************************************************************
2817  template< typename VT2 >
2818  struct VectorizedMultAssign {
2819  enum : bool { value = useOptimizedKernels &&
2820  simdEnabled && VT2::simdEnabled &&
2821  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2822  HasSIMDMult< ElementType, ElementType_<VT2> >::value };
2823  };
2824  //**********************************************************************************************
2825 
2826  //**********************************************************************************************
2828  template< typename VT2 >
2829  struct VectorizedDivAssign {
2830  enum : bool { value = useOptimizedKernels &&
2831  simdEnabled && VT2::simdEnabled &&
2832  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2833  HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
2834  };
2835  //**********************************************************************************************
2836 
2837  //**SIMD properties*****************************************************************************
2839  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
2840  //**********************************************************************************************
2841 
2842  public:
2843  //**Expression template evaluation functions****************************************************
2846  template< typename Other >
2847  inline bool canAlias( const Other* alias ) const noexcept;
2848 
2849  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
2850  inline bool canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
2851 
2852  template< typename Other >
2853  inline bool isAliased( const Other* alias ) const noexcept;
2854 
2855  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
2856  inline bool isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
2857 
2858  inline bool isAligned () const noexcept;
2859  inline bool canSMPAssign() const noexcept;
2860 
2861  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
2862  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
2863  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
2864 
2865  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
2866  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
2867  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
2868  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
2869 
2870  template< typename VT2 >
2871  inline DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2872 
2873  template< typename VT2 >
2874  inline EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2875 
2876  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
2877 
2878  template< typename VT2 >
2879  inline DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
2880 
2881  template< typename VT2 >
2882  inline EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
2883 
2884  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
2885 
2886  template< typename VT2 >
2887  inline DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
2888 
2889  template< typename VT2 >
2890  inline EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
2891 
2892  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
2893 
2894  template< typename VT2 >
2895  inline DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2896 
2897  template< typename VT2 >
2898  inline EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2899 
2900  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
2901 
2902  template< typename VT2 >
2903  inline DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2904 
2905  template< typename VT2 >
2906  inline EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2908  //**********************************************************************************************
2909 
2910  private:
2911  //**Member variables****************************************************************************
2914  Operand vector_;
2915 
2916  //**********************************************************************************************
2917 
2918  //**Friend declarations*************************************************************************
2919  template< typename VT2, AlignmentFlag AF2, bool TF2, bool DF2, size_t... CSAs2 > friend class Subvector;
2920  //**********************************************************************************************
2921 
2922  //**Compile time checks*************************************************************************
2928  //**********************************************************************************************
2929 };
2931 //*************************************************************************************************
2932 
2933 
2934 
2935 
2936 //=================================================================================================
2937 //
2938 // CONSTRUCTORS
2939 //
2940 //=================================================================================================
2941 
2942 //*************************************************************************************************
2956 template< typename VT // Type of the dense vector
2957  , bool TF // Transpose flag
2958  , size_t... CSAs > // Compile time subvector arguments
2959 template< typename... RSAs > // Runtime subvector arguments
2960 inline Subvector<VT,aligned,TF,true,CSAs...>::Subvector( VT& vector, RSAs... args )
2961  : DataType( args... ) // Base class initialization
2962  , vector_ ( vector ) // The vector containing the subvector
2963 {
2964  if( !Contains< TypeList<RSAs...>, Unchecked >::value )
2965  {
2966  if( offset() + size() > vector.size() ) {
2967  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
2968  }
2969 
2970  if( simdEnabled && vector_.data() != nullptr && !checkAlignment( data() ) ) {
2971  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector alignment" );
2972  }
2973  }
2974  else {
2975  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
2976  BLAZE_USER_ASSERT( !simdEnabled || vector_.data() == nullptr || checkAlignment( data() ), "Invalid subvector alignment" );
2977  }
2978 }
2980 //*************************************************************************************************
2981 
2982 
2983 
2984 
2985 //=================================================================================================
2986 //
2987 // DATA ACCESS FUNCTIONS
2988 //
2989 //=================================================================================================
2990 
2991 //*************************************************************************************************
2998 template< typename VT // Type of the dense vector
2999  , bool TF // Transpose flag
3000  , size_t... CSAs > // Compile time subvector arguments
3001 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Reference
3002  Subvector<VT,aligned,TF,true,CSAs...>::operator[]( size_t index )
3003 {
3004  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
3005  return vector_[offset()+index];
3006 }
3008 //*************************************************************************************************
3009 
3010 
3011 //*************************************************************************************************
3018 template< typename VT // Type of the dense vector
3019  , bool TF // Transpose flag
3020  , size_t... CSAs > // Compile time subvector arguments
3021 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstReference
3022  Subvector<VT,aligned,TF,true,CSAs...>::operator[]( size_t index ) const
3023 {
3024  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
3025  return const_cast<const VT&>( vector_ )[offset()+index];
3026 }
3028 //*************************************************************************************************
3029 
3030 
3031 //*************************************************************************************************
3042 template< typename VT // Type of the dense vector
3043  , bool TF // Transpose flag
3044  , size_t... CSAs > // Compile time subvector arguments
3045 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Reference
3046  Subvector<VT,aligned,TF,true,CSAs...>::at( size_t index )
3047 {
3048  if( index >= size() ) {
3049  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3050  }
3051  return (*this)[index];
3052 }
3054 //*************************************************************************************************
3055 
3056 
3057 //*************************************************************************************************
3068 template< typename VT // Type of the dense vector
3069  , bool TF // Transpose flag
3070  , size_t... CSAs > // Compile time subvector arguments
3071 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstReference
3072  Subvector<VT,aligned,TF,true,CSAs...>::at( size_t index ) const
3073 {
3074  if( index >= size() ) {
3075  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3076  }
3077  return (*this)[index];
3078 }
3080 //*************************************************************************************************
3081 
3082 
3083 //*************************************************************************************************
3091 template< typename VT // Type of the dense vector
3092  , bool TF // Transpose flag
3093  , size_t... CSAs > // Compile time subvector arguments
3094 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Pointer
3096 {
3097  return vector_.data() + offset();
3098 }
3100 //*************************************************************************************************
3101 
3102 
3103 //*************************************************************************************************
3111 template< typename VT // Type of the dense vector
3112  , bool TF // Transpose flag
3113  , size_t... CSAs > // Compile time subvector arguments
3114 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstPointer
3116 {
3117  return vector_.data() + offset();
3118 }
3120 //*************************************************************************************************
3121 
3122 
3123 //*************************************************************************************************
3131 template< typename VT // Type of the dense vector
3132  , bool TF // Transpose flag
3133  , size_t... CSAs > // Compile time subvector arguments
3134 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Iterator
3136 {
3137  return ( vector_.begin() + offset() );
3138 }
3140 //*************************************************************************************************
3141 
3142 
3143 //*************************************************************************************************
3151 template< typename VT // Type of the dense vector
3152  , bool TF // Transpose flag
3153  , size_t... CSAs > // Compile time subvector arguments
3154 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3156 {
3157  return ( vector_.cbegin() + offset() );
3158 }
3160 //*************************************************************************************************
3161 
3162 
3163 //*************************************************************************************************
3171 template< typename VT // Type of the dense vector
3172  , bool TF // Transpose flag
3173  , size_t... CSAs > // Compile time subvector arguments
3174 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3176 {
3177  return ( vector_.cbegin() + offset() );
3178 }
3180 //*************************************************************************************************
3181 
3182 
3183 //*************************************************************************************************
3191 template< typename VT // Type of the dense vector
3192  , bool TF // Transpose flag
3193  , size_t... CSAs > // Compile time subvector arguments
3194 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Iterator
3196 {
3197  return ( vector_.begin() + offset() + size() );
3198 }
3200 //*************************************************************************************************
3201 
3202 
3203 //*************************************************************************************************
3211 template< typename VT // Type of the dense vector
3212  , bool TF // Transpose flag
3213  , size_t... CSAs > // Compile time subvector arguments
3214 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3216 {
3217  return ( vector_.cbegin() + offset() + size() );
3218 }
3220 //*************************************************************************************************
3221 
3222 
3223 //*************************************************************************************************
3231 template< typename VT // Type of the dense vector
3232  , bool TF // Transpose flag
3233  , size_t... CSAs > // Compile time subvector arguments
3234 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3236 {
3237  return ( vector_.cbegin() + offset() + size() );
3238 }
3240 //*************************************************************************************************
3241 
3242 
3243 
3244 
3245 //=================================================================================================
3246 //
3247 // ASSIGNMENT OPERATORS
3248 //
3249 //=================================================================================================
3250 
3251 //*************************************************************************************************
3258 template< typename VT // Type of the dense vector
3259  , bool TF // Transpose flag
3260  , size_t... CSAs > // Compile time subvector arguments
3261 inline Subvector<VT,aligned,TF,true,CSAs...>&
3262  Subvector<VT,aligned,TF,true,CSAs...>::operator=( const ElementType& rhs )
3263 {
3264  const size_t iend( offset() + size() );
3265  decltype(auto) left( derestrict( vector_ ) );
3266 
3267  for( size_t i=offset(); i<iend; ++i ) {
3268  if( !IsRestricted<VT>::value || trySet( vector_, i, rhs ) )
3269  left[i] = rhs;
3270  }
3271 
3272  return *this;
3273 }
3275 //*************************************************************************************************
3276 
3277 
3278 //*************************************************************************************************
3291 template< typename VT // Type of the dense vector
3292  , bool TF // Transpose flag
3293  , size_t... CSAs > // Compile time subvector arguments
3294 inline Subvector<VT,aligned,TF,true,CSAs...>&
3295  Subvector<VT,aligned,TF,true,CSAs...>::operator=( initializer_list<ElementType> list )
3296 {
3297  if( list.size() > size() ) {
3298  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
3299  }
3300 
3301  if( IsRestricted<VT>::value ) {
3302  const InitializerVector<ElementType,TF> tmp( list, size() );
3303  if( !tryAssign( vector_, tmp, offset() ) ) {
3304  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3305  }
3306  }
3307 
3308  decltype(auto) left( derestrict( *this ) );
3309 
3310  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
3311 
3312  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3313 
3314  return *this;
3315 }
3317 //*************************************************************************************************
3318 
3319 
3320 //*************************************************************************************************
3332 template< typename VT // Type of the dense vector
3333  , bool TF // Transpose flag
3334  , size_t... CSAs > // Compile time subvector arguments
3335 inline Subvector<VT,aligned,TF,true,CSAs...>&
3336  Subvector<VT,aligned,TF,true,CSAs...>::operator=( const Subvector& rhs )
3337 {
3340 
3341  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset() == rhs.offset() ) )
3342  return *this;
3343 
3344  if( size() != rhs.size() ) {
3345  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
3346  }
3347 
3348  if( !tryAssign( vector_, rhs, offset() ) ) {
3349  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3350  }
3351 
3352  decltype(auto) left( derestrict( *this ) );
3353 
3354  if( rhs.canAlias( &vector_ ) ) {
3355  const ResultType tmp( ~rhs );
3356  smpAssign( left, tmp );
3357  }
3358  else {
3359  smpAssign( left, rhs );
3360  }
3361 
3362  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3363 
3364  return *this;
3365 }
3367 //*************************************************************************************************
3368 
3369 
3370 //*************************************************************************************************
3382 template< typename VT // Type of the dense vector
3383  , bool TF // Transpose flag
3384  , size_t... CSAs > // Compile time subvector arguments
3385 template< typename VT2 > // Type of the right-hand side vector
3386 inline Subvector<VT,aligned,TF,true,CSAs...>&
3387  Subvector<VT,aligned,TF,true,CSAs...>::operator=( const Vector<VT2,TF>& rhs )
3388 {
3391 
3392  if( size() != (~rhs).size() ) {
3393  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3394  }
3395 
3396  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3397  Right right( ~rhs );
3398 
3399  if( !tryAssign( vector_, right, offset() ) ) {
3400  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3401  }
3402 
3403  decltype(auto) left( derestrict( *this ) );
3404 
3405  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3406  const ResultType_<VT2> tmp( right );
3407  smpAssign( left, tmp );
3408  }
3409  else {
3410  if( IsSparseVector<VT2>::value )
3411  reset();
3412  smpAssign( left, right );
3413  }
3414 
3415  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3416 
3417  return *this;
3418 }
3420 //*************************************************************************************************
3421 
3422 
3423 //*************************************************************************************************
3435 template< typename VT // Type of the dense vector
3436  , bool TF // Transpose flag
3437  , size_t... CSAs > // Compile time subvector arguments
3438 template< typename VT2 > // Type of the right-hand side vector
3439 inline Subvector<VT,aligned,TF,true,CSAs...>&
3440  Subvector<VT,aligned,TF,true,CSAs...>::operator+=( const Vector<VT2,TF>& rhs )
3441 {
3444 
3445  if( size() != (~rhs).size() ) {
3446  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3447  }
3448 
3449  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3450  Right right( ~rhs );
3451 
3452  if( !tryAddAssign( vector_, right, offset() ) ) {
3453  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3454  }
3455 
3456  decltype(auto) left( derestrict( *this ) );
3457 
3458  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3459  const ResultType_<VT2> tmp( right );
3460  smpAddAssign( left, tmp );
3461  }
3462  else {
3463  smpAddAssign( left, right );
3464  }
3465 
3466  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3467 
3468  return *this;
3469 }
3471 //*************************************************************************************************
3472 
3473 
3474 //*************************************************************************************************
3486 template< typename VT // Type of the dense vector
3487  , bool TF // Transpose flag
3488  , size_t... CSAs > // Compile time subvector arguments
3489 template< typename VT2 > // Type of the right-hand side vector
3490 inline Subvector<VT,aligned,TF,true,CSAs...>&
3491  Subvector<VT,aligned,TF,true,CSAs...>::operator-=( const Vector<VT2,TF>& rhs )
3492 {
3495 
3496  if( size() != (~rhs).size() ) {
3497  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3498  }
3499 
3500  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3501  Right right( ~rhs );
3502 
3503  if( !trySubAssign( vector_, right, offset() ) ) {
3504  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3505  }
3506 
3507  decltype(auto) left( derestrict( *this ) );
3508 
3509  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3510  const ResultType_<VT2> tmp( right );
3511  smpSubAssign( left, tmp );
3512  }
3513  else {
3514  smpSubAssign( left, right );
3515  }
3516 
3517  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3518 
3519  return *this;
3520 }
3522 //*************************************************************************************************
3523 
3524 
3525 //*************************************************************************************************
3538 template< typename VT // Type of the dense vector
3539  , bool TF // Transpose flag
3540  , size_t... CSAs > // Compile time subvector arguments
3541 template< typename VT2 > // Type of the right-hand side vector
3542 inline Subvector<VT,aligned,TF,true,CSAs...>&
3543  Subvector<VT,aligned,TF,true,CSAs...>::operator*=( const Vector<VT2,TF>& rhs )
3544 {
3547 
3548  if( size() != (~rhs).size() ) {
3549  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3550  }
3551 
3552  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3553  Right right( ~rhs );
3554 
3555  if( !tryMultAssign( vector_, right, offset() ) ) {
3556  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3557  }
3558 
3559  decltype(auto) left( derestrict( *this ) );
3560 
3561  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3562  const ResultType_<VT2> tmp( right );
3563  smpMultAssign( left, tmp );
3564  }
3565  else {
3566  smpMultAssign( left, right );
3567  }
3568 
3569  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3570 
3571  return *this;
3572 }
3574 //*************************************************************************************************
3575 
3576 
3577 //*************************************************************************************************
3589 template< typename VT // Type of the dense vector
3590  , bool TF // Transpose flag
3591  , size_t... CSAs > // Compile time subvector arguments
3592 template< typename VT2 > // Type of the right-hand side dense vector
3593 inline Subvector<VT,aligned,TF,true,CSAs...>&
3594  Subvector<VT,aligned,TF,true,CSAs...>::operator/=( const DenseVector<VT2,TF>& rhs )
3595 {
3598 
3599  if( size() != (~rhs).size() ) {
3600  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3601  }
3602 
3603  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3604  Right right( ~rhs );
3605 
3606  if( !tryDivAssign( vector_, right, offset() ) ) {
3607  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3608  }
3609 
3610  decltype(auto) left( derestrict( *this ) );
3611 
3612  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3613  const ResultType_<VT2> tmp( right );
3614  smpDivAssign( left, tmp );
3615  }
3616  else {
3617  smpDivAssign( left, right );
3618  }
3619 
3620  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3621 
3622  return *this;
3623 }
3625 //*************************************************************************************************
3626 
3627 
3628 //*************************************************************************************************
3641 template< typename VT // Type of the dense vector
3642  , bool TF // Transpose flag
3643  , size_t... CSAs > // Compile time subvector arguments
3644 template< typename VT2 > // Type of the right-hand side vector
3645 inline Subvector<VT,aligned,TF,true,CSAs...>&
3646  Subvector<VT,aligned,TF,true,CSAs...>::operator%=( const Vector<VT2,TF>& rhs )
3647 {
3648  using blaze::assign;
3649 
3652 
3653  using CrossType = CrossTrait_< ResultType, ResultType_<VT2> >;
3654 
3658 
3659  if( size() != 3UL || (~rhs).size() != 3UL ) {
3660  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3661  }
3662 
3663  const CrossType tmp( *this % (~rhs) );
3664 
3665  if( !tryAssign( vector_, tmp, offset() ) ) {
3666  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3667  }
3668 
3669  decltype(auto) left( derestrict( *this ) );
3670 
3671  assign( left, tmp );
3672 
3673  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3674 
3675  return *this;
3676 }
3678 //*************************************************************************************************
3679 
3680 
3681 
3682 
3683 //=================================================================================================
3684 //
3685 // UTILITY FUNCTIONS
3686 //
3687 //=================================================================================================
3688 
3689 //*************************************************************************************************
3695 template< typename VT // Type of the dense vector
3696  , bool TF // Transpose flag
3697  , size_t... CSAs > // Compile time subvector arguments
3698 inline VT& Subvector<VT,aligned,TF,true,CSAs...>::operand() noexcept
3699 {
3700  return vector_;
3701 }
3703 //*************************************************************************************************
3704 
3705 
3706 //*************************************************************************************************
3712 template< typename VT // Type of the dense vector
3713  , bool TF // Transpose flag
3714  , size_t... CSAs > // Compile time subvector arguments
3715 inline const VT& Subvector<VT,aligned,TF,true,CSAs...>::operand() const noexcept
3716 {
3717  return vector_;
3718 }
3720 //*************************************************************************************************
3721 
3722 
3723 //*************************************************************************************************
3732 template< typename VT // Type of the dense vector
3733  , bool TF // Transpose flag
3734  , size_t... CSAs > // Compile time subvector arguments
3735 inline size_t Subvector<VT,aligned,TF,true,CSAs...>::spacing() const noexcept
3736 {
3737  return vector_.spacing() - offset();
3738 }
3740 //*************************************************************************************************
3741 
3742 
3743 //*************************************************************************************************
3749 template< typename VT // Type of the dense vector
3750  , bool TF // Transpose flag
3751  , size_t... CSAs > // Compile time subvector arguments
3752 inline size_t Subvector<VT,aligned,TF,true,CSAs...>::capacity() const noexcept
3753 {
3754  return vector_.capacity() - offset();
3755 }
3757 //*************************************************************************************************
3758 
3759 
3760 //*************************************************************************************************
3769 template< typename VT // Type of the dense vector
3770  , bool TF // Transpose flag
3771  , size_t... CSAs > // Compile time subvector arguments
3773 {
3774  size_t nonzeros( 0 );
3775 
3776  const size_t iend( offset() + size() );
3777  for( size_t i=offset(); i<iend; ++i ) {
3778  if( !isDefault( vector_[i] ) )
3779  ++nonzeros;
3780  }
3781 
3782  return nonzeros;
3783 }
3785 //*************************************************************************************************
3786 
3787 
3788 //*************************************************************************************************
3794 template< typename VT // Type of the dense vector
3795  , bool TF // Transpose flag
3796  , size_t... CSAs > // Compile time subvector arguments
3798 {
3799  using blaze::clear;
3800 
3801  const size_t iend( offset() + size() );
3802  for( size_t i=offset(); i<iend; ++i )
3803  clear( vector_[i] );
3804 }
3806 //*************************************************************************************************
3807 
3808 
3809 
3810 
3811 //=================================================================================================
3812 //
3813 // NUMERIC FUNCTIONS
3814 //
3815 //=================================================================================================
3816 
3817 //*************************************************************************************************
3828 template< typename VT // Type of the dense vector
3829  , bool TF // Transpose flag
3830  , size_t... CSAs > // Compile time subvector arguments
3831 template< typename Other > // Data type of the scalar value
3832 inline Subvector<VT,aligned,TF,true,CSAs...>&
3833  Subvector<VT,aligned,TF,true,CSAs...>::scale( const Other& scalar )
3834 {
3835  const size_t iend( offset() + size() );
3836  for( size_t i=offset(); i<iend; ++i )
3837  vector_[i] *= scalar;
3838  return *this;
3839 }
3841 //*************************************************************************************************
3842 
3843 
3844 
3845 
3846 //=================================================================================================
3847 //
3848 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3849 //
3850 //=================================================================================================
3851 
3852 //*************************************************************************************************
3863 template< typename VT // Type of the dense vector
3864  , bool TF // Transpose flag
3865  , size_t... CSAs > // Compile time subvector arguments
3866 template< typename Other > // Data type of the foreign expression
3867 inline bool Subvector<VT,aligned,TF,true,CSAs...>::canAlias( const Other* alias ) const noexcept
3868 {
3869  return vector_.isAliased( alias );
3870 }
3872 //*************************************************************************************************
3873 
3874 
3875 //*************************************************************************************************
3886 template< typename VT // Type of the dense vector
3887  , bool TF // Transpose flag
3888  , size_t... CSAs > // Compile time subvector arguments
3889 template< typename VT2 // Data type of the foreign dense subvector
3890  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
3891  , bool TF2 // Transpose flag of the foreign dense subvector
3892  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
3893 inline bool
3894  Subvector<VT,aligned,TF,true,CSAs...>::canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
3895 {
3896  return ( vector_.isAliased( &alias->vector_ ) &&
3897  ( offset() + size() > alias->offset() ) &&
3898  ( offset() < alias->offset() + alias->size() ) );
3899 }
3901 //*************************************************************************************************
3902 
3903 
3904 //*************************************************************************************************
3915 template< typename VT // Type of the dense vector
3916  , bool TF // Transpose flag
3917  , size_t... CSAs > // Compile time subvector arguments
3918 template< typename Other > // Data type of the foreign expression
3919 inline bool Subvector<VT,aligned,TF,true,CSAs...>::isAliased( const Other* alias ) const noexcept
3920 {
3921  return vector_.isAliased( alias );
3922 }
3924 //*************************************************************************************************
3925 
3926 
3927 //*************************************************************************************************
3938 template< typename VT // Type of the dense vector
3939  , bool TF // Transpose flag
3940  , size_t... CSAs > // Compile time subvector arguments
3941 template< typename VT2 // Data type of the foreign dense subvector
3942  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
3943  , bool TF2 // Transpose flag of the foreign dense subvector
3944  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
3945 inline bool
3946  Subvector<VT,aligned,TF,true,CSAs...>::isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
3947 {
3948  return ( vector_.isAliased( &alias->vector_ ) &&
3949  ( offset() + size() > alias->offset() ) &&
3950  ( offset() < alias->offset() + alias->size() ) );
3951 }
3953 //*************************************************************************************************
3954 
3955 
3956 //*************************************************************************************************
3966 template< typename VT // Type of the dense vector
3967  , bool TF // Transpose flag
3968  , size_t... CSAs > // Compile time subvector arguments
3969 inline bool Subvector<VT,aligned,TF,true,CSAs...>::isAligned() const noexcept
3970 {
3971  return true;
3972 }
3974 //*************************************************************************************************
3975 
3976 
3977 //*************************************************************************************************
3988 template< typename VT // Type of the dense vector
3989  , bool TF // Transpose flag
3990  , size_t... CSAs > // Compile time subvector arguments
3991 inline bool Subvector<VT,aligned,TF,true,CSAs...>::canSMPAssign() const noexcept
3992 {
3993  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3994 }
3996 //*************************************************************************************************
3997 
3998 
3999 //*************************************************************************************************
4013 template< typename VT // Type of the dense vector
4014  , bool TF // Transpose flag
4015  , size_t... CSAs > // Compile time subvector arguments
4016 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4017  Subvector<VT,aligned,TF,true,CSAs...>::load( size_t index ) const noexcept
4018 {
4019  return loada( index );
4020 }
4022 //*************************************************************************************************
4023 
4024 
4025 //*************************************************************************************************
4039 template< typename VT // Type of the dense vector
4040  , bool TF // Transpose flag
4041  , size_t... CSAs > // Compile time subvector arguments
4042 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4043  Subvector<VT,aligned,TF,true,CSAs...>::loada( size_t index ) const noexcept
4044 {
4046 
4047  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4048  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4049  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4050 
4051  return vector_.loada( offset()+index );
4052 }
4054 //*************************************************************************************************
4055 
4056 
4057 //*************************************************************************************************
4071 template< typename VT // Type of the dense vector
4072  , bool TF // Transpose flag
4073  , size_t... CSAs > // Compile time subvector arguments
4074 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4075  Subvector<VT,aligned,TF,true,CSAs...>::loadu( size_t index ) const noexcept
4076 {
4078 
4079  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4080  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4081  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4082 
4083  return vector_.loadu( offset()+index );
4084 }
4086 //*************************************************************************************************
4087 
4088 
4089 //*************************************************************************************************
4104 template< typename VT // Type of the dense vector
4105  , bool TF // Transpose flag
4106  , size_t... CSAs > // Compile time subvector arguments
4108  Subvector<VT,aligned,TF,true,CSAs...>::store( size_t index, const SIMDType& value ) noexcept
4109 {
4110  storea( index, value );
4111 }
4113 //*************************************************************************************************
4114 
4115 
4116 //*************************************************************************************************
4131 template< typename VT // Type of the dense vector
4132  , bool TF // Transpose flag
4133  , size_t... CSAs > // Compile time subvector arguments
4135  Subvector<VT,aligned,TF,true,CSAs...>::storea( size_t index, const SIMDType& value ) noexcept
4136 {
4138 
4139  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4140  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4141  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4142 
4143  vector_.storea( offset()+index, value );
4144 }
4146 //*************************************************************************************************
4147 
4148 
4149 //*************************************************************************************************
4164 template< typename VT // Type of the dense vector
4165  , bool TF // Transpose flag
4166  , size_t... CSAs > // Compile time subvector arguments
4168  Subvector<VT,aligned,TF,true,CSAs...>::storeu( size_t index, const SIMDType& value ) noexcept
4169 {
4171 
4172  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4173  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4174  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4175 
4176  vector_.storeu( offset()+index, value );
4177 }
4179 //*************************************************************************************************
4180 
4181 
4182 //*************************************************************************************************
4197 template< typename VT // Type of the dense vector
4198  , bool TF // Transpose flag
4199  , size_t... CSAs > // Compile time subvector arguments
4201  Subvector<VT,aligned,TF,true,CSAs...>::stream( size_t index, const SIMDType& value ) noexcept
4202 {
4204 
4205  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4206  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4207  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4208 
4209  vector_.stream( offset()+index, value );
4210 }
4212 //*************************************************************************************************
4213 
4214 
4215 //*************************************************************************************************
4227 template< typename VT // Type of the dense vector
4228  , bool TF // Transpose flag
4229  , size_t... CSAs > // Compile time subvector arguments
4230 template< typename VT2 > // Type of the right-hand side dense vector
4231 inline DisableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4232  Subvector<VT,aligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
4233 {
4234  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4235 
4236  const size_t ipos( size() & size_t(-2) );
4237  for( size_t i=0UL; i<ipos; i+=2UL ) {
4238  vector_[offset()+i ] = (~rhs)[i ];
4239  vector_[offset()+i+1UL] = (~rhs)[i+1UL];
4240  }
4241  if( ipos < size() ) {
4242  vector_[offset()+ipos] = (~rhs)[ipos];
4243  }
4244 }
4246 //*************************************************************************************************
4247 
4248 
4249 //*************************************************************************************************
4261 template< typename VT // Type of the dense vector
4262  , bool TF // Transpose flag
4263  , size_t... CSAs > // Compile time subvector arguments
4264 template< typename VT2 > // Type of the right-hand side dense vector
4265 inline EnableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4266  Subvector<VT,aligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
4267 {
4269 
4270  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4271 
4272  const size_t ipos( size() & size_t(-SIMDSIZE) );
4273  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4274 
4275  size_t i( 0UL );
4276  Iterator left( begin() );
4277  ConstIterator_<VT2> right( (~rhs).begin() );
4278 
4279  if( useStreaming && size() > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
4280  {
4281  for( ; i<ipos; i+=SIMDSIZE ) {
4282  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4283  }
4284  for( ; i<size(); ++i ) {
4285  *left = *right; ++left; ++right;
4286  }
4287  }
4288  else
4289  {
4290  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4291  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4292  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4293  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4294  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4295  }
4296  for( ; i<ipos; i+=SIMDSIZE ) {
4297  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4298  }
4299  for( ; i<size(); ++i ) {
4300  *left = *right; ++left; ++right;
4301  }
4302  }
4303 }
4305 //*************************************************************************************************
4306 
4307 
4308 //*************************************************************************************************
4320 template< typename VT // Type of the dense vector
4321  , bool TF // Transpose flag
4322  , size_t... CSAs > // Compile time subvector arguments
4323 template< typename VT2 > // Type of the right-hand side sparse vector
4324 inline void Subvector<VT,aligned,TF,true,CSAs...>::assign( const SparseVector<VT2,TF>& rhs )
4325 {
4326  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4327 
4328  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4329  vector_[offset()+element->index()] = element->value();
4330 }
4332 //*************************************************************************************************
4333 
4334 
4335 //*************************************************************************************************
4347 template< typename VT // Type of the dense vector
4348  , bool TF // Transpose flag
4349  , size_t... CSAs > // Compile time subvector arguments
4350 template< typename VT2 > // Type of the right-hand side dense vector
4351 inline DisableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4352  Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
4353 {
4354  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4355 
4356  const size_t ipos( size() & size_t(-2) );
4357  for( size_t i=0UL; i<ipos; i+=2UL ) {
4358  vector_[offset()+i ] += (~rhs)[i ];
4359  vector_[offset()+i+1UL] += (~rhs)[i+1UL];
4360  }
4361  if( ipos < size() ) {
4362  vector_[offset()+ipos] += (~rhs)[ipos];
4363  }
4364 }
4366 //*************************************************************************************************
4367 
4368 
4369 //*************************************************************************************************
4381 template< typename VT // Type of the dense vector
4382  , bool TF // Transpose flag
4383  , size_t... CSAs > // Compile time subvector arguments
4384 template< typename VT2 > // Type of the right-hand side dense vector
4385 inline EnableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4386  Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
4387 {
4389 
4390  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4391 
4392  const size_t ipos( size() & size_t(-SIMDSIZE) );
4393  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4394 
4395  size_t i( 0UL );
4396  Iterator left( begin() );
4397  ConstIterator_<VT2> right( (~rhs).begin() );
4398 
4399  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4400  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4401  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4402  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4403  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4404  }
4405  for( ; i<ipos; i+=SIMDSIZE ) {
4406  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4407  }
4408  for( ; i<size(); ++i ) {
4409  *left += *right; ++left; ++right;
4410  }
4411 }
4413 //*************************************************************************************************
4414 
4415 
4416 //*************************************************************************************************
4428 template< typename VT // Type of the dense vector
4429  , bool TF // Transpose flag
4430  , size_t... CSAs > // Compile time subvector arguments
4431 template< typename VT2 > // Type of the right-hand side sparse vector
4432 inline void Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const SparseVector<VT2,TF>& rhs )
4433 {
4434  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4435 
4436  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4437  vector_[offset()+element->index()] += element->value();
4438 }
4440 //*************************************************************************************************
4441 
4442 
4443 //*************************************************************************************************
4455 template< typename VT // Type of the dense vector
4456  , bool TF // Transpose flag
4457  , size_t... CSAs > // Compile time subvector arguments
4458 template< typename VT2 > // Type of the right-hand side dense vector
4459 inline DisableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4460  Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
4461 {
4462  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4463 
4464  const size_t ipos( size() & size_t(-2) );
4465  for( size_t i=0UL; i<ipos; i+=2UL ) {
4466  vector_[offset()+i ] -= (~rhs)[i ];
4467  vector_[offset()+i+1UL] -= (~rhs)[i+1UL];
4468  }
4469  if( ipos < size() ) {
4470  vector_[offset()+ipos] -= (~rhs)[ipos];
4471  }
4472 }
4474 //*************************************************************************************************
4475 
4476 
4477 //*************************************************************************************************
4489 template< typename VT // Type of the dense vector
4490  , bool TF // Transpose flag
4491  , size_t... CSAs > // Compile time subvector arguments
4492 template< typename VT2 > // Type of the right-hand side dense vector
4493 inline EnableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4494  Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
4495 {
4497 
4498  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4499 
4500  const size_t ipos( size() & size_t(-SIMDSIZE) );
4501  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4502 
4503  size_t i( 0UL );
4504  Iterator left( begin() );
4505  ConstIterator_<VT2> right( (~rhs).begin() );
4506 
4507  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4508  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4509  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4510  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4511  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4512  }
4513  for( ; i<ipos; i+=SIMDSIZE ) {
4514  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4515  }
4516  for( ; i<size(); ++i ) {
4517  *left -= *right; ++left; ++right;
4518  }
4519 }
4521 //*************************************************************************************************
4522 
4523 
4524 //*************************************************************************************************
4536 template< typename VT // Type of the dense vector
4537  , bool TF // Transpose flag
4538  , size_t... CSAs > // Compile time subvector arguments
4539 template< typename VT2 > // Type of the right-hand side sparse vector
4540 inline void Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const SparseVector<VT2,TF>& rhs )
4541 {
4542  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4543 
4544  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4545  vector_[offset()+element->index()] -= element->value();
4546 }
4548 //*************************************************************************************************
4549 
4550 
4551 //*************************************************************************************************
4563 template< typename VT // Type of the dense vector
4564  , bool TF // Transpose flag
4565  , size_t... CSAs > // Compile time subvector arguments
4566 template< typename VT2 > // Type of the right-hand side dense vector
4567 inline DisableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4568  Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
4569 {
4570  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4571 
4572  const size_t ipos( size() & size_t(-2) );
4573  for( size_t i=0UL; i<ipos; i+=2UL ) {
4574  vector_[offset()+i ] *= (~rhs)[i ];
4575  vector_[offset()+i+1UL] *= (~rhs)[i+1UL];
4576  }
4577  if( ipos < size() ) {
4578  vector_[offset()+ipos] *= (~rhs)[ipos];
4579  }
4580 }
4582 //*************************************************************************************************
4583 
4584 
4585 //*************************************************************************************************
4597 template< typename VT // Type of the dense vector
4598  , bool TF // Transpose flag
4599  , size_t... CSAs > // Compile time subvector arguments
4600 template< typename VT2 > // Type of the right-hand side dense vector
4601 inline EnableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4602  Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
4603 {
4605 
4606  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4607 
4608  const size_t ipos( size() & size_t(-SIMDSIZE) );
4609  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4610 
4611  size_t i( 0UL );
4612  Iterator left( begin() );
4613  ConstIterator_<VT2> right( (~rhs).begin() );
4614 
4615  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4616  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4617  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4618  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4619  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4620  }
4621  for( ; i<ipos; i+=SIMDSIZE ) {
4622  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4623  }
4624  for( ; i<size(); ++i ) {
4625  *left *= *right; ++left; ++right;
4626  }
4627 }
4629 //*************************************************************************************************
4630 
4631 
4632 //*************************************************************************************************
4644 template< typename VT // Type of the dense vector
4645  , bool TF // Transpose flag
4646  , size_t... CSAs > // Compile time subvector arguments
4647 template< typename VT2 > // Type of the right-hand side sparse vector
4648 inline void Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const SparseVector<VT2,TF>& rhs )
4649 {
4650  using blaze::reset;
4651 
4652  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4653 
4654  size_t i( 0UL );
4655 
4656  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
4657  const size_t index( element->index() );
4658  for( ; i<index; ++i )
4659  reset( vector_[offset()+i] );
4660  vector_[offset()+i] *= element->value();
4661  ++i;
4662  }
4663 
4664  for( ; i<size(); ++i ) {
4665  reset( vector_[offset()+i] );
4666  }
4667 }
4669 //*************************************************************************************************
4670 
4671 
4672 //*************************************************************************************************
4684 template< typename VT // Type of the dense vector
4685  , bool TF // Transpose flag
4686  , size_t... CSAs > // Compile time subvector arguments
4687 template< typename VT2 > // Type of the right-hand side dense vector
4688 inline DisableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4689  Subvector<VT,aligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
4690 {
4691  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4692 
4693  const size_t ipos( size() & size_t(-2) );
4694  for( size_t i=0UL; i<ipos; i+=2UL ) {
4695  vector_[offset()+i ] /= (~rhs)[i ];
4696  vector_[offset()+i+1UL] /= (~rhs)[i+1UL];
4697  }
4698  if( ipos < size() ) {
4699  vector_[offset()+ipos] /= (~rhs)[ipos];
4700  }
4701 }
4703 //*************************************************************************************************
4704 
4705 
4706 //*************************************************************************************************
4718 template< typename VT // Type of the dense vector
4719  , bool TF // Transpose flag
4720  , size_t... CSAs > // Compile time subvector arguments
4721 template< typename VT2 > // Type of the right-hand side dense vector
4722 inline EnableIf_< typename Subvector<VT,aligned,TF,true,CSAs...>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4723  Subvector<VT,aligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
4724 {
4726 
4727  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4728 
4729  const size_t ipos( size() & size_t(-SIMDSIZE) );
4730  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4731 
4732  size_t i( 0UL );
4733  Iterator left( begin() );
4734  ConstIterator_<VT2> right( (~rhs).begin() );
4735 
4736  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4737  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4738  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4739  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4740  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4741  }
4742  for( ; i<ipos; i+=SIMDSIZE ) {
4743  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4744  }
4745  for( ; i<size(); ++i ) {
4746  *left /= *right; ++left; ++right;
4747  }
4748 }
4750 //*************************************************************************************************
4751 
4752 
4753 
4754 
4755 
4756 
4757 
4758 
4759 //=================================================================================================
4760 //
4761 // CLASS TEMPLATE SPECIALIZATION FOR DVECDVECCROSSEXPR
4762 //
4763 //=================================================================================================
4764 
4765 //*************************************************************************************************
4773 template< typename VT1 // Type of the left-hand side dense vector
4774  , typename VT2 // Type of the right-hand side dense vector
4775  , bool TF // Transpose flag
4776  , size_t... CSAs > // Compile time subvector arguments
4777 class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
4778  : public View< DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
4779  , private SubvectorData<CSAs...>
4780 {
4781  private:
4782  //**Type definitions****************************************************************************
4783  using CPE = DVecDVecCrossExpr<VT1,VT2,TF>;
4784  using RT = ResultType_<CPE>;
4785  using DataType = SubvectorData<CSAs...>;
4786  //**********************************************************************************************
4787 
4788  public:
4789  //**Type definitions****************************************************************************
4791  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
4792 
4793  using BaseType = DenseVector<This,TF>;
4794  using ViewedType = CPE;
4795  using ResultType = SubvectorTrait_<RT,CSAs...>;
4796  using TransposeType = TransposeType_<ResultType>;
4797  using ElementType = ElementType_<CPE>;
4798  using ReturnType = ReturnType_<CPE>;
4799  using CompositeType = const ResultType;
4800  //**********************************************************************************************
4801 
4802  //**Compilation flags***************************************************************************
4804  enum : bool { simdEnabled = false };
4805 
4807  enum : bool { smpAssignable = false };
4808  //**********************************************************************************************
4809 
4810  //**Constructor*********************************************************************************
4817  template< typename... RSAs > // Optional subvector arguments
4818  explicit inline Subvector( const CPE& vector, RSAs... args )
4819  : DataType( args... ) // Base class initialization
4820  , vector_ ( vector ) // The dense vector/dense vector cross product expression
4821  {
4822  if( Contains< TypeList<RSAs...>, Unchecked >::value ) {
4823  if( offset() + size() > vector.size() ) {
4824  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
4825  }
4826  }
4827  else {
4828  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
4829  }
4830  }
4831  //**********************************************************************************************
4832 
4833  //**Subscript operator**************************************************************************
4839  inline ReturnType operator[]( size_t index ) const {
4840  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4841  return vector_[offset()+index];
4842  }
4843  //**********************************************************************************************
4844 
4845  //**At function*********************************************************************************
4852  inline ReturnType at( size_t index ) const {
4853  if( index >= size() ) {
4854  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
4855  }
4856  return (*this)[index];
4857  }
4858  //**********************************************************************************************
4859 
4860  //**********************************************************************************************
4861  using DataType::offset;
4862  using DataType::size;
4863  //**********************************************************************************************
4864 
4865  //**Operand access******************************************************************************
4870  inline CPE operand() const noexcept {
4871  return vector_;
4872  }
4873  //**********************************************************************************************
4874 
4875  //**********************************************************************************************
4881  template< typename T >
4882  inline bool canAlias( const T* alias ) const noexcept {
4883  return vector_.canAlias( alias );
4884  }
4885  //**********************************************************************************************
4886 
4887  //**********************************************************************************************
4893  template< typename T >
4894  inline bool isAliased( const T* alias ) const noexcept {
4895  return vector_.isAliased( alias );
4896  }
4897  //**********************************************************************************************
4898 
4899  private:
4900  //**Member variables****************************************************************************
4901  CPE vector_;
4902  //**********************************************************************************************
4903 };
4905 //*************************************************************************************************
4906 
4907 
4908 
4909 
4910 
4911 
4912 
4913 
4914 //=================================================================================================
4915 //
4916 // CLASS TEMPLATE SPECIALIZATION FOR DVECSVECCROSSEXPR
4917 //
4918 //=================================================================================================
4919 
4920 //*************************************************************************************************
4928 template< typename VT1 // Type of the left-hand side dense vector
4929  , typename VT2 // Type of the right-hand side sparse vector
4930  , bool TF // Transpose flag
4931  , size_t... CSAs > // Compile time subvector arguments
4932 class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
4933  : public View< DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
4934  , private SubvectorData<CSAs...>
4935 {
4936  private:
4937  //**Type definitions****************************************************************************
4938  using CPE = DVecSVecCrossExpr<VT1,VT2,TF>;
4939  using RT = ResultType_<CPE>;
4940  using DataType = SubvectorData<CSAs...>;
4941  //**********************************************************************************************
4942 
4943  public:
4944  //**Type definitions****************************************************************************
4946  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
4947 
4948  using BaseType = DenseVector<This,TF>;
4949  using ViewedType = CPE;
4950  using ResultType = SubvectorTrait_<RT,CSAs...>;
4951  using TransposeType = TransposeType_<ResultType>;
4952  using ElementType = ElementType_<CPE>;
4953  using ReturnType = ReturnType_<CPE>;
4954  using CompositeType = const ResultType;
4955  //**********************************************************************************************
4956 
4957  //**Compilation flags***************************************************************************
4959  enum : bool { simdEnabled = false };
4960 
4962  enum : bool { smpAssignable = false };
4963  //**********************************************************************************************
4964 
4965  //**Constructor*********************************************************************************
4972  template< typename... RSAs > // Optional subvector arguments
4973  explicit inline Subvector( const CPE& vector, RSAs... args )
4974  : DataType( args... ) // Base class initialization
4975  , vector_ ( vector ) // The dense vector/sparse vector cross product expression
4976  {
4977  if( Contains< TypeList<RSAs...>, Unchecked >::value ) {
4978  if( offset() + size() > vector.size() ) {
4979  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
4980  }
4981  }
4982  else {
4983  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
4984  }
4985  }
4986  //**********************************************************************************************
4987 
4988  //**Subscript operator**************************************************************************
4994  inline ReturnType operator[]( size_t index ) const {
4995  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4996  return vector_[offset()+index];
4997  }
4998  //**********************************************************************************************
4999 
5000  //**At function*********************************************************************************
5007  inline ReturnType at( size_t index ) const {
5008  if( index >= size() ) {
5009  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5010  }
5011  return (*this)[index];
5012  }
5013  //**********************************************************************************************
5014 
5015  //**********************************************************************************************
5016  using DataType::offset;
5017  using DataType::size;
5018  //**********************************************************************************************
5019 
5020  //**Operand access******************************************************************************
5025  inline CPE operand() const noexcept {
5026  return vector_;
5027  }
5028  //**********************************************************************************************
5029 
5030  //**********************************************************************************************
5036  template< typename T >
5037  inline bool canAlias( const T* alias ) const noexcept {
5038  return vector_.canAlias( alias );
5039  }
5040  //**********************************************************************************************
5041 
5042  //**********************************************************************************************
5048  template< typename T >
5049  inline bool isAliased( const T* alias ) const noexcept {
5050  return vector_.isAliased( alias );
5051  }
5052  //**********************************************************************************************
5053 
5054  private:
5055  //**Member variables****************************************************************************
5056  CPE vector_;
5057  //**********************************************************************************************
5058 };
5060 //*************************************************************************************************
5061 
5062 
5063 
5064 
5065 
5066 
5067 
5068 
5069 //=================================================================================================
5070 //
5071 // CLASS TEMPLATE SPECIALIZATION FOR SVECDVECCROSSEXPR
5072 //
5073 //=================================================================================================
5074 
5075 //*************************************************************************************************
5083 template< typename VT1 // Type of the left-hand side sparse vector
5084  , typename VT2 // Type of the right-hand side dense vector
5085  , bool TF // Transpose flag
5086  , size_t... CSAs > // Compile time subvector arguments
5087 class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
5088  : public View< DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
5089  , private SubvectorData<CSAs...>
5090 {
5091  private:
5092  //**Type definitions****************************************************************************
5093  using CPE = SVecDVecCrossExpr<VT1,VT2,TF>;
5094  using RT = ResultType_<CPE>;
5095  using DataType = SubvectorData<CSAs...>;
5096  //**********************************************************************************************
5097 
5098  public:
5099  //**Type definitions****************************************************************************
5101  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
5102 
5103  using BaseType = DenseVector<This,TF>;
5104  using ViewedType = CPE;
5105  using ResultType = SubvectorTrait_<RT,CSAs...>;
5106  using TransposeType = TransposeType_<ResultType>;
5107  using ElementType = ElementType_<CPE>;
5108  using ReturnType = ReturnType_<CPE>;
5109  using CompositeType = const ResultType;
5110  //**********************************************************************************************
5111 
5112  //**Compilation flags***************************************************************************
5114  enum : bool { simdEnabled = false };
5115 
5117  enum : bool { smpAssignable = false };
5118  //**********************************************************************************************
5119 
5120  //**Constructor*********************************************************************************
5127  template< typename... RSAs > // Optional subvector arguments
5128  explicit inline Subvector( const CPE& vector, RSAs... args )
5129  : DataType( args... ) // Base class initialization
5130  , vector_ ( vector ) // The sparse vector/dense vector cross product expression
5131  {
5132  if( Contains< TypeList<RSAs...>, Unchecked >::value ) {
5133  if( offset() + size() > vector.size() ) {
5134  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
5135  }
5136  }
5137  else {
5138  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
5139  }
5140  }
5141  //**********************************************************************************************
5142 
5143  //**Subscript operator**************************************************************************
5149  inline ReturnType operator[]( size_t index ) const {
5150  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5151  return vector_[offset()+index];
5152  }
5153  //**********************************************************************************************
5154 
5155  //**At function*********************************************************************************
5162  inline ReturnType at( size_t index ) const {
5163  if( index >= size() ) {
5164  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5165  }
5166  return (*this)[index];
5167  }
5168  //**********************************************************************************************
5169 
5170  //**********************************************************************************************
5171  using DataType::offset;
5172  using DataType::size;
5173  //**********************************************************************************************
5174 
5175  //**Operand access******************************************************************************
5180  inline CPE operand() const noexcept {
5181  return vector_;
5182  }
5183  //**********************************************************************************************
5184 
5185  //**********************************************************************************************
5191  template< typename T >
5192  inline bool canAlias( const T* alias ) const noexcept {
5193  return vector_.canAlias( alias );
5194  }
5195  //**********************************************************************************************
5196 
5197  //**********************************************************************************************
5203  template< typename T >
5204  inline bool isAliased( const T* alias ) const noexcept {
5205  return vector_.isAliased( alias );
5206  }
5207  //**********************************************************************************************
5208 
5209  private:
5210  //**Member variables****************************************************************************
5211  CPE vector_;
5212  //**********************************************************************************************
5213 };
5215 //*************************************************************************************************
5216 
5217 
5218 
5219 
5220 
5221 
5222 
5223 
5224 //=================================================================================================
5225 //
5226 // CLASS TEMPLATE SPECIALIZATION FOR SVECSVECCROSSEXPR
5227 //
5228 //=================================================================================================
5229 
5230 //*************************************************************************************************
5238 template< typename VT1 // Type of the left-hand side sparse vector
5239  , typename VT2 // Type of the right-hand side sparse vector
5240  , bool TF // Transpose flag
5241  , size_t... CSAs > // Compile time subvector arguments
5242 class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
5243  : public View< DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
5244  , private SubvectorData<CSAs...>
5245 {
5246  private:
5247  //**Type definitions****************************************************************************
5248  using CPE = SVecSVecCrossExpr<VT1,VT2,TF>;
5249  using RT = ResultType_<CPE>;
5250  using DataType = SubvectorData<CSAs...>;
5251  //**********************************************************************************************
5252 
5253  public:
5254  //**Type definitions****************************************************************************
5256  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
5257 
5258  using BaseType = DenseVector<This,TF>;
5259  using ViewedType = CPE;
5260  using ResultType = SubvectorTrait_<RT,CSAs...>;
5261  using TransposeType = TransposeType_<ResultType>;
5262  using ElementType = ElementType_<CPE>;
5263  using ReturnType = ReturnType_<CPE>;
5264  using CompositeType = const ResultType;
5265  //**********************************************************************************************
5266 
5267  //**Compilation flags***************************************************************************
5269  enum : bool { simdEnabled = false };
5270 
5272  enum : bool { smpAssignable = false };
5273  //**********************************************************************************************
5274 
5275  //**Constructor*********************************************************************************
5282  template< typename... RSAs > // Optional subvector arguments
5283  explicit inline Subvector( const CPE& vector, RSAs... args )
5284  : DataType( args... ) // Base class initialization
5285  , vector_ ( vector ) // The sparse vector/sparse vector cross product expression
5286  {
5287  if( Contains< TypeList<RSAs...>, Unchecked >::value ) {
5288  if( offset() + size() > vector.size() ) {
5289  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
5290  }
5291  }
5292  else {
5293  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
5294  }
5295  }
5296  //**********************************************************************************************
5297 
5298  //**Subscript operator**************************************************************************
5304  inline ReturnType operator[]( size_t index ) const {
5305  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5306  return vector_[offset()+index];
5307  }
5308  //**********************************************************************************************
5309 
5310  //**At function*********************************************************************************
5317  inline ReturnType at( size_t index ) const {
5318  if( index >= size() ) {
5319  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5320  }
5321  return (*this)[index];
5322  }
5323  //**********************************************************************************************
5324 
5325  //**********************************************************************************************
5326  using DataType::offset;
5327  using DataType::size;
5328  //**********************************************************************************************
5329 
5330  //**Operand access******************************************************************************
5335  inline CPE operand() const noexcept {
5336  return vector_;
5337  }
5338  //**********************************************************************************************
5339 
5340  //**********************************************************************************************
5346  template< typename T >
5347  inline bool canAlias( const T* alias ) const noexcept {
5348  return vector_.canAlias( alias );
5349  }
5350  //**********************************************************************************************
5351 
5352  //**********************************************************************************************
5358  template< typename T >
5359  inline bool isAliased( const T* alias ) const {
5360  return vector_.isAliased( alias );
5361  }
5362  //**********************************************************************************************
5363 
5364  private:
5365  //**Member variables****************************************************************************
5366  CPE vector_;
5367  //**********************************************************************************************
5368 };
5370 //*************************************************************************************************
5371 
5372 } // namespace blaze
5373 
5374 #endif
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.Via these flags it is possible to specify subvec...
Definition: AlignmentFlag.h:62
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
Header file for the blaze::checked and blaze::unchecked instances.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the alignment flag values.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:522
Header file for basic type definitions.
Header file for the View base class.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:329
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3076
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:364
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3074
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:701
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3078
Header file for the DenseVector base class.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3083
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:560
Header file for the Computation base class.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:733
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3084
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
STL namespace.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:474
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:408
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:252
Constraint on the data type.
Header file for the DisableIf class template.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3082
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
Header file for the If class template.
Header file for the implementation of a vector representation of an initializer list.
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3079
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:367
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:443
Header file for the implementation of the Subvector base template.
Header file for the Not class template.
Header file for the implementation of the SubvectorData class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for the subvector trait.
Header file for all SIMD functionality.
Constraint on the data type.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:430
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:608
typename SubvectorTrait< VT, CSAs... >::Type SubvectorTrait_
Auxiliary alias declaration for the SubvectorTrait type trait.The SubvectorTrait_ alias declaration p...
Definition: SubvectorTrait.h:145
Header file for the CrossExpr base class.
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the cross product trait.
Header file for the Unique class template.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance...
Definition: Check.h:96
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
Header file for the cache size of the target architecture.
Header file for the isDefault shim.
Header file for the HasSIMDSub type trait.
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:405
Header file for the HasMutableDataAccess type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
BLAZE_ALWAYS_INLINE MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:169
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBVECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is a subvector type (i.e. a dense or sparse subvector), a compilation error is created.
Definition: Subvector.h:81
EnableIf_< IsNumeric< ST >, MT &> operator/=(DenseMatrix< MT, SO > &mat, ST scalar)
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:655
Header file for the HasSIMDDiv type trait.
Flag for unaligned vectors and matrices.
Definition: AlignmentFlag.h:64
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3081
Header file for the alignment check function.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
EnableIf_< IsNumeric< ST >, MT &> operator*=(DenseMatrix< MT, SO > &mat, ST scalar)
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:593
Header file for the IsRestricted type trait.
System settings for the inline keywords.
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the IsExpression type trait class.