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>
75 #include <blaze/math/views/Check.h>
78 #include <blaze/system/CacheSize.h>
79 #include <blaze/system/Inline.h>
83 #include <blaze/util/Assert.h>
85 #include <blaze/util/DisableIf.h>
86 #include <blaze/util/EnableIf.h>
87 #include <blaze/util/mpl/If.h>
88 #include <blaze/util/TypeList.h>
89 #include <blaze/util/Types.h>
91 
92 
93 namespace blaze {
94 
95 //=================================================================================================
96 //
97 // CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED DENSE SUBVECTORS
98 //
99 //=================================================================================================
100 
101 //*************************************************************************************************
109 template< typename VT // Type of the dense vector
110  , bool TF // Transpose flag
111  , size_t... CSAs > // Compile time subvector arguments
112 class Subvector<VT,unaligned,TF,true,CSAs...>
113  : public View< DenseVector< Subvector<VT,unaligned,TF,true,CSAs...>, TF > >
114  , private SubvectorData<CSAs...>
115 {
116  private:
117  //**Type definitions****************************************************************************
118  using DataType = SubvectorData<CSAs...>;
119  using Operand = If_t< IsExpression_v<VT>, VT, VT& >;
120  //**********************************************************************************************
121 
122  public:
123  //**Type definitions****************************************************************************
125  using This = Subvector<VT,unaligned,TF,true,CSAs...>;
126 
127  using BaseType = DenseVector<This,TF>;
128  using ViewedType = VT;
129  using ResultType = SubvectorTrait_t<VT,CSAs...>;
130  using TransposeType = TransposeType_t<ResultType>;
131  using ElementType = ElementType_t<VT>;
132  using SIMDType = SIMDTrait_t<ElementType>;
133  using ReturnType = ReturnType_t<VT>;
134  using CompositeType = const Subvector&;
135 
137  using ConstReference = ConstReference_t<VT>;
138 
140  using Reference = If_t< IsConst_v<VT>, ConstReference, Reference_t<VT> >;
141 
143  using ConstPointer = ConstPointer_t<VT>;
144 
146  using Pointer = If_t< IsConst_v<VT> || !HasMutableDataAccess_v<VT>, ConstPointer, Pointer_t<VT> >;
147  //**********************************************************************************************
148 
149  //**SubvectorIterator class definition**********************************************************
152  template< typename IteratorType > // Type of the dense vector iterator
153  class SubvectorIterator
154  {
155  public:
156  //**Type definitions*************************************************************************
158  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
159 
161  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
162 
164  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
165 
167  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
168 
170  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
171 
172  // STL iterator requirements
173  using iterator_category = IteratorCategory;
174  using value_type = ValueType;
175  using pointer = PointerType;
176  using reference = ReferenceType;
177  using difference_type = DifferenceType;
178  //*******************************************************************************************
179 
180  //**Constructor******************************************************************************
183  inline SubvectorIterator()
184  : iterator_ ( ) // Iterator to the current subvector element
185  , isAligned_( false ) // Memory alignment flag
186  {}
187  //*******************************************************************************************
188 
189  //**Constructor******************************************************************************
195  inline SubvectorIterator( IteratorType iterator, bool isMemoryAligned )
196  : iterator_ ( iterator ) // Iterator to the current subvector element
197  , isAligned_( isMemoryAligned ) // Memory alignment flag
198  {}
199  //*******************************************************************************************
200 
201  //**Constructor******************************************************************************
206  template< typename IteratorType2 >
207  inline SubvectorIterator( const SubvectorIterator<IteratorType2>& it )
208  : iterator_ ( it.base() ) // Iterator to the current subvector element
209  , isAligned_( it.isAligned() ) // Memory alignment flag
210  {}
211  //*******************************************************************************************
212 
213  //**Addition assignment operator*************************************************************
219  inline SubvectorIterator& operator+=( size_t inc ) {
220  iterator_ += inc;
221  return *this;
222  }
223  //*******************************************************************************************
224 
225  //**Subtraction assignment operator**********************************************************
231  inline SubvectorIterator& operator-=( size_t dec ) {
232  iterator_ -= dec;
233  return *this;
234  }
235  //*******************************************************************************************
236 
237  //**Prefix increment operator****************************************************************
242  inline SubvectorIterator& operator++() {
243  ++iterator_;
244  return *this;
245  }
246  //*******************************************************************************************
247 
248  //**Postfix increment operator***************************************************************
253  inline const SubvectorIterator operator++( int ) {
254  return SubvectorIterator( iterator_++, isAligned_ );
255  }
256  //*******************************************************************************************
257 
258  //**Prefix decrement operator****************************************************************
263  inline SubvectorIterator& operator--() {
264  --iterator_;
265  return *this;
266  }
267  //*******************************************************************************************
268 
269  //**Postfix decrement operator***************************************************************
274  inline const SubvectorIterator operator--( int ) {
275  return SubvectorIterator( iterator_--, isAligned_ );
276  }
277  //*******************************************************************************************
278 
279  //**Element access operator******************************************************************
284  inline ReferenceType operator*() const {
285  return *iterator_;
286  }
287  //*******************************************************************************************
288 
289  //**Element access operator******************************************************************
294  inline IteratorType operator->() const {
295  return iterator_;
296  }
297  //*******************************************************************************************
298 
299  //**Load function****************************************************************************
309  inline SIMDType load() const {
310  if( isAligned_ ) {
311  return loada();
312  }
313  else {
314  return loadu();
315  }
316  }
317  //*******************************************************************************************
318 
319  //**Loada function***************************************************************************
329  inline SIMDType loada() const {
330  return iterator_.loada();
331  }
332  //*******************************************************************************************
333 
334  //**Loadu function***************************************************************************
344  inline SIMDType loadu() const {
345  return iterator_.loadu();
346  }
347  //*******************************************************************************************
348 
349  //**Store function***************************************************************************
360  inline void store( const SIMDType& value ) const {
361  if( isAligned_ ) {
362  storea( value );
363  }
364  else {
365  storeu( value );
366  }
367  }
368  //*******************************************************************************************
369 
370  //**Storea function**************************************************************************
381  inline void storea( const SIMDType& value ) const {
382  iterator_.storea( value );
383  }
384  //*******************************************************************************************
385 
386  //**Storeu function**************************************************************************
397  inline void storeu( const SIMDType& value ) const {
398  iterator_.storeu( value );
399  }
400  //*******************************************************************************************
401 
402  //**Stream function**************************************************************************
413  inline void stream( const SIMDType& value ) const {
414  iterator_.stream( value );
415  }
416  //*******************************************************************************************
417 
418  //**Equality operator************************************************************************
424  inline bool operator==( const SubvectorIterator& rhs ) const {
425  return iterator_ == rhs.iterator_;
426  }
427  //*******************************************************************************************
428 
429  //**Inequality operator**********************************************************************
435  inline bool operator!=( const SubvectorIterator& rhs ) const {
436  return iterator_ != rhs.iterator_;
437  }
438  //*******************************************************************************************
439 
440  //**Less-than operator***********************************************************************
446  inline bool operator<( const SubvectorIterator& rhs ) const {
447  return iterator_ < rhs.iterator_;
448  }
449  //*******************************************************************************************
450 
451  //**Greater-than operator********************************************************************
457  inline bool operator>( const SubvectorIterator& rhs ) const {
458  return iterator_ > rhs.iterator_;
459  }
460  //*******************************************************************************************
461 
462  //**Less-or-equal-than operator**************************************************************
468  inline bool operator<=( const SubvectorIterator& rhs ) const {
469  return iterator_ <= rhs.iterator_;
470  }
471  //*******************************************************************************************
472 
473  //**Greater-or-equal-than operator***********************************************************
479  inline bool operator>=( const SubvectorIterator& rhs ) const {
480  return iterator_ >= rhs.iterator_;
481  }
482  //*******************************************************************************************
483 
484  //**Subtraction operator*********************************************************************
490  inline DifferenceType operator-( const SubvectorIterator& rhs ) const {
491  return iterator_ - rhs.iterator_;
492  }
493  //*******************************************************************************************
494 
495  //**Addition operator************************************************************************
502  friend inline const SubvectorIterator operator+( const SubvectorIterator& it, size_t inc ) {
503  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
504  }
505  //*******************************************************************************************
506 
507  //**Addition operator************************************************************************
514  friend inline const SubvectorIterator operator+( size_t inc, const SubvectorIterator& it ) {
515  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
516  }
517  //*******************************************************************************************
518 
519  //**Subtraction operator*********************************************************************
526  friend inline const SubvectorIterator operator-( const SubvectorIterator& it, size_t dec ) {
527  return SubvectorIterator( it.iterator_ - dec, it.isAligned_ );
528  }
529  //*******************************************************************************************
530 
531  //**Base function****************************************************************************
536  inline IteratorType base() const {
537  return iterator_;
538  }
539  //*******************************************************************************************
540 
541  //**IsAligned function***********************************************************************
546  inline bool isAligned() const {
547  return isAligned_;
548  }
549  //*******************************************************************************************
550 
551  private:
552  //**Member variables*************************************************************************
553  IteratorType iterator_;
554  bool isAligned_;
555  //*******************************************************************************************
556  };
557  //**********************************************************************************************
558 
559  //**Type definitions****************************************************************************
561  using ConstIterator = SubvectorIterator< ConstIterator_t<VT> >;
562 
564  using Iterator = If_t< IsConst_v<VT>, ConstIterator, SubvectorIterator< Iterator_t<VT> > >;
565  //**********************************************************************************************
566 
567  //**Compilation flags***************************************************************************
569  static constexpr bool simdEnabled = VT::simdEnabled;
570 
572  static constexpr bool smpAssignable = VT::smpAssignable;
573  //**********************************************************************************************
574 
575  //**Constructors********************************************************************************
578  template< typename... RSAs >
579  explicit inline Subvector( VT& vector, RSAs... args );
580 
581  Subvector( const Subvector& ) = default;
583  //**********************************************************************************************
584 
585  //**Destructor**********************************************************************************
588  ~Subvector() = default;
590  //**********************************************************************************************
591 
592  //**Data access functions***********************************************************************
595  inline Reference operator[]( size_t index );
596  inline ConstReference operator[]( size_t index ) const;
597  inline Reference at( size_t index );
598  inline ConstReference at( size_t index ) const;
599  inline Pointer data () noexcept;
600  inline ConstPointer data () const noexcept;
601  inline Iterator begin ();
602  inline ConstIterator begin () const;
603  inline ConstIterator cbegin() const;
604  inline Iterator end ();
605  inline ConstIterator end () const;
606  inline ConstIterator cend () const;
608  //**********************************************************************************************
609 
610  //**Assignment operators************************************************************************
613  inline Subvector& operator= ( const ElementType& rhs );
614  inline Subvector& operator= ( initializer_list<ElementType> list );
615  inline Subvector& operator= ( const Subvector& 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 Vector<VT2,TF>& rhs );
619  template< typename VT2 > inline Subvector& operator*=( const Vector<VT2,TF>& rhs );
620  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
621  template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
623  //**********************************************************************************************
624 
625  //**Utility functions***************************************************************************
628  using DataType::offset;
629  using DataType::size;
630 
631  inline VT& operand() noexcept;
632  inline const VT& operand() const noexcept;
633 
634  inline size_t spacing() const noexcept;
635  inline size_t capacity() const noexcept;
636  inline size_t nonZeros() const;
637  inline void reset();
639  //**********************************************************************************************
640 
641  //**Numeric functions***************************************************************************
644  template< typename Other > inline Subvector& scale( const Other& scalar );
646  //**********************************************************************************************
647 
648  private:
649  //**********************************************************************************************
651  template< typename VT2 >
652  static constexpr bool VectorizedAssign_v =
653  ( useOptimizedKernels &&
654  simdEnabled && VT2::simdEnabled &&
656  //**********************************************************************************************
657 
658  //**********************************************************************************************
660  template< typename VT2 >
661  static constexpr bool VectorizedAddAssign_v =
662  ( useOptimizedKernels &&
663  simdEnabled && VT2::simdEnabled &&
666  //**********************************************************************************************
667 
668  //**********************************************************************************************
670  template< typename VT2 >
671  static constexpr bool VectorizedSubAssign_v =
672  ( useOptimizedKernels &&
673  simdEnabled && VT2::simdEnabled &&
676  //**********************************************************************************************
677 
678  //**********************************************************************************************
680  template< typename VT2 >
681  static constexpr bool VectorizedMultAssign_v =
682  ( useOptimizedKernels &&
683  simdEnabled && VT2::simdEnabled &&
686  //**********************************************************************************************
687 
688  //**********************************************************************************************
690  template< typename VT2 >
691  static constexpr bool VectorizedDivAssign_v =
692  ( useOptimizedKernels &&
693  simdEnabled && VT2::simdEnabled &&
696  //**********************************************************************************************
697 
698  //**SIMD properties*****************************************************************************
700  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
701  //**********************************************************************************************
702 
703  public:
704  //**Expression template evaluation functions****************************************************
707  template< typename Other >
708  inline bool canAlias( const Other* alias ) const noexcept;
709 
710  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
711  inline bool canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
712 
713  template< typename Other >
714  inline bool isAliased( const Other* alias ) const noexcept;
715 
716  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
717  inline bool isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
718 
719  inline bool isAligned () const noexcept;
720  inline bool canSMPAssign() const noexcept;
721 
722  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
723  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
724  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
725 
726  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
727  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
728  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
729  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
730 
731  template< typename VT2 >
732  inline auto assign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT2> >;
733 
734  template< typename VT2 >
735  inline auto assign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT2> >;
736 
737  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
738 
739  template< typename VT2 >
740  inline auto addAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT2> >;
741 
742  template< typename VT2 >
743  inline auto addAssign ( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT2> >;
744 
745  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
746 
747  template< typename VT2 >
748  inline auto subAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT2> >;
749 
750  template< typename VT2 >
751  inline auto subAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT2> >;
752 
753  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
754 
755  template< typename VT2 >
756  inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT2> >;
757 
758  template< typename VT2 >
759  inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT2> >;
760 
761  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
762 
763  template< typename VT2 >
764  inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT2> >;
765 
766  template< typename VT2 >
767  inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT2> >;
769  //**********************************************************************************************
770 
771  private:
772  //**Member variables****************************************************************************
775  Operand vector_;
776  const bool isAligned_;
777 
784  //**********************************************************************************************
785 
786  //**Friend declarations*************************************************************************
787  template< typename VT2, AlignmentFlag AF2, bool TF2, bool DF2, size_t... CSAs2 > friend class Subvector;
788  //**********************************************************************************************
789 
790  //**Compile time checks*************************************************************************
796  //**********************************************************************************************
797 };
799 //*************************************************************************************************
800 
801 
802 
803 
804 //=================================================================================================
805 //
806 // CONSTRUCTORS
807 //
808 //=================================================================================================
809 
810 //*************************************************************************************************
824 template< typename VT // Type of the dense vector
825  , bool TF // Transpose flag
826  , size_t... CSAs > // Compile time subvector arguments
827 template< typename... RSAs > // Runtime subvector arguments
828 inline Subvector<VT,unaligned,TF,true,CSAs...>::Subvector( VT& vector, RSAs... args )
829  : DataType ( args... ) // Base class initialization
830  , vector_ ( vector ) // The vector containing the subvector
831  , isAligned_( simdEnabled && IsContiguous_v<VT> &&
832  vector.data() != nullptr && checkAlignment( data() ) )
833 {
834  if( !Contains_v< TypeList<RSAs...>, Unchecked > ) {
835  if( offset() + size() > vector.size() ) {
836  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
837  }
838  }
839  else {
840  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
841  }
842 }
844 //*************************************************************************************************
845 
846 
847 
848 
849 //=================================================================================================
850 //
851 // DATA ACCESS FUNCTIONS
852 //
853 //=================================================================================================
854 
855 //*************************************************************************************************
865 template< typename VT // Type of the dense vector
866  , bool TF // Transpose flag
867  , size_t... CSAs > // Compile time subvector arguments
868 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Reference
869  Subvector<VT,unaligned,TF,true,CSAs...>::operator[]( size_t index )
870 {
871  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
872  return vector_[offset()+index];
873 }
875 //*************************************************************************************************
876 
877 
878 //*************************************************************************************************
888 template< typename VT // Type of the dense vector
889  , bool TF // Transpose flag
890  , size_t... CSAs > // Compile time subvector arguments
891 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstReference
892  Subvector<VT,unaligned,TF,true,CSAs...>::operator[]( size_t index ) const
893 {
894  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
895  return const_cast<const VT&>( vector_ )[offset()+index];
896 }
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
912 template< typename VT // Type of the dense vector
913  , bool TF // Transpose flag
914  , size_t... CSAs > // Compile time subvector arguments
915 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Reference
916  Subvector<VT,unaligned,TF,true,CSAs...>::at( size_t index )
917 {
918  if( index >= size() ) {
919  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
920  }
921  return (*this)[index];
922 }
924 //*************************************************************************************************
925 
926 
927 //*************************************************************************************************
938 template< typename VT // Type of the dense vector
939  , bool TF // Transpose flag
940  , size_t... CSAs > // Compile time subvector arguments
941 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstReference
942  Subvector<VT,unaligned,TF,true,CSAs...>::at( size_t index ) const
943 {
944  if( index >= size() ) {
945  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
946  }
947  return (*this)[index];
948 }
950 //*************************************************************************************************
951 
952 
953 //*************************************************************************************************
961 template< typename VT // Type of the dense vector
962  , bool TF // Transpose flag
963  , size_t... CSAs > // Compile time subvector arguments
964 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Pointer
966 {
967  return vector_.data() + offset();
968 }
970 //*************************************************************************************************
971 
972 
973 //*************************************************************************************************
981 template< typename VT // Type of the dense vector
982  , bool TF // Transpose flag
983  , size_t... CSAs > // Compile time subvector arguments
984 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstPointer
986 {
987  return vector_.data() + offset();
988 }
990 //*************************************************************************************************
991 
992 
993 //*************************************************************************************************
1001 template< typename VT // Type of the dense vector
1002  , bool TF // Transpose flag
1003  , size_t... CSAs > // Compile time subvector arguments
1004 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Iterator
1006 {
1007  return Iterator( vector_.begin() + offset(), isAligned_ );
1008 }
1010 //*************************************************************************************************
1011 
1012 
1013 //*************************************************************************************************
1021 template< typename VT // Type of the dense vector
1022  , bool TF // Transpose flag
1023  , size_t... CSAs > // Compile time subvector arguments
1024 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1026 {
1027  return ConstIterator( vector_.cbegin() + offset(), isAligned_ );
1028 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1041 template< typename VT // Type of the dense vector
1042  , bool TF // Transpose flag
1043  , size_t... CSAs > // Compile time subvector arguments
1044 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1046 {
1047  return ConstIterator( vector_.cbegin() + offset(), isAligned_ );
1048 }
1050 //*************************************************************************************************
1051 
1052 
1053 //*************************************************************************************************
1061 template< typename VT // Type of the dense vector
1062  , bool TF // Transpose flag
1063  , size_t... CSAs > // Compile time subvector arguments
1064 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Iterator
1066 {
1067  return Iterator( vector_.begin() + offset() + size(), isAligned_ );
1068 }
1070 //*************************************************************************************************
1071 
1072 
1073 //*************************************************************************************************
1081 template< typename VT // Type of the dense vector
1082  , bool TF // Transpose flag
1083  , size_t... CSAs > // Compile time subvector arguments
1084 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1086 {
1087  return ConstIterator( vector_.cbegin() + offset() + size(), isAligned_ );
1088 }
1090 //*************************************************************************************************
1091 
1092 
1093 //*************************************************************************************************
1101 template< typename VT // Type of the dense vector
1102  , bool TF // Transpose flag
1103  , size_t... CSAs > // Compile time subvector arguments
1104 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1106 {
1107  return ConstIterator( vector_.cbegin() + offset() + size(), isAligned_ );
1108 }
1110 //*************************************************************************************************
1111 
1112 
1113 
1114 
1115 //=================================================================================================
1116 //
1117 // ASSIGNMENT OPERATORS
1118 //
1119 //=================================================================================================
1120 
1121 //*************************************************************************************************
1128 template< typename VT // Type of the dense vector
1129  , bool TF // Transpose flag
1130  , size_t... CSAs > // Compile time subvector arguments
1131 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1132  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const ElementType& rhs )
1133 {
1134  const size_t iend( offset() + size() );
1135  decltype(auto) left( derestrict( vector_ ) );
1136 
1137  for( size_t i=offset(); i<iend; ++i ) {
1138  if( !IsRestricted_v<VT> || trySet( vector_, i, rhs ) )
1139  left[i] = rhs;
1140  }
1141 
1142  return *this;
1143 }
1145 //*************************************************************************************************
1146 
1147 
1148 //*************************************************************************************************
1164 template< typename VT // Type of the dense vector
1165  , bool TF // Transpose flag
1166  , size_t... CSAs > // Compile time subvector arguments
1167 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1168  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( initializer_list<ElementType> list )
1169 {
1170  if( list.size() > size() ) {
1171  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
1172  }
1173 
1174  if( IsRestricted_v<VT> ) {
1175  const InitializerVector<ElementType,TF> tmp( list, size() );
1176  if( !tryAssign( vector_, tmp, offset() ) ) {
1177  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1178  }
1179  }
1180 
1181  decltype(auto) left( derestrict( *this ) );
1182 
1183  std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
1184 
1185  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1186 
1187  return *this;
1188 }
1190 //*************************************************************************************************
1191 
1192 
1193 //*************************************************************************************************
1205 template< typename VT // Type of the dense vector
1206  , bool TF // Transpose flag
1207  , size_t... CSAs > // Compile time subvector arguments
1208 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1209  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const Subvector& rhs )
1210 {
1213 
1214  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset() == rhs.offset() ) )
1215  return *this;
1216 
1217  if( size() != rhs.size() ) {
1218  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
1219  }
1220 
1221  if( !tryAssign( vector_, rhs, offset() ) ) {
1222  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1223  }
1224 
1225  decltype(auto) left( derestrict( *this ) );
1226 
1227  if( rhs.canAlias( &vector_ ) ) {
1228  const ResultType tmp( rhs );
1229  smpAssign( left, tmp );
1230  }
1231  else {
1232  smpAssign( left, rhs );
1233  }
1234 
1235  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1236 
1237  return *this;
1238 }
1240 //*************************************************************************************************
1241 
1242 
1243 //*************************************************************************************************
1255 template< typename VT // Type of the dense vector
1256  , bool TF // Transpose flag
1257  , size_t... CSAs > // Compile time subvector arguments
1258 template< typename VT2 > // Type of the right-hand side vector
1259 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1260  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const Vector<VT2,TF>& rhs )
1261 {
1262  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1263  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1264 
1265  if( size() != (~rhs).size() ) {
1266  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1267  }
1268 
1269  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1270  Right right( ~rhs );
1271 
1272  if( !tryAssign( vector_, right, offset() ) ) {
1273  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1274  }
1275 
1276  decltype(auto) left( derestrict( *this ) );
1277 
1278  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1279  const ResultType_t<VT2> tmp( right );
1280  smpAssign( left, tmp );
1281  }
1282  else {
1283  if( IsSparseVector_v<VT2> )
1284  reset();
1285  smpAssign( left, right );
1286  }
1287 
1288  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1289 
1290  return *this;
1291 }
1293 //*************************************************************************************************
1294 
1295 
1296 //*************************************************************************************************
1308 template< typename VT // Type of the dense vector
1309  , bool TF // Transpose flag
1310  , size_t... CSAs > // Compile time subvector arguments
1311 template< typename VT2 > // Type of the right-hand side vector
1312 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1313  Subvector<VT,unaligned,TF,true,CSAs...>::operator+=( const Vector<VT2,TF>& rhs )
1314 {
1315  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1316  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1317 
1318  if( size() != (~rhs).size() ) {
1319  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1320  }
1321 
1322  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1323  Right right( ~rhs );
1324 
1325  if( !tryAddAssign( vector_, right, offset() ) ) {
1326  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1327  }
1328 
1329  decltype(auto) left( derestrict( *this ) );
1330 
1331  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1332  const ResultType_t<VT2> tmp( right );
1333  smpAddAssign( left, tmp );
1334  }
1335  else {
1336  smpAddAssign( left, right );
1337  }
1338 
1339  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1340 
1341  return *this;
1342 }
1344 //*************************************************************************************************
1345 
1346 
1347 //*************************************************************************************************
1359 template< typename VT // Type of the dense vector
1360  , bool TF // Transpose flag
1361  , size_t... CSAs > // Compile time subvector arguments
1362 template< typename VT2 > // Type of the right-hand side vector
1363 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1364  Subvector<VT,unaligned,TF,true,CSAs...>::operator-=( const Vector<VT2,TF>& rhs )
1365 {
1366  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1367  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1368 
1369  if( size() != (~rhs).size() ) {
1370  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1371  }
1372 
1373  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1374  Right right( ~rhs );
1375 
1376  if( !trySubAssign( vector_, right, offset() ) ) {
1377  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1378  }
1379 
1380  decltype(auto) left( derestrict( *this ) );
1381 
1382  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1383  const ResultType_t<VT2> tmp( right );
1384  smpSubAssign( left, tmp );
1385  }
1386  else {
1387  smpSubAssign( left, right );
1388  }
1389 
1390  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1391 
1392  return *this;
1393 }
1395 //*************************************************************************************************
1396 
1397 
1398 //*************************************************************************************************
1411 template< typename VT // Type of the dense vector
1412  , bool TF // Transpose flag
1413  , size_t... CSAs > // Compile time subvector arguments
1414 template< typename VT2 > // Type of the right-hand side vector
1415 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1416  Subvector<VT,unaligned,TF,true,CSAs...>::operator*=( const Vector<VT2,TF>& rhs )
1417 {
1418  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1419  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1420 
1421  if( size() != (~rhs).size() ) {
1422  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1423  }
1424 
1425  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1426  Right right( ~rhs );
1427 
1428  if( !tryMultAssign( vector_, right, offset() ) ) {
1429  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1430  }
1431 
1432  decltype(auto) left( derestrict( *this ) );
1433 
1434  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1435  const ResultType_t<VT2> tmp( right );
1436  smpMultAssign( left, tmp );
1437  }
1438  else {
1439  smpMultAssign( left, right );
1440  }
1441 
1442  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1443 
1444  return *this;
1445 }
1447 //*************************************************************************************************
1448 
1449 
1450 //*************************************************************************************************
1462 template< typename VT // Type of the dense vector
1463  , bool TF // Transpose flag
1464  , size_t... CSAs > // Compile time subvector arguments
1465 template< typename VT2 > // Type of the right-hand side dense vector
1466 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1467  Subvector<VT,unaligned,TF,true,CSAs...>::operator/=( const DenseVector<VT2,TF>& rhs )
1468 {
1469  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1470  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1471 
1472  if( size() != (~rhs).size() ) {
1473  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1474  }
1475 
1476  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1477  Right right( ~rhs );
1478 
1479  if( !tryDivAssign( vector_, right, offset() ) ) {
1480  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1481  }
1482 
1483  decltype(auto) left( derestrict( *this ) );
1484 
1485  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1486  const ResultType_t<VT2> tmp( right );
1487  smpDivAssign( left, tmp );
1488  }
1489  else {
1490  smpDivAssign( left, right );
1491  }
1492 
1493  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1494 
1495  return *this;
1496 }
1498 //*************************************************************************************************
1499 
1500 
1501 //*************************************************************************************************
1514 template< typename VT // Type of the dense vector
1515  , bool TF // Transpose flag
1516  , size_t... CSAs > // Compile time subvector arguments
1517 template< typename VT2 > // Type of the right-hand side vector
1518 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1519  Subvector<VT,unaligned,TF,true,CSAs...>::operator%=( const Vector<VT2,TF>& rhs )
1520 {
1521  using blaze::assign;
1522 
1523  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1524  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1525 
1526  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT2> >;
1527 
1531 
1532  if( size() != 3UL || (~rhs).size() != 3UL ) {
1533  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1534  }
1535 
1536  const CrossType tmp( *this % (~rhs) );
1537 
1538  if( !tryAssign( vector_, tmp, offset() ) ) {
1539  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1540  }
1541 
1542  decltype(auto) left( derestrict( *this ) );
1543 
1544  assign( left, tmp );
1545 
1546  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1547 
1548  return *this;
1549 }
1551 //*************************************************************************************************
1552 
1553 
1554 
1555 
1556 //=================================================================================================
1557 //
1558 // UTILITY FUNCTIONS
1559 //
1560 //=================================================================================================
1561 
1562 //*************************************************************************************************
1568 template< typename VT // Type of the dense vector
1569  , bool TF // Transpose flag
1570  , size_t... CSAs > // Compile time subvector arguments
1571 inline VT& Subvector<VT,unaligned,TF,true,CSAs...>::operand() noexcept
1572 {
1573  return vector_;
1574 }
1576 //*************************************************************************************************
1577 
1578 
1579 //*************************************************************************************************
1585 template< typename VT // Type of the dense vector
1586  , bool TF // Transpose flag
1587  , size_t... CSAs > // Compile time subvector arguments
1588 inline const VT& Subvector<VT,unaligned,TF,true,CSAs...>::operand() const noexcept
1589 {
1590  return vector_;
1591 }
1593 //*************************************************************************************************
1594 
1595 
1596 //*************************************************************************************************
1605 template< typename VT // Type of the dense vector
1606  , bool TF // Transpose flag
1607  , size_t... CSAs > // Compile time subvector arguments
1608 inline size_t Subvector<VT,unaligned,TF,true,CSAs...>::spacing() const noexcept
1609 {
1610  return vector_.spacing() - offset();
1611 }
1613 //*************************************************************************************************
1614 
1615 
1616 //*************************************************************************************************
1622 template< typename VT // Type of the dense vector
1623  , bool TF // Transpose flag
1624  , size_t... CSAs > // Compile time subvector arguments
1625 inline size_t Subvector<VT,unaligned,TF,true,CSAs...>::capacity() const noexcept
1626 {
1627  return vector_.capacity() - offset();
1628 }
1630 //*************************************************************************************************
1631 
1632 
1633 //*************************************************************************************************
1642 template< typename VT // Type of the dense vector
1643  , bool TF // Transpose flag
1644  , size_t... CSAs > // Compile time subvector arguments
1646 {
1647  size_t nonzeros( 0 );
1648 
1649  const size_t iend( offset() + size() );
1650  for( size_t i=offset(); i<iend; ++i ) {
1651  if( !isDefault( vector_[i] ) )
1652  ++nonzeros;
1653  }
1654 
1655  return nonzeros;
1656 }
1658 //*************************************************************************************************
1659 
1660 
1661 //*************************************************************************************************
1667 template< typename VT // Type of the dense vector
1668  , bool TF // Transpose flag
1669  , size_t... CSAs > // Compile time subvector arguments
1671 {
1672  using blaze::clear;
1673 
1674  const size_t iend( offset() + size() );
1675  for( size_t i=offset(); i<iend; ++i )
1676  clear( vector_[i] );
1677 }
1679 //*************************************************************************************************
1680 
1681 
1682 
1683 
1684 //=================================================================================================
1685 //
1686 // NUMERIC FUNCTIONS
1687 //
1688 //=================================================================================================
1689 
1690 //*************************************************************************************************
1701 template< typename VT // Type of the dense vector
1702  , bool TF // Transpose flag
1703  , size_t... CSAs > // Compile time subvector arguments
1704 template< typename Other > // Data type of the scalar value
1705 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1706  Subvector<VT,unaligned,TF,true,CSAs...>::scale( const Other& scalar )
1707 {
1708  const size_t iend( offset() + size() );
1709  for( size_t i=offset(); i<iend; ++i )
1710  vector_[i] *= scalar;
1711  return *this;
1712 }
1714 //*************************************************************************************************
1715 
1716 
1717 
1718 
1719 //=================================================================================================
1720 //
1721 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1722 //
1723 //=================================================================================================
1724 
1725 //*************************************************************************************************
1736 template< typename VT // Type of the dense vector
1737  , bool TF // Transpose flag
1738  , size_t... CSAs > // Compile time subvector arguments
1739 template< typename Other > // Data type of the foreign expression
1740 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::canAlias( const Other* alias ) const noexcept
1741 {
1742  return vector_.isAliased( alias );
1743 }
1745 //*************************************************************************************************
1746 
1747 
1748 //*************************************************************************************************
1759 template< typename VT // Type of the dense vector
1760  , bool TF // Transpose flag
1761  , size_t... CSAs > // Compile time subvector arguments
1762 template< typename VT2 // Data type of the foreign dense subvector
1763  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
1764  , bool TF2 // Transpose flag of the foreign dense subvector
1765  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
1766 inline bool
1767  Subvector<VT,unaligned,TF,true,CSAs...>::canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
1768 {
1769  return ( vector_.isAliased( &alias->vector_ ) &&
1770  ( offset() + size() > alias->offset() ) &&
1771  ( offset() < alias->offset() + alias->size() ) );
1772 }
1774 //*************************************************************************************************
1775 
1776 
1777 //*************************************************************************************************
1788 template< typename VT // Type of the dense vector
1789  , bool TF // Transpose flag
1790  , size_t... CSAs > // Compile time subvector arguments
1791 template< typename Other > // Data type of the foreign expression
1792 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::isAliased( const Other* alias ) const noexcept
1793 {
1794  return vector_.isAliased( alias );
1795 }
1797 //*************************************************************************************************
1798 
1799 
1800 //*************************************************************************************************
1811 template< typename VT // Type of the dense vector
1812  , bool TF // Transpose flag
1813  , size_t... CSAs > // Compile time subvector arguments
1814 template< typename VT2 // Data type of the foreign dense subvector
1815  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
1816  , bool TF2 // Transpose flag of the foreign dense subvector
1817  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
1818 inline bool
1819  Subvector<VT,unaligned,TF,true,CSAs...>::isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
1820 {
1821  return ( vector_.isAliased( &alias->vector_ ) &&
1822  ( offset() + size() > alias->offset() ) &&
1823  ( offset() < alias->offset() + alias->size() ) );
1824 }
1826 //*************************************************************************************************
1827 
1828 
1829 //*************************************************************************************************
1839 template< typename VT // Type of the dense vector
1840  , bool TF // Transpose flag
1841  , size_t... CSAs > // Compile time subvector arguments
1842 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::isAligned() const noexcept
1843 {
1844  return isAligned_;
1845 }
1847 //*************************************************************************************************
1848 
1849 
1850 //*************************************************************************************************
1861 template< typename VT // Type of the dense vector
1862  , bool TF // Transpose flag
1863  , size_t... CSAs > // Compile time subvector arguments
1864 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::canSMPAssign() const noexcept
1865 {
1866  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1867 }
1869 //*************************************************************************************************
1870 
1871 
1872 //*************************************************************************************************
1886 template< typename VT // Type of the dense vector
1887  , bool TF // Transpose flag
1888  , size_t... CSAs > // Compile time subvector arguments
1889 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1890  Subvector<VT,unaligned,TF,true,CSAs...>::load( size_t index ) const noexcept
1891 {
1892  if( isAligned_ )
1893  return loada( index );
1894  else
1895  return loadu( index );
1896 }
1898 //*************************************************************************************************
1899 
1900 
1901 //*************************************************************************************************
1915 template< typename VT // Type of the dense vector
1916  , bool TF // Transpose flag
1917  , size_t... CSAs > // Compile time subvector arguments
1918 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1919  Subvector<VT,unaligned,TF,true,CSAs...>::loada( size_t index ) const noexcept
1920 {
1922 
1923  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1924  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1925  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1926 
1927  return vector_.loada( offset()+index );
1928 }
1930 //*************************************************************************************************
1931 
1932 
1933 //*************************************************************************************************
1947 template< typename VT // Type of the dense vector
1948  , bool TF // Transpose flag
1949  , size_t... CSAs > // Compile time subvector arguments
1950 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1951  Subvector<VT,unaligned,TF,true,CSAs...>::loadu( size_t index ) const noexcept
1952 {
1954 
1955  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1956  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1957  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1958 
1959  return vector_.loadu( offset()+index );
1960 }
1962 //*************************************************************************************************
1963 
1964 
1965 //*************************************************************************************************
1980 template< typename VT // Type of the dense vector
1981  , bool TF // Transpose flag
1982  , size_t... CSAs > // Compile time subvector arguments
1984  Subvector<VT,unaligned,TF,true,CSAs...>::store( size_t index, const SIMDType& value ) noexcept
1985 {
1986  if( isAligned_ )
1987  storea( index, value );
1988  else
1989  storeu( index, value );
1990 }
1992 //*************************************************************************************************
1993 
1994 
1995 //*************************************************************************************************
2010 template< typename VT // Type of the dense vector
2011  , bool TF // Transpose flag
2012  , size_t... CSAs > // Compile time subvector arguments
2014  Subvector<VT,unaligned,TF,true,CSAs...>::storea( size_t index, const SIMDType& value ) noexcept
2015 {
2017 
2018  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2019  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2020  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2021 
2022  vector_.storea( offset()+index, value );
2023 }
2025 //*************************************************************************************************
2026 
2027 
2028 //*************************************************************************************************
2043 template< typename VT // Type of the dense vector
2044  , bool TF // Transpose flag
2045  , size_t... CSAs > // Compile time subvector arguments
2047  Subvector<VT,unaligned,TF,true,CSAs...>::storeu( size_t index, const SIMDType& value ) noexcept
2048 {
2050 
2051  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2052  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2053  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2054 
2055  vector_.storeu( offset()+index, value );
2056 }
2058 //*************************************************************************************************
2059 
2060 
2061 //*************************************************************************************************
2076 template< typename VT // Type of the dense vector
2077  , bool TF // Transpose flag
2078  , size_t... CSAs > // Compile time subvector arguments
2080  Subvector<VT,unaligned,TF,true,CSAs...>::stream( size_t index, const SIMDType& value ) noexcept
2081 {
2083 
2084  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2085  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2086  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2087 
2088  if( isAligned_ )
2089  vector_.stream( offset()+index, value );
2090  else
2091  vector_.storeu( offset()+index, value );
2092 }
2094 //*************************************************************************************************
2095 
2096 
2097 //*************************************************************************************************
2109 template< typename VT // Type of the dense vector
2110  , bool TF // Transpose flag
2111  , size_t... CSAs > // Compile time subvector arguments
2112 template< typename VT2 > // Type of the right-hand side dense vector
2113 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
2114  -> DisableIf_t< VectorizedAssign_v<VT2> >
2115 {
2116  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2117 
2118  const size_t ipos( size() & size_t(-2) );
2119  for( size_t i=0UL; i<ipos; i+=2UL ) {
2120  vector_[offset()+i ] = (~rhs)[i ];
2121  vector_[offset()+i+1UL] = (~rhs)[i+1UL];
2122  }
2123  if( ipos < size() ) {
2124  vector_[offset()+ipos] = (~rhs)[ipos];
2125  }
2126 }
2128 //*************************************************************************************************
2129 
2130 
2131 //*************************************************************************************************
2143 template< typename VT // Type of the dense vector
2144  , bool TF // Transpose flag
2145  , size_t... CSAs > // Compile time subvector arguments
2146 template< typename VT2 > // Type of the right-hand side dense vector
2147 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
2148  -> EnableIf_t< VectorizedAssign_v<VT2> >
2149 {
2151 
2152  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2153 
2154  const size_t ipos( size() & size_t(-SIMDSIZE) );
2155  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2156 
2157  size_t i( 0UL );
2158  Iterator left( begin() );
2159  ConstIterator_t<VT2> right( (~rhs).begin() );
2160 
2161  if( useStreaming && isAligned_ &&
2162  ( size() > ( cacheSize/( sizeof(ElementType) * 3UL ) ) ) &&
2163  !(~rhs).isAliased( &vector_ ) )
2164  {
2165  for( ; i<ipos; i+=SIMDSIZE ) {
2166  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2167  }
2168  for( ; i<size(); ++i ) {
2169  *left = *right;
2170  }
2171  }
2172  else
2173  {
2174  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2175  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2176  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2177  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2178  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2179  }
2180  for( ; i<ipos; i+=SIMDSIZE ) {
2181  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2182  }
2183  for( ; i<size(); ++i ) {
2184  *left = *right; ++left; ++right;
2185  }
2186  }
2187 }
2189 //*************************************************************************************************
2190 
2191 
2192 //*************************************************************************************************
2204 template< typename VT // Type of the dense vector
2205  , bool TF // Transpose flag
2206  , size_t... CSAs > // Compile time subvector arguments
2207 template< typename VT2 > // Type of the right-hand side sparse vector
2208 inline void Subvector<VT,unaligned,TF,true,CSAs...>::assign( const SparseVector<VT2,TF>& rhs )
2209 {
2210  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2211 
2212  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2213  vector_[offset()+element->index()] = element->value();
2214 }
2216 //*************************************************************************************************
2217 
2218 
2219 //*************************************************************************************************
2231 template< typename VT // Type of the dense vector
2232  , bool TF // Transpose flag
2233  , size_t... CSAs > // Compile time subvector arguments
2234 template< typename VT2 > // Type of the right-hand side dense vector
2235 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
2236  -> DisableIf_t< VectorizedAddAssign_v<VT2> >
2237 {
2238  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2239 
2240  const size_t ipos( size() & size_t(-2) );
2241  for( size_t i=0UL; i<ipos; i+=2UL ) {
2242  vector_[offset()+i ] += (~rhs)[i ];
2243  vector_[offset()+i+1UL] += (~rhs)[i+1UL];
2244  }
2245  if( ipos < size() ) {
2246  vector_[offset()+ipos] += (~rhs)[ipos];
2247  }
2248 }
2250 //*************************************************************************************************
2251 
2252 
2253 //*************************************************************************************************
2265 template< typename VT // Type of the dense vector
2266  , bool TF // Transpose flag
2267  , size_t... CSAs > // Compile time subvector arguments
2268 template< typename VT2 > // Type of the right-hand side dense vector
2269 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
2270  -> EnableIf_t< VectorizedAddAssign_v<VT2> >
2271 {
2273 
2274  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2275 
2276  const size_t ipos( size() & size_t(-SIMDSIZE) );
2277  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2278 
2279  size_t i( 0UL );
2280  Iterator left( begin() );
2281  ConstIterator_t<VT2> right( (~rhs).begin() );
2282 
2283  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2284  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2285  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2286  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2287  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2288  }
2289  for( ; i<ipos; i+=SIMDSIZE ) {
2290  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2291  }
2292  for( ; i<size(); ++i ) {
2293  *left += *right; ++left; ++right;
2294  }
2295 }
2297 //*************************************************************************************************
2298 
2299 
2300 //*************************************************************************************************
2312 template< typename VT // Type of the dense vector
2313  , bool TF // Transpose flag
2314  , size_t... CSAs > // Compile time subvector arguments
2315 template< typename VT2 > // Type of the right-hand side sparse vector
2316 inline void Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const SparseVector<VT2,TF>& rhs )
2317 {
2318  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2319 
2320  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2321  vector_[offset()+element->index()] += element->value();
2322 }
2324 //*************************************************************************************************
2325 
2326 
2327 //*************************************************************************************************
2339 template< typename VT // Type of the dense vector
2340  , bool TF // Transpose flag
2341  , size_t... CSAs > // Compile time subvector arguments
2342 template< typename VT2 > // Type of the right-hand side dense vector
2343 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
2344  -> DisableIf_t< VectorizedSubAssign_v<VT2> >
2345 {
2346  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2347 
2348  const size_t ipos( size() & size_t(-2) );
2349  for( size_t i=0UL; i<ipos; i+=2UL ) {
2350  vector_[offset()+i ] -= (~rhs)[i ];
2351  vector_[offset()+i+1UL] -= (~rhs)[i+1UL];
2352  }
2353  if( ipos < size() ) {
2354  vector_[offset()+ipos] -= (~rhs)[ipos];
2355  }
2356 }
2358 //*************************************************************************************************
2359 
2360 
2361 //*************************************************************************************************
2373 template< typename VT // Type of the dense vector
2374  , bool TF // Transpose flag
2375  , size_t... CSAs > // Compile time subvector arguments
2376 template< typename VT2 > // Type of the right-hand side dense vector
2377 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
2378  -> EnableIf_t< VectorizedSubAssign_v<VT2> >
2379 {
2381 
2382  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2383 
2384  const size_t ipos( size() & size_t(-SIMDSIZE) );
2385  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2386 
2387  size_t i( 0UL );
2388  Iterator left( begin() );
2389  ConstIterator_t<VT2> right( (~rhs).begin() );
2390 
2391  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2392  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2393  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2394  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2395  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2396  }
2397  for( ; i<ipos; i+=SIMDSIZE ) {
2398  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2399  }
2400  for( ; i<size(); ++i ) {
2401  *left -= *right; ++left; ++right;
2402  }
2403 }
2405 //*************************************************************************************************
2406 
2407 
2408 //*************************************************************************************************
2420 template< typename VT // Type of the dense vector
2421  , bool TF // Transpose flag
2422  , size_t... CSAs > // Compile time subvector arguments
2423 template< typename VT2 > // Type of the right-hand side sparse vector
2424 inline void Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const SparseVector<VT2,TF>& rhs )
2425 {
2426  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2427 
2428  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2429  vector_[offset()+element->index()] -= element->value();
2430 }
2432 //*************************************************************************************************
2433 
2434 
2435 //*************************************************************************************************
2447 template< typename VT // Type of the dense vector
2448  , bool TF // Transpose flag
2449  , size_t... CSAs > // Compile time subvector arguments
2450 template< typename VT2 > // Type of the right-hand side dense vector
2451 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
2452  -> DisableIf_t< VectorizedMultAssign_v<VT2> >
2453 {
2454  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2455 
2456  const size_t ipos( size() & size_t(-2) );
2457  for( size_t i=0UL; i<ipos; i+=2UL ) {
2458  vector_[offset()+i ] *= (~rhs)[i ];
2459  vector_[offset()+i+1UL] *= (~rhs)[i+1UL];
2460  }
2461  if( ipos < size() ) {
2462  vector_[offset()+ipos] *= (~rhs)[ipos];
2463  }
2464 }
2466 //*************************************************************************************************
2467 
2468 
2469 //*************************************************************************************************
2481 template< typename VT // Type of the dense vector
2482  , bool TF // Transpose flag
2483  , size_t... CSAs > // Compile time subvector arguments
2484 template< typename VT2 > // Type of the right-hand side dense vector
2485 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
2486  -> EnableIf_t< VectorizedMultAssign_v<VT2> >
2487 {
2489 
2490  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2491 
2492  const size_t ipos( size() & size_t(-SIMDSIZE) );
2493  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2494 
2495  size_t i( 0UL );
2496  Iterator left( begin() );
2497  ConstIterator_t<VT2> right( (~rhs).begin() );
2498 
2499  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2500  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2501  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2502  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2503  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2504  }
2505  for( ; i<ipos; i+=SIMDSIZE ) {
2506  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2507  }
2508  for( ; i<size(); ++i ) {
2509  *left *= *right; ++left; ++right;
2510  }
2511 }
2513 //*************************************************************************************************
2514 
2515 
2516 //*************************************************************************************************
2528 template< typename VT // Type of the dense vector
2529  , bool TF // Transpose flag
2530  , size_t... CSAs > // Compile time subvector arguments
2531 template< typename VT2 > // Type of the right-hand side sparse vector
2532 inline void Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const SparseVector<VT2,TF>& rhs )
2533 {
2534  using blaze::reset;
2535 
2536  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2537 
2538  size_t i( 0UL );
2539 
2540  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2541  const size_t index( element->index() );
2542  for( ; i<index; ++i )
2543  reset( vector_[offset()+i] );
2544  vector_[offset()+i] *= element->value();
2545  ++i;
2546  }
2547 
2548  for( ; i<size(); ++i ) {
2549  reset( vector_[offset()+i] );
2550  }
2551 }
2553 //*************************************************************************************************
2554 
2555 
2556 //*************************************************************************************************
2568 template< typename VT // Type of the dense vector
2569  , bool TF // Transpose flag
2570  , size_t... CSAs > // Compile time subvector arguments
2571 template< typename VT2 > // Type of the right-hand side dense vector
2572 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
2573  -> DisableIf_t< VectorizedDivAssign_v<VT2> >
2574 {
2575  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2576 
2577  const size_t ipos( size() & size_t(-2) );
2578  for( size_t i=0UL; i<ipos; i+=2UL ) {
2579  vector_[offset()+i ] /= (~rhs)[i ];
2580  vector_[offset()+i+1UL] /= (~rhs)[i+1UL];
2581  }
2582  if( ipos < size() ) {
2583  vector_[offset()+ipos] /= (~rhs)[ipos];
2584  }
2585 }
2587 //*************************************************************************************************
2588 
2589 
2590 //*************************************************************************************************
2602 template< typename VT // Type of the dense vector
2603  , bool TF // Transpose flag
2604  , size_t... CSAs > // Compile time subvector arguments
2605 template< typename VT2 > // Type of the right-hand side dense vector
2606 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
2607  -> EnableIf_t< VectorizedDivAssign_v<VT2> >
2608 {
2610 
2611  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2612 
2613  const size_t ipos( size() & size_t(-SIMDSIZE) );
2614  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2615 
2616  size_t i( 0UL );
2617  Iterator left( begin() );
2618  ConstIterator_t<VT2> right( (~rhs).begin() );
2619 
2620  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2621  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2622  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2623  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2624  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2625  }
2626  for( ; i<ipos; i+=SIMDSIZE ) {
2627  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2628  }
2629  for( ; i<size(); ++i ) {
2630  *left /= *right; ++left; ++right;
2631  }
2632 }
2634 //*************************************************************************************************
2635 
2636 
2637 
2638 
2639 
2640 
2641 
2642 
2643 //=================================================================================================
2644 //
2645 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED DENSE SUBVECTORS
2646 //
2647 //=================================================================================================
2648 
2649 //*************************************************************************************************
2657 template< typename VT // Type of the dense vector
2658  , bool TF // Transpose flag
2659  , size_t... CSAs > // Compile time subvector arguments
2660 class Subvector<VT,aligned,TF,true,CSAs...>
2661  : public View< DenseVector< Subvector<VT,aligned,TF,true,CSAs...>, TF > >
2662  , private SubvectorData<CSAs...>
2663 {
2664  private:
2665  //**Type definitions****************************************************************************
2666  using DataType = SubvectorData<CSAs...>;
2667  using Operand = If_t< IsExpression_v<VT>, VT, VT& >;
2668  //**********************************************************************************************
2669 
2670  public:
2671  //**Type definitions****************************************************************************
2673  using This = Subvector<VT,aligned,TF,true,CSAs...>;
2674 
2675  using BaseType = DenseVector<This,TF>;
2676  using ViewedType = VT;
2677  using ResultType = SubvectorTrait_t<VT,CSAs...>;
2678  using TransposeType = TransposeType_t<ResultType>;
2679  using ElementType = ElementType_t<VT>;
2680  using SIMDType = SIMDTrait_t<ElementType>;
2681  using ReturnType = ReturnType_t<VT>;
2682  using CompositeType = const Subvector&;
2683 
2685  using ConstReference = ConstReference_t<VT>;
2686 
2688  using Reference = If_t< IsConst_v<VT>, ConstReference, Reference_t<VT> >;
2689 
2691  using ConstPointer = ConstPointer_t<VT>;
2692 
2694  using Pointer = If_t< IsConst_v<VT> || !HasMutableDataAccess_v<VT>, ConstPointer, Pointer_t<VT> >;
2695 
2697  using ConstIterator = ConstIterator_t<VT>;
2698 
2700  using Iterator = If_t< IsConst_v<VT>, ConstIterator, Iterator_t<VT> >;
2701  //**********************************************************************************************
2702 
2703  //**Compilation flags***************************************************************************
2705  static constexpr bool simdEnabled = VT::simdEnabled;
2706 
2708  static constexpr bool smpAssignable = VT::smpAssignable;
2709  //**********************************************************************************************
2710 
2711  //**Constructors********************************************************************************
2714  template< typename... RSAs >
2715  explicit inline Subvector( VT& vector, RSAs... args );
2716 
2717  Subvector( const Subvector& ) = default;
2719  //**********************************************************************************************
2720 
2721  //**Destructor**********************************************************************************
2724  ~Subvector() = default;
2726  //**********************************************************************************************
2727 
2728  //**Data access functions***********************************************************************
2731  inline Reference operator[]( size_t index );
2732  inline ConstReference operator[]( size_t index ) const;
2733  inline Reference at( size_t index );
2734  inline ConstReference at( size_t index ) const;
2735  inline Pointer data () noexcept;
2736  inline ConstPointer data () const noexcept;
2737  inline Iterator begin ();
2738  inline ConstIterator begin () const;
2739  inline ConstIterator cbegin() const;
2740  inline Iterator end ();
2741  inline ConstIterator end () const;
2742  inline ConstIterator cend () const;
2744  //**********************************************************************************************
2745 
2746  //**Assignment operators************************************************************************
2749  inline Subvector& operator= ( const ElementType& rhs );
2750  inline Subvector& operator= ( initializer_list<ElementType> list );
2751  inline Subvector& operator= ( const Subvector& 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 Vector<VT2,TF>& rhs );
2755  template< typename VT2 > inline Subvector& operator*=( const Vector<VT2,TF>& rhs );
2756  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2757  template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
2759  //**********************************************************************************************
2760 
2761  //**Utility functions***************************************************************************
2764  using DataType::offset;
2765  using DataType::size;
2766 
2767  inline VT& operand() noexcept;
2768  inline const VT& operand() const noexcept;
2769 
2770  inline size_t spacing() const noexcept;
2771  inline size_t capacity() const noexcept;
2772  inline size_t nonZeros() const;
2773  inline void reset();
2775  //**********************************************************************************************
2776 
2777  //**Numeric functions***************************************************************************
2780  template< typename Other > inline Subvector& scale( const Other& scalar );
2782  //**********************************************************************************************
2783 
2784  private:
2785  //**********************************************************************************************
2787  template< typename VT2 >
2788  static constexpr bool VectorizedAssign_v =
2789  ( useOptimizedKernels &&
2790  simdEnabled && VT2::simdEnabled &&
2792  //**********************************************************************************************
2793 
2794  //**********************************************************************************************
2796  template< typename VT2 >
2797  static constexpr bool VectorizedAddAssign_v =
2798  ( useOptimizedKernels &&
2799  simdEnabled && VT2::simdEnabled &&
2802  //**********************************************************************************************
2803 
2804  //**********************************************************************************************
2806  template< typename VT2 >
2807  static constexpr bool VectorizedSubAssign_v =
2808  ( useOptimizedKernels &&
2809  simdEnabled && VT2::simdEnabled &&
2812  //**********************************************************************************************
2813 
2814  //**********************************************************************************************
2816  template< typename VT2 >
2817  static constexpr bool VectorizedMultAssign_v =
2818  ( useOptimizedKernels &&
2819  simdEnabled && VT2::simdEnabled &&
2822  //**********************************************************************************************
2823 
2824  //**********************************************************************************************
2826  template< typename VT2 >
2827  static constexpr bool VectorizedDivAssign_v =
2828  ( useOptimizedKernels &&
2829  simdEnabled && VT2::simdEnabled &&
2832  //**********************************************************************************************
2833 
2834  //**SIMD properties*****************************************************************************
2836  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
2837  //**********************************************************************************************
2838 
2839  public:
2840  //**Expression template evaluation functions****************************************************
2843  template< typename Other >
2844  inline bool canAlias( const Other* alias ) const noexcept;
2845 
2846  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
2847  inline bool canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
2848 
2849  template< typename Other >
2850  inline bool isAliased( const Other* alias ) const noexcept;
2851 
2852  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
2853  inline bool isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
2854 
2855  inline bool isAligned () const noexcept;
2856  inline bool canSMPAssign() const noexcept;
2857 
2858  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
2859  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
2860  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
2861 
2862  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
2863  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
2864  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
2865  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
2866 
2867  template< typename VT2 >
2868  inline auto assign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT2> >;
2869 
2870  template< typename VT2 >
2871  inline auto assign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT2> >;
2872 
2873  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
2874 
2875  template< typename VT2 >
2876  inline auto addAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT2> >;
2877 
2878  template< typename VT2 >
2879  inline auto addAssign ( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT2> >;
2880 
2881  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
2882 
2883  template< typename VT2 >
2884  inline auto subAssign ( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT2> >;
2885 
2886  template< typename VT2 >
2887  inline auto subAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT2> >;
2888 
2889  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
2890 
2891  template< typename VT2 >
2892  inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT2> >;
2893 
2894  template< typename VT2 >
2895  inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT2> >;
2896 
2897  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
2898 
2899  template< typename VT2 >
2900  inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT2> >;
2901 
2902  template< typename VT2 >
2903  inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT2> >;
2905  //**********************************************************************************************
2906 
2907  private:
2908  //**Member variables****************************************************************************
2911  Operand vector_;
2912 
2913  //**********************************************************************************************
2914 
2915  //**Friend declarations*************************************************************************
2916  template< typename VT2, AlignmentFlag AF2, bool TF2, bool DF2, size_t... CSAs2 > friend class Subvector;
2917  //**********************************************************************************************
2918 
2919  //**Compile time checks*************************************************************************
2925  //**********************************************************************************************
2926 };
2928 //*************************************************************************************************
2929 
2930 
2931 
2932 
2933 //=================================================================================================
2934 //
2935 // CONSTRUCTORS
2936 //
2937 //=================================================================================================
2938 
2939 //*************************************************************************************************
2953 template< typename VT // Type of the dense vector
2954  , bool TF // Transpose flag
2955  , size_t... CSAs > // Compile time subvector arguments
2956 template< typename... RSAs > // Runtime subvector arguments
2957 inline Subvector<VT,aligned,TF,true,CSAs...>::Subvector( VT& vector, RSAs... args )
2958  : DataType( args... ) // Base class initialization
2959  , vector_ ( vector ) // The vector containing the subvector
2960 {
2961  if( !Contains_v< TypeList<RSAs...>, Unchecked > )
2962  {
2963  if( offset() + size() > vector.size() ) {
2964  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
2965  }
2966 
2967  if( simdEnabled && IsContiguous_v<VT> && !checkAlignment( data() ) ) {
2968  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector alignment" );
2969  }
2970  }
2971  else
2972  {
2973  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
2974  BLAZE_USER_ASSERT( !simdEnabled || !IsContiguous_v<VT> || checkAlignment( data() ), "Invalid subvector alignment" );
2975  }
2976 }
2978 //*************************************************************************************************
2979 
2980 
2981 
2982 
2983 //=================================================================================================
2984 //
2985 // DATA ACCESS FUNCTIONS
2986 //
2987 //=================================================================================================
2988 
2989 //*************************************************************************************************
2996 template< typename VT // Type of the dense vector
2997  , bool TF // Transpose flag
2998  , size_t... CSAs > // Compile time subvector arguments
2999 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Reference
3000  Subvector<VT,aligned,TF,true,CSAs...>::operator[]( size_t index )
3001 {
3002  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
3003  return vector_[offset()+index];
3004 }
3006 //*************************************************************************************************
3007 
3008 
3009 //*************************************************************************************************
3016 template< typename VT // Type of the dense vector
3017  , bool TF // Transpose flag
3018  , size_t... CSAs > // Compile time subvector arguments
3019 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstReference
3020  Subvector<VT,aligned,TF,true,CSAs...>::operator[]( size_t index ) const
3021 {
3022  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
3023  return const_cast<const VT&>( vector_ )[offset()+index];
3024 }
3026 //*************************************************************************************************
3027 
3028 
3029 //*************************************************************************************************
3040 template< typename VT // Type of the dense vector
3041  , bool TF // Transpose flag
3042  , size_t... CSAs > // Compile time subvector arguments
3043 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Reference
3044  Subvector<VT,aligned,TF,true,CSAs...>::at( size_t index )
3045 {
3046  if( index >= size() ) {
3047  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3048  }
3049  return (*this)[index];
3050 }
3052 //*************************************************************************************************
3053 
3054 
3055 //*************************************************************************************************
3066 template< typename VT // Type of the dense vector
3067  , bool TF // Transpose flag
3068  , size_t... CSAs > // Compile time subvector arguments
3069 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstReference
3070  Subvector<VT,aligned,TF,true,CSAs...>::at( size_t index ) const
3071 {
3072  if( index >= size() ) {
3073  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3074  }
3075  return (*this)[index];
3076 }
3078 //*************************************************************************************************
3079 
3080 
3081 //*************************************************************************************************
3089 template< typename VT // Type of the dense vector
3090  , bool TF // Transpose flag
3091  , size_t... CSAs > // Compile time subvector arguments
3092 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Pointer
3094 {
3095  return vector_.data() + offset();
3096 }
3098 //*************************************************************************************************
3099 
3100 
3101 //*************************************************************************************************
3109 template< typename VT // Type of the dense vector
3110  , bool TF // Transpose flag
3111  , size_t... CSAs > // Compile time subvector arguments
3112 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstPointer
3114 {
3115  return vector_.data() + offset();
3116 }
3118 //*************************************************************************************************
3119 
3120 
3121 //*************************************************************************************************
3129 template< typename VT // Type of the dense vector
3130  , bool TF // Transpose flag
3131  , size_t... CSAs > // Compile time subvector arguments
3132 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Iterator
3134 {
3135  return ( vector_.begin() + offset() );
3136 }
3138 //*************************************************************************************************
3139 
3140 
3141 //*************************************************************************************************
3149 template< typename VT // Type of the dense vector
3150  , bool TF // Transpose flag
3151  , size_t... CSAs > // Compile time subvector arguments
3152 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3154 {
3155  return ( vector_.cbegin() + offset() );
3156 }
3158 //*************************************************************************************************
3159 
3160 
3161 //*************************************************************************************************
3169 template< typename VT // Type of the dense vector
3170  , bool TF // Transpose flag
3171  , size_t... CSAs > // Compile time subvector arguments
3172 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3174 {
3175  return ( vector_.cbegin() + offset() );
3176 }
3178 //*************************************************************************************************
3179 
3180 
3181 //*************************************************************************************************
3189 template< typename VT // Type of the dense vector
3190  , bool TF // Transpose flag
3191  , size_t... CSAs > // Compile time subvector arguments
3192 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Iterator
3194 {
3195  return ( vector_.begin() + offset() + size() );
3196 }
3198 //*************************************************************************************************
3199 
3200 
3201 //*************************************************************************************************
3209 template< typename VT // Type of the dense vector
3210  , bool TF // Transpose flag
3211  , size_t... CSAs > // Compile time subvector arguments
3212 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3214 {
3215  return ( vector_.cbegin() + offset() + size() );
3216 }
3218 //*************************************************************************************************
3219 
3220 
3221 //*************************************************************************************************
3229 template< typename VT // Type of the dense vector
3230  , bool TF // Transpose flag
3231  , size_t... CSAs > // Compile time subvector arguments
3232 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3234 {
3235  return ( vector_.cbegin() + offset() + size() );
3236 }
3238 //*************************************************************************************************
3239 
3240 
3241 
3242 
3243 //=================================================================================================
3244 //
3245 // ASSIGNMENT OPERATORS
3246 //
3247 //=================================================================================================
3248 
3249 //*************************************************************************************************
3256 template< typename VT // Type of the dense vector
3257  , bool TF // Transpose flag
3258  , size_t... CSAs > // Compile time subvector arguments
3259 inline Subvector<VT,aligned,TF,true,CSAs...>&
3260  Subvector<VT,aligned,TF,true,CSAs...>::operator=( const ElementType& rhs )
3261 {
3262  const size_t iend( offset() + size() );
3263  decltype(auto) left( derestrict( vector_ ) );
3264 
3265  for( size_t i=offset(); i<iend; ++i ) {
3266  if( !IsRestricted_v<VT> || trySet( vector_, i, rhs ) )
3267  left[i] = rhs;
3268  }
3269 
3270  return *this;
3271 }
3273 //*************************************************************************************************
3274 
3275 
3276 //*************************************************************************************************
3289 template< typename VT // Type of the dense vector
3290  , bool TF // Transpose flag
3291  , size_t... CSAs > // Compile time subvector arguments
3292 inline Subvector<VT,aligned,TF,true,CSAs...>&
3293  Subvector<VT,aligned,TF,true,CSAs...>::operator=( initializer_list<ElementType> list )
3294 {
3295  if( list.size() > size() ) {
3296  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
3297  }
3298 
3299  if( IsRestricted_v<VT> ) {
3300  const InitializerVector<ElementType,TF> tmp( list, size() );
3301  if( !tryAssign( vector_, tmp, offset() ) ) {
3302  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3303  }
3304  }
3305 
3306  decltype(auto) left( derestrict( *this ) );
3307 
3308  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
3309 
3310  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3311 
3312  return *this;
3313 }
3315 //*************************************************************************************************
3316 
3317 
3318 //*************************************************************************************************
3330 template< typename VT // Type of the dense vector
3331  , bool TF // Transpose flag
3332  , size_t... CSAs > // Compile time subvector arguments
3333 inline Subvector<VT,aligned,TF,true,CSAs...>&
3334  Subvector<VT,aligned,TF,true,CSAs...>::operator=( const Subvector& rhs )
3335 {
3338 
3339  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset() == rhs.offset() ) )
3340  return *this;
3341 
3342  if( size() != rhs.size() ) {
3343  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
3344  }
3345 
3346  if( !tryAssign( vector_, rhs, offset() ) ) {
3347  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3348  }
3349 
3350  decltype(auto) left( derestrict( *this ) );
3351 
3352  if( rhs.canAlias( &vector_ ) ) {
3353  const ResultType tmp( ~rhs );
3354  smpAssign( left, tmp );
3355  }
3356  else {
3357  smpAssign( left, rhs );
3358  }
3359 
3360  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3361 
3362  return *this;
3363 }
3365 //*************************************************************************************************
3366 
3367 
3368 //*************************************************************************************************
3380 template< typename VT // Type of the dense vector
3381  , bool TF // Transpose flag
3382  , size_t... CSAs > // Compile time subvector arguments
3383 template< typename VT2 > // Type of the right-hand side vector
3384 inline Subvector<VT,aligned,TF,true,CSAs...>&
3385  Subvector<VT,aligned,TF,true,CSAs...>::operator=( const Vector<VT2,TF>& rhs )
3386 {
3387  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3388  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3389 
3390  if( size() != (~rhs).size() ) {
3391  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3392  }
3393 
3394  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3395  Right right( ~rhs );
3396 
3397  if( !tryAssign( vector_, right, offset() ) ) {
3398  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3399  }
3400 
3401  decltype(auto) left( derestrict( *this ) );
3402 
3403  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3404  const ResultType_t<VT2> tmp( right );
3405  smpAssign( left, tmp );
3406  }
3407  else {
3408  if( IsSparseVector_v<VT2> )
3409  reset();
3410  smpAssign( left, right );
3411  }
3412 
3413  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3414 
3415  return *this;
3416 }
3418 //*************************************************************************************************
3419 
3420 
3421 //*************************************************************************************************
3433 template< typename VT // Type of the dense vector
3434  , bool TF // Transpose flag
3435  , size_t... CSAs > // Compile time subvector arguments
3436 template< typename VT2 > // Type of the right-hand side vector
3437 inline Subvector<VT,aligned,TF,true,CSAs...>&
3438  Subvector<VT,aligned,TF,true,CSAs...>::operator+=( const Vector<VT2,TF>& rhs )
3439 {
3440  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3441  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3442 
3443  if( size() != (~rhs).size() ) {
3444  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3445  }
3446 
3447  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3448  Right right( ~rhs );
3449 
3450  if( !tryAddAssign( vector_, right, offset() ) ) {
3451  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3452  }
3453 
3454  decltype(auto) left( derestrict( *this ) );
3455 
3456  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3457  const ResultType_t<VT2> tmp( right );
3458  smpAddAssign( left, tmp );
3459  }
3460  else {
3461  smpAddAssign( left, right );
3462  }
3463 
3464  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3465 
3466  return *this;
3467 }
3469 //*************************************************************************************************
3470 
3471 
3472 //*************************************************************************************************
3484 template< typename VT // Type of the dense vector
3485  , bool TF // Transpose flag
3486  , size_t... CSAs > // Compile time subvector arguments
3487 template< typename VT2 > // Type of the right-hand side vector
3488 inline Subvector<VT,aligned,TF,true,CSAs...>&
3489  Subvector<VT,aligned,TF,true,CSAs...>::operator-=( const Vector<VT2,TF>& rhs )
3490 {
3491  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3492  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3493 
3494  if( size() != (~rhs).size() ) {
3495  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3496  }
3497 
3498  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3499  Right right( ~rhs );
3500 
3501  if( !trySubAssign( vector_, right, offset() ) ) {
3502  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3503  }
3504 
3505  decltype(auto) left( derestrict( *this ) );
3506 
3507  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3508  const ResultType_t<VT2> tmp( right );
3509  smpSubAssign( left, tmp );
3510  }
3511  else {
3512  smpSubAssign( left, right );
3513  }
3514 
3515  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3516 
3517  return *this;
3518 }
3520 //*************************************************************************************************
3521 
3522 
3523 //*************************************************************************************************
3536 template< typename VT // Type of the dense vector
3537  , bool TF // Transpose flag
3538  , size_t... CSAs > // Compile time subvector arguments
3539 template< typename VT2 > // Type of the right-hand side vector
3540 inline Subvector<VT,aligned,TF,true,CSAs...>&
3541  Subvector<VT,aligned,TF,true,CSAs...>::operator*=( const Vector<VT2,TF>& rhs )
3542 {
3543  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3544  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3545 
3546  if( size() != (~rhs).size() ) {
3547  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3548  }
3549 
3550  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3551  Right right( ~rhs );
3552 
3553  if( !tryMultAssign( vector_, right, offset() ) ) {
3554  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3555  }
3556 
3557  decltype(auto) left( derestrict( *this ) );
3558 
3559  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3560  const ResultType_t<VT2> tmp( right );
3561  smpMultAssign( left, tmp );
3562  }
3563  else {
3564  smpMultAssign( left, right );
3565  }
3566 
3567  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3568 
3569  return *this;
3570 }
3572 //*************************************************************************************************
3573 
3574 
3575 //*************************************************************************************************
3587 template< typename VT // Type of the dense vector
3588  , bool TF // Transpose flag
3589  , size_t... CSAs > // Compile time subvector arguments
3590 template< typename VT2 > // Type of the right-hand side dense vector
3591 inline Subvector<VT,aligned,TF,true,CSAs...>&
3592  Subvector<VT,aligned,TF,true,CSAs...>::operator/=( const DenseVector<VT2,TF>& rhs )
3593 {
3594  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3595  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3596 
3597  if( size() != (~rhs).size() ) {
3598  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3599  }
3600 
3601  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3602  Right right( ~rhs );
3603 
3604  if( !tryDivAssign( vector_, right, offset() ) ) {
3605  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3606  }
3607 
3608  decltype(auto) left( derestrict( *this ) );
3609 
3610  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3611  const ResultType_t<VT2> tmp( right );
3612  smpDivAssign( left, tmp );
3613  }
3614  else {
3615  smpDivAssign( left, right );
3616  }
3617 
3618  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3619 
3620  return *this;
3621 }
3623 //*************************************************************************************************
3624 
3625 
3626 //*************************************************************************************************
3639 template< typename VT // Type of the dense vector
3640  , bool TF // Transpose flag
3641  , size_t... CSAs > // Compile time subvector arguments
3642 template< typename VT2 > // Type of the right-hand side vector
3643 inline Subvector<VT,aligned,TF,true,CSAs...>&
3644  Subvector<VT,aligned,TF,true,CSAs...>::operator%=( const Vector<VT2,TF>& rhs )
3645 {
3646  using blaze::assign;
3647 
3648  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3649  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3650 
3651  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT2> >;
3652 
3656 
3657  if( size() != 3UL || (~rhs).size() != 3UL ) {
3658  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3659  }
3660 
3661  const CrossType tmp( *this % (~rhs) );
3662 
3663  if( !tryAssign( vector_, tmp, offset() ) ) {
3664  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3665  }
3666 
3667  decltype(auto) left( derestrict( *this ) );
3668 
3669  assign( left, tmp );
3670 
3671  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3672 
3673  return *this;
3674 }
3676 //*************************************************************************************************
3677 
3678 
3679 
3680 
3681 //=================================================================================================
3682 //
3683 // UTILITY FUNCTIONS
3684 //
3685 //=================================================================================================
3686 
3687 //*************************************************************************************************
3693 template< typename VT // Type of the dense vector
3694  , bool TF // Transpose flag
3695  , size_t... CSAs > // Compile time subvector arguments
3696 inline VT& Subvector<VT,aligned,TF,true,CSAs...>::operand() noexcept
3697 {
3698  return vector_;
3699 }
3701 //*************************************************************************************************
3702 
3703 
3704 //*************************************************************************************************
3710 template< typename VT // Type of the dense vector
3711  , bool TF // Transpose flag
3712  , size_t... CSAs > // Compile time subvector arguments
3713 inline const VT& Subvector<VT,aligned,TF,true,CSAs...>::operand() const noexcept
3714 {
3715  return vector_;
3716 }
3718 //*************************************************************************************************
3719 
3720 
3721 //*************************************************************************************************
3730 template< typename VT // Type of the dense vector
3731  , bool TF // Transpose flag
3732  , size_t... CSAs > // Compile time subvector arguments
3733 inline size_t Subvector<VT,aligned,TF,true,CSAs...>::spacing() const noexcept
3734 {
3735  return vector_.spacing() - offset();
3736 }
3738 //*************************************************************************************************
3739 
3740 
3741 //*************************************************************************************************
3747 template< typename VT // Type of the dense vector
3748  , bool TF // Transpose flag
3749  , size_t... CSAs > // Compile time subvector arguments
3750 inline size_t Subvector<VT,aligned,TF,true,CSAs...>::capacity() const noexcept
3751 {
3752  return vector_.capacity() - offset();
3753 }
3755 //*************************************************************************************************
3756 
3757 
3758 //*************************************************************************************************
3767 template< typename VT // Type of the dense vector
3768  , bool TF // Transpose flag
3769  , size_t... CSAs > // Compile time subvector arguments
3771 {
3772  size_t nonzeros( 0 );
3773 
3774  const size_t iend( offset() + size() );
3775  for( size_t i=offset(); i<iend; ++i ) {
3776  if( !isDefault( vector_[i] ) )
3777  ++nonzeros;
3778  }
3779 
3780  return nonzeros;
3781 }
3783 //*************************************************************************************************
3784 
3785 
3786 //*************************************************************************************************
3792 template< typename VT // Type of the dense vector
3793  , bool TF // Transpose flag
3794  , size_t... CSAs > // Compile time subvector arguments
3796 {
3797  using blaze::clear;
3798 
3799  const size_t iend( offset() + size() );
3800  for( size_t i=offset(); i<iend; ++i )
3801  clear( vector_[i] );
3802 }
3804 //*************************************************************************************************
3805 
3806 
3807 
3808 
3809 //=================================================================================================
3810 //
3811 // NUMERIC FUNCTIONS
3812 //
3813 //=================================================================================================
3814 
3815 //*************************************************************************************************
3826 template< typename VT // Type of the dense vector
3827  , bool TF // Transpose flag
3828  , size_t... CSAs > // Compile time subvector arguments
3829 template< typename Other > // Data type of the scalar value
3830 inline Subvector<VT,aligned,TF,true,CSAs...>&
3831  Subvector<VT,aligned,TF,true,CSAs...>::scale( const Other& scalar )
3832 {
3833  const size_t iend( offset() + size() );
3834  for( size_t i=offset(); i<iend; ++i )
3835  vector_[i] *= scalar;
3836  return *this;
3837 }
3839 //*************************************************************************************************
3840 
3841 
3842 
3843 
3844 //=================================================================================================
3845 //
3846 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3847 //
3848 //=================================================================================================
3849 
3850 //*************************************************************************************************
3861 template< typename VT // Type of the dense vector
3862  , bool TF // Transpose flag
3863  , size_t... CSAs > // Compile time subvector arguments
3864 template< typename Other > // Data type of the foreign expression
3865 inline bool Subvector<VT,aligned,TF,true,CSAs...>::canAlias( const Other* alias ) const noexcept
3866 {
3867  return vector_.isAliased( alias );
3868 }
3870 //*************************************************************************************************
3871 
3872 
3873 //*************************************************************************************************
3884 template< typename VT // Type of the dense vector
3885  , bool TF // Transpose flag
3886  , size_t... CSAs > // Compile time subvector arguments
3887 template< typename VT2 // Data type of the foreign dense subvector
3888  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
3889  , bool TF2 // Transpose flag of the foreign dense subvector
3890  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
3891 inline bool
3892  Subvector<VT,aligned,TF,true,CSAs...>::canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
3893 {
3894  return ( vector_.isAliased( &alias->vector_ ) &&
3895  ( offset() + size() > alias->offset() ) &&
3896  ( offset() < alias->offset() + alias->size() ) );
3897 }
3899 //*************************************************************************************************
3900 
3901 
3902 //*************************************************************************************************
3913 template< typename VT // Type of the dense vector
3914  , bool TF // Transpose flag
3915  , size_t... CSAs > // Compile time subvector arguments
3916 template< typename Other > // Data type of the foreign expression
3917 inline bool Subvector<VT,aligned,TF,true,CSAs...>::isAliased( const Other* alias ) const noexcept
3918 {
3919  return vector_.isAliased( alias );
3920 }
3922 //*************************************************************************************************
3923 
3924 
3925 //*************************************************************************************************
3936 template< typename VT // Type of the dense vector
3937  , bool TF // Transpose flag
3938  , size_t... CSAs > // Compile time subvector arguments
3939 template< typename VT2 // Data type of the foreign dense subvector
3940  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
3941  , bool TF2 // Transpose flag of the foreign dense subvector
3942  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
3943 inline bool
3944  Subvector<VT,aligned,TF,true,CSAs...>::isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
3945 {
3946  return ( vector_.isAliased( &alias->vector_ ) &&
3947  ( offset() + size() > alias->offset() ) &&
3948  ( offset() < alias->offset() + alias->size() ) );
3949 }
3951 //*************************************************************************************************
3952 
3953 
3954 //*************************************************************************************************
3964 template< typename VT // Type of the dense vector
3965  , bool TF // Transpose flag
3966  , size_t... CSAs > // Compile time subvector arguments
3967 inline bool Subvector<VT,aligned,TF,true,CSAs...>::isAligned() const noexcept
3968 {
3969  return true;
3970 }
3972 //*************************************************************************************************
3973 
3974 
3975 //*************************************************************************************************
3986 template< typename VT // Type of the dense vector
3987  , bool TF // Transpose flag
3988  , size_t... CSAs > // Compile time subvector arguments
3989 inline bool Subvector<VT,aligned,TF,true,CSAs...>::canSMPAssign() const noexcept
3990 {
3991  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3992 }
3994 //*************************************************************************************************
3995 
3996 
3997 //*************************************************************************************************
4011 template< typename VT // Type of the dense vector
4012  , bool TF // Transpose flag
4013  , size_t... CSAs > // Compile time subvector arguments
4014 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4015  Subvector<VT,aligned,TF,true,CSAs...>::load( size_t index ) const noexcept
4016 {
4017  return loada( index );
4018 }
4020 //*************************************************************************************************
4021 
4022 
4023 //*************************************************************************************************
4037 template< typename VT // Type of the dense vector
4038  , bool TF // Transpose flag
4039  , size_t... CSAs > // Compile time subvector arguments
4040 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4041  Subvector<VT,aligned,TF,true,CSAs...>::loada( size_t index ) const noexcept
4042 {
4044 
4045  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4046  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4047  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4048 
4049  return vector_.loada( offset()+index );
4050 }
4052 //*************************************************************************************************
4053 
4054 
4055 //*************************************************************************************************
4069 template< typename VT // Type of the dense vector
4070  , bool TF // Transpose flag
4071  , size_t... CSAs > // Compile time subvector arguments
4072 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4073  Subvector<VT,aligned,TF,true,CSAs...>::loadu( size_t index ) const noexcept
4074 {
4076 
4077  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4078  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4079  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4080 
4081  return vector_.loadu( offset()+index );
4082 }
4084 //*************************************************************************************************
4085 
4086 
4087 //*************************************************************************************************
4102 template< typename VT // Type of the dense vector
4103  , bool TF // Transpose flag
4104  , size_t... CSAs > // Compile time subvector arguments
4106  Subvector<VT,aligned,TF,true,CSAs...>::store( size_t index, const SIMDType& value ) noexcept
4107 {
4108  storea( index, value );
4109 }
4111 //*************************************************************************************************
4112 
4113 
4114 //*************************************************************************************************
4129 template< typename VT // Type of the dense vector
4130  , bool TF // Transpose flag
4131  , size_t... CSAs > // Compile time subvector arguments
4133  Subvector<VT,aligned,TF,true,CSAs...>::storea( size_t index, const SIMDType& value ) noexcept
4134 {
4136 
4137  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4138  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4139  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4140 
4141  vector_.storea( offset()+index, value );
4142 }
4144 //*************************************************************************************************
4145 
4146 
4147 //*************************************************************************************************
4162 template< typename VT // Type of the dense vector
4163  , bool TF // Transpose flag
4164  , size_t... CSAs > // Compile time subvector arguments
4166  Subvector<VT,aligned,TF,true,CSAs...>::storeu( size_t index, const SIMDType& value ) noexcept
4167 {
4169 
4170  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4171  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4172  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4173 
4174  vector_.storeu( offset()+index, value );
4175 }
4177 //*************************************************************************************************
4178 
4179 
4180 //*************************************************************************************************
4195 template< typename VT // Type of the dense vector
4196  , bool TF // Transpose flag
4197  , size_t... CSAs > // Compile time subvector arguments
4199  Subvector<VT,aligned,TF,true,CSAs...>::stream( size_t index, const SIMDType& value ) noexcept
4200 {
4202 
4203  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4204  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4205  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4206 
4207  vector_.stream( offset()+index, value );
4208 }
4210 //*************************************************************************************************
4211 
4212 
4213 //*************************************************************************************************
4225 template< typename VT // Type of the dense vector
4226  , bool TF // Transpose flag
4227  , size_t... CSAs > // Compile time subvector arguments
4228 template< typename VT2 > // Type of the right-hand side dense vector
4229 inline auto Subvector<VT,aligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
4230  -> DisableIf_t< VectorizedAssign_v<VT2> >
4231 {
4232  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4233 
4234  const size_t ipos( size() & size_t(-2) );
4235  for( size_t i=0UL; i<ipos; i+=2UL ) {
4236  vector_[offset()+i ] = (~rhs)[i ];
4237  vector_[offset()+i+1UL] = (~rhs)[i+1UL];
4238  }
4239  if( ipos < size() ) {
4240  vector_[offset()+ipos] = (~rhs)[ipos];
4241  }
4242 }
4244 //*************************************************************************************************
4245 
4246 
4247 //*************************************************************************************************
4259 template< typename VT // Type of the dense vector
4260  , bool TF // Transpose flag
4261  , size_t... CSAs > // Compile time subvector arguments
4262 template< typename VT2 > // Type of the right-hand side dense vector
4263 inline auto Subvector<VT,aligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
4264  -> EnableIf_t< VectorizedAssign_v<VT2> >
4265 {
4267 
4268  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4269 
4270  const size_t ipos( size() & size_t(-SIMDSIZE) );
4271  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4272 
4273  size_t i( 0UL );
4274  Iterator left( begin() );
4275  ConstIterator_t<VT2> right( (~rhs).begin() );
4276 
4277  if( useStreaming && size() > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
4278  {
4279  for( ; i<ipos; i+=SIMDSIZE ) {
4280  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4281  }
4282  for( ; i<size(); ++i ) {
4283  *left = *right; ++left; ++right;
4284  }
4285  }
4286  else
4287  {
4288  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4289  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4290  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4291  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4292  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4293  }
4294  for( ; i<ipos; i+=SIMDSIZE ) {
4295  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4296  }
4297  for( ; i<size(); ++i ) {
4298  *left = *right; ++left; ++right;
4299  }
4300  }
4301 }
4303 //*************************************************************************************************
4304 
4305 
4306 //*************************************************************************************************
4318 template< typename VT // Type of the dense vector
4319  , bool TF // Transpose flag
4320  , size_t... CSAs > // Compile time subvector arguments
4321 template< typename VT2 > // Type of the right-hand side sparse vector
4322 inline void Subvector<VT,aligned,TF,true,CSAs...>::assign( const SparseVector<VT2,TF>& rhs )
4323 {
4324  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4325 
4326  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4327  vector_[offset()+element->index()] = element->value();
4328 }
4330 //*************************************************************************************************
4331 
4332 
4333 //*************************************************************************************************
4345 template< typename VT // Type of the dense vector
4346  , bool TF // Transpose flag
4347  , size_t... CSAs > // Compile time subvector arguments
4348 template< typename VT2 > // Type of the right-hand side dense vector
4349 inline auto Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
4350  -> DisableIf_t< VectorizedAddAssign_v<VT2> >
4351 {
4352  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4353 
4354  const size_t ipos( size() & size_t(-2) );
4355  for( size_t i=0UL; i<ipos; i+=2UL ) {
4356  vector_[offset()+i ] += (~rhs)[i ];
4357  vector_[offset()+i+1UL] += (~rhs)[i+1UL];
4358  }
4359  if( ipos < size() ) {
4360  vector_[offset()+ipos] += (~rhs)[ipos];
4361  }
4362 }
4364 //*************************************************************************************************
4365 
4366 
4367 //*************************************************************************************************
4379 template< typename VT // Type of the dense vector
4380  , bool TF // Transpose flag
4381  , size_t... CSAs > // Compile time subvector arguments
4382 template< typename VT2 > // Type of the right-hand side dense vector
4383 inline auto Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
4384  -> EnableIf_t< VectorizedAddAssign_v<VT2> >
4385 {
4387 
4388  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4389 
4390  const size_t ipos( size() & size_t(-SIMDSIZE) );
4391  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4392 
4393  size_t i( 0UL );
4394  Iterator left( begin() );
4395  ConstIterator_t<VT2> right( (~rhs).begin() );
4396 
4397  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4398  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4399  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4400  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4401  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4402  }
4403  for( ; i<ipos; i+=SIMDSIZE ) {
4404  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4405  }
4406  for( ; i<size(); ++i ) {
4407  *left += *right; ++left; ++right;
4408  }
4409 }
4411 //*************************************************************************************************
4412 
4413 
4414 //*************************************************************************************************
4426 template< typename VT // Type of the dense vector
4427  , bool TF // Transpose flag
4428  , size_t... CSAs > // Compile time subvector arguments
4429 template< typename VT2 > // Type of the right-hand side sparse vector
4430 inline void Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const SparseVector<VT2,TF>& rhs )
4431 {
4432  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4433 
4434  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4435  vector_[offset()+element->index()] += element->value();
4436 }
4438 //*************************************************************************************************
4439 
4440 
4441 //*************************************************************************************************
4453 template< typename VT // Type of the dense vector
4454  , bool TF // Transpose flag
4455  , size_t... CSAs > // Compile time subvector arguments
4456 template< typename VT2 > // Type of the right-hand side dense vector
4457 inline auto Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
4458  -> DisableIf_t< VectorizedSubAssign_v<VT2> >
4459 {
4460  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4461 
4462  const size_t ipos( size() & size_t(-2) );
4463  for( size_t i=0UL; i<ipos; i+=2UL ) {
4464  vector_[offset()+i ] -= (~rhs)[i ];
4465  vector_[offset()+i+1UL] -= (~rhs)[i+1UL];
4466  }
4467  if( ipos < size() ) {
4468  vector_[offset()+ipos] -= (~rhs)[ipos];
4469  }
4470 }
4472 //*************************************************************************************************
4473 
4474 
4475 //*************************************************************************************************
4487 template< typename VT // Type of the dense vector
4488  , bool TF // Transpose flag
4489  , size_t... CSAs > // Compile time subvector arguments
4490 template< typename VT2 > // Type of the right-hand side dense vector
4491 inline auto Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
4492  -> EnableIf_t< VectorizedSubAssign_v<VT2> >
4493 {
4495 
4496  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4497 
4498  const size_t ipos( size() & size_t(-SIMDSIZE) );
4499  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4500 
4501  size_t i( 0UL );
4502  Iterator left( begin() );
4503  ConstIterator_t<VT2> right( (~rhs).begin() );
4504 
4505  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4506  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4507  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4508  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4509  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4510  }
4511  for( ; i<ipos; i+=SIMDSIZE ) {
4512  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4513  }
4514  for( ; i<size(); ++i ) {
4515  *left -= *right; ++left; ++right;
4516  }
4517 }
4519 //*************************************************************************************************
4520 
4521 
4522 //*************************************************************************************************
4534 template< typename VT // Type of the dense vector
4535  , bool TF // Transpose flag
4536  , size_t... CSAs > // Compile time subvector arguments
4537 template< typename VT2 > // Type of the right-hand side sparse vector
4538 inline void Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const SparseVector<VT2,TF>& rhs )
4539 {
4540  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4541 
4542  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4543  vector_[offset()+element->index()] -= element->value();
4544 }
4546 //*************************************************************************************************
4547 
4548 
4549 //*************************************************************************************************
4561 template< typename VT // Type of the dense vector
4562  , bool TF // Transpose flag
4563  , size_t... CSAs > // Compile time subvector arguments
4564 template< typename VT2 > // Type of the right-hand side dense vector
4565 inline auto Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
4566  -> DisableIf_t< VectorizedMultAssign_v<VT2> >
4567 {
4568  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4569 
4570  const size_t ipos( size() & size_t(-2) );
4571  for( size_t i=0UL; i<ipos; i+=2UL ) {
4572  vector_[offset()+i ] *= (~rhs)[i ];
4573  vector_[offset()+i+1UL] *= (~rhs)[i+1UL];
4574  }
4575  if( ipos < size() ) {
4576  vector_[offset()+ipos] *= (~rhs)[ipos];
4577  }
4578 }
4580 //*************************************************************************************************
4581 
4582 
4583 //*************************************************************************************************
4595 template< typename VT // Type of the dense vector
4596  , bool TF // Transpose flag
4597  , size_t... CSAs > // Compile time subvector arguments
4598 template< typename VT2 > // Type of the right-hand side dense vector
4599 inline auto Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
4600  -> EnableIf_t< VectorizedMultAssign_v<VT2> >
4601 {
4603 
4604  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4605 
4606  const size_t ipos( size() & size_t(-SIMDSIZE) );
4607  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4608 
4609  size_t i( 0UL );
4610  Iterator left( begin() );
4611  ConstIterator_t<VT2> right( (~rhs).begin() );
4612 
4613  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4614  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4615  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4616  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4617  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4618  }
4619  for( ; i<ipos; i+=SIMDSIZE ) {
4620  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4621  }
4622  for( ; i<size(); ++i ) {
4623  *left *= *right; ++left; ++right;
4624  }
4625 }
4627 //*************************************************************************************************
4628 
4629 
4630 //*************************************************************************************************
4642 template< typename VT // Type of the dense vector
4643  , bool TF // Transpose flag
4644  , size_t... CSAs > // Compile time subvector arguments
4645 template< typename VT2 > // Type of the right-hand side sparse vector
4646 inline void Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const SparseVector<VT2,TF>& rhs )
4647 {
4648  using blaze::reset;
4649 
4650  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4651 
4652  size_t i( 0UL );
4653 
4654  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
4655  const size_t index( element->index() );
4656  for( ; i<index; ++i )
4657  reset( vector_[offset()+i] );
4658  vector_[offset()+i] *= element->value();
4659  ++i;
4660  }
4661 
4662  for( ; i<size(); ++i ) {
4663  reset( vector_[offset()+i] );
4664  }
4665 }
4667 //*************************************************************************************************
4668 
4669 
4670 //*************************************************************************************************
4682 template< typename VT // Type of the dense vector
4683  , bool TF // Transpose flag
4684  , size_t... CSAs > // Compile time subvector arguments
4685 template< typename VT2 > // Type of the right-hand side dense vector
4686 inline auto Subvector<VT,aligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
4687  -> DisableIf_t< VectorizedDivAssign_v<VT2> >
4688 {
4689  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4690 
4691  const size_t ipos( size() & size_t(-2) );
4692  for( size_t i=0UL; i<ipos; i+=2UL ) {
4693  vector_[offset()+i ] /= (~rhs)[i ];
4694  vector_[offset()+i+1UL] /= (~rhs)[i+1UL];
4695  }
4696  if( ipos < size() ) {
4697  vector_[offset()+ipos] /= (~rhs)[ipos];
4698  }
4699 }
4701 //*************************************************************************************************
4702 
4703 
4704 //*************************************************************************************************
4716 template< typename VT // Type of the dense vector
4717  , bool TF // Transpose flag
4718  , size_t... CSAs > // Compile time subvector arguments
4719 template< typename VT2 > // Type of the right-hand side dense vector
4720 inline auto Subvector<VT,aligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
4721  -> EnableIf_t< VectorizedDivAssign_v<VT2> >
4722 {
4724 
4725  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4726 
4727  const size_t ipos( size() & size_t(-SIMDSIZE) );
4728  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4729 
4730  size_t i( 0UL );
4731  Iterator left( begin() );
4732  ConstIterator_t<VT2> right( (~rhs).begin() );
4733 
4734  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4735  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4736  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4737  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4738  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4739  }
4740  for( ; i<ipos; i+=SIMDSIZE ) {
4741  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4742  }
4743  for( ; i<size(); ++i ) {
4744  *left /= *right; ++left; ++right;
4745  }
4746 }
4748 //*************************************************************************************************
4749 
4750 
4751 
4752 
4753 
4754 
4755 
4756 
4757 //=================================================================================================
4758 //
4759 // CLASS TEMPLATE SPECIALIZATION FOR DVECDVECCROSSEXPR
4760 //
4761 //=================================================================================================
4762 
4763 //*************************************************************************************************
4771 template< typename VT1 // Type of the left-hand side dense vector
4772  , typename VT2 // Type of the right-hand side dense vector
4773  , bool TF // Transpose flag
4774  , size_t... CSAs > // Compile time subvector arguments
4775 class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
4776  : public View< DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
4777  , private SubvectorData<CSAs...>
4778 {
4779  private:
4780  //**Type definitions****************************************************************************
4781  using CPE = DVecDVecCrossExpr<VT1,VT2,TF>;
4782  using RT = ResultType_t<CPE>;
4783  using DataType = SubvectorData<CSAs...>;
4784  //**********************************************************************************************
4785 
4786  public:
4787  //**Type definitions****************************************************************************
4789  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
4790 
4791  using BaseType = DenseVector<This,TF>;
4792  using ViewedType = CPE;
4793  using ResultType = SubvectorTrait_t<RT,CSAs...>;
4794  using TransposeType = TransposeType_t<ResultType>;
4795  using ElementType = ElementType_t<CPE>;
4796  using ReturnType = ReturnType_t<CPE>;
4797  using CompositeType = const ResultType;
4798  //**********************************************************************************************
4799 
4800  //**Compilation flags***************************************************************************
4802  static constexpr bool simdEnabled = false;
4803 
4805  static constexpr bool smpAssignable = false;
4806  //**********************************************************************************************
4807 
4808  //**Constructor*********************************************************************************
4815  template< typename... RSAs > // Optional subvector arguments
4816  explicit inline Subvector( const CPE& vector, RSAs... args )
4817  : DataType( args... ) // Base class initialization
4818  , vector_ ( vector ) // The dense vector/dense vector cross product expression
4819  {
4820  if( Contains_v< TypeList<RSAs...>, Unchecked > ) {
4821  if( offset() + size() > vector.size() ) {
4822  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
4823  }
4824  }
4825  else {
4826  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
4827  }
4828  }
4829  //**********************************************************************************************
4830 
4831  //**Subscript operator**************************************************************************
4837  inline ReturnType operator[]( size_t index ) const {
4838  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4839  return vector_[offset()+index];
4840  }
4841  //**********************************************************************************************
4842 
4843  //**At function*********************************************************************************
4850  inline ReturnType at( size_t index ) const {
4851  if( index >= size() ) {
4852  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
4853  }
4854  return (*this)[index];
4855  }
4856  //**********************************************************************************************
4857 
4858  //**********************************************************************************************
4859  using DataType::offset;
4860  using DataType::size;
4861  //**********************************************************************************************
4862 
4863  //**Operand access******************************************************************************
4868  inline CPE operand() const noexcept {
4869  return vector_;
4870  }
4871  //**********************************************************************************************
4872 
4873  //**********************************************************************************************
4879  template< typename T >
4880  inline bool canAlias( const T* alias ) const noexcept {
4881  return vector_.canAlias( alias );
4882  }
4883  //**********************************************************************************************
4884 
4885  //**********************************************************************************************
4891  template< typename T >
4892  inline bool isAliased( const T* alias ) const noexcept {
4893  return vector_.isAliased( alias );
4894  }
4895  //**********************************************************************************************
4896 
4897  private:
4898  //**Member variables****************************************************************************
4899  CPE vector_;
4900  //**********************************************************************************************
4901 };
4903 //*************************************************************************************************
4904 
4905 
4906 
4907 
4908 
4909 
4910 
4911 
4912 //=================================================================================================
4913 //
4914 // CLASS TEMPLATE SPECIALIZATION FOR DVECSVECCROSSEXPR
4915 //
4916 //=================================================================================================
4917 
4918 //*************************************************************************************************
4926 template< typename VT1 // Type of the left-hand side dense vector
4927  , typename VT2 // Type of the right-hand side sparse vector
4928  , bool TF // Transpose flag
4929  , size_t... CSAs > // Compile time subvector arguments
4930 class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
4931  : public View< DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
4932  , private SubvectorData<CSAs...>
4933 {
4934  private:
4935  //**Type definitions****************************************************************************
4936  using CPE = DVecSVecCrossExpr<VT1,VT2,TF>;
4937  using RT = ResultType_t<CPE>;
4938  using DataType = SubvectorData<CSAs...>;
4939  //**********************************************************************************************
4940 
4941  public:
4942  //**Type definitions****************************************************************************
4944  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
4945 
4946  using BaseType = DenseVector<This,TF>;
4947  using ViewedType = CPE;
4948  using ResultType = SubvectorTrait_t<RT,CSAs...>;
4949  using TransposeType = TransposeType_t<ResultType>;
4950  using ElementType = ElementType_t<CPE>;
4951  using ReturnType = ReturnType_t<CPE>;
4952  using CompositeType = const ResultType;
4953  //**********************************************************************************************
4954 
4955  //**Compilation flags***************************************************************************
4957  static constexpr bool simdEnabled = false;
4958 
4960  static constexpr bool smpAssignable = false;
4961  //**********************************************************************************************
4962 
4963  //**Constructor*********************************************************************************
4970  template< typename... RSAs > // Optional subvector arguments
4971  explicit inline Subvector( const CPE& vector, RSAs... args )
4972  : DataType( args... ) // Base class initialization
4973  , vector_ ( vector ) // The dense vector/sparse vector cross product expression
4974  {
4975  if( Contains_v< TypeList<RSAs...>, Unchecked > ) {
4976  if( offset() + size() > vector.size() ) {
4977  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
4978  }
4979  }
4980  else {
4981  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
4982  }
4983  }
4984  //**********************************************************************************************
4985 
4986  //**Subscript operator**************************************************************************
4992  inline ReturnType operator[]( size_t index ) const {
4993  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4994  return vector_[offset()+index];
4995  }
4996  //**********************************************************************************************
4997 
4998  //**At function*********************************************************************************
5005  inline ReturnType at( size_t index ) const {
5006  if( index >= size() ) {
5007  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5008  }
5009  return (*this)[index];
5010  }
5011  //**********************************************************************************************
5012 
5013  //**********************************************************************************************
5014  using DataType::offset;
5015  using DataType::size;
5016  //**********************************************************************************************
5017 
5018  //**Operand access******************************************************************************
5023  inline CPE operand() const noexcept {
5024  return vector_;
5025  }
5026  //**********************************************************************************************
5027 
5028  //**********************************************************************************************
5034  template< typename T >
5035  inline bool canAlias( const T* alias ) const noexcept {
5036  return vector_.canAlias( alias );
5037  }
5038  //**********************************************************************************************
5039 
5040  //**********************************************************************************************
5046  template< typename T >
5047  inline bool isAliased( const T* alias ) const noexcept {
5048  return vector_.isAliased( alias );
5049  }
5050  //**********************************************************************************************
5051 
5052  private:
5053  //**Member variables****************************************************************************
5054  CPE vector_;
5055  //**********************************************************************************************
5056 };
5058 //*************************************************************************************************
5059 
5060 
5061 
5062 
5063 
5064 
5065 
5066 
5067 //=================================================================================================
5068 //
5069 // CLASS TEMPLATE SPECIALIZATION FOR SVECDVECCROSSEXPR
5070 //
5071 //=================================================================================================
5072 
5073 //*************************************************************************************************
5081 template< typename VT1 // Type of the left-hand side sparse vector
5082  , typename VT2 // Type of the right-hand side dense vector
5083  , bool TF // Transpose flag
5084  , size_t... CSAs > // Compile time subvector arguments
5085 class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
5086  : public View< DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
5087  , private SubvectorData<CSAs...>
5088 {
5089  private:
5090  //**Type definitions****************************************************************************
5091  using CPE = SVecDVecCrossExpr<VT1,VT2,TF>;
5092  using RT = ResultType_t<CPE>;
5093  using DataType = SubvectorData<CSAs...>;
5094  //**********************************************************************************************
5095 
5096  public:
5097  //**Type definitions****************************************************************************
5099  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
5100 
5101  using BaseType = DenseVector<This,TF>;
5102  using ViewedType = CPE;
5103  using ResultType = SubvectorTrait_t<RT,CSAs...>;
5104  using TransposeType = TransposeType_t<ResultType>;
5105  using ElementType = ElementType_t<CPE>;
5106  using ReturnType = ReturnType_t<CPE>;
5107  using CompositeType = const ResultType;
5108  //**********************************************************************************************
5109 
5110  //**Compilation flags***************************************************************************
5112  static constexpr bool simdEnabled = false;
5113 
5115  static constexpr bool smpAssignable = false;
5116  //**********************************************************************************************
5117 
5118  //**Constructor*********************************************************************************
5125  template< typename... RSAs > // Optional subvector arguments
5126  explicit inline Subvector( const CPE& vector, RSAs... args )
5127  : DataType( args... ) // Base class initialization
5128  , vector_ ( vector ) // The sparse vector/dense vector cross product expression
5129  {
5130  if( Contains_v< TypeList<RSAs...>, Unchecked > ) {
5131  if( offset() + size() > vector.size() ) {
5132  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
5133  }
5134  }
5135  else {
5136  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
5137  }
5138  }
5139  //**********************************************************************************************
5140 
5141  //**Subscript operator**************************************************************************
5147  inline ReturnType operator[]( size_t index ) const {
5148  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5149  return vector_[offset()+index];
5150  }
5151  //**********************************************************************************************
5152 
5153  //**At function*********************************************************************************
5160  inline ReturnType at( size_t index ) const {
5161  if( index >= size() ) {
5162  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5163  }
5164  return (*this)[index];
5165  }
5166  //**********************************************************************************************
5167 
5168  //**********************************************************************************************
5169  using DataType::offset;
5170  using DataType::size;
5171  //**********************************************************************************************
5172 
5173  //**Operand access******************************************************************************
5178  inline CPE operand() const noexcept {
5179  return vector_;
5180  }
5181  //**********************************************************************************************
5182 
5183  //**********************************************************************************************
5189  template< typename T >
5190  inline bool canAlias( const T* alias ) const noexcept {
5191  return vector_.canAlias( alias );
5192  }
5193  //**********************************************************************************************
5194 
5195  //**********************************************************************************************
5201  template< typename T >
5202  inline bool isAliased( const T* alias ) const noexcept {
5203  return vector_.isAliased( alias );
5204  }
5205  //**********************************************************************************************
5206 
5207  private:
5208  //**Member variables****************************************************************************
5209  CPE vector_;
5210  //**********************************************************************************************
5211 };
5213 //*************************************************************************************************
5214 
5215 
5216 
5217 
5218 
5219 
5220 
5221 
5222 //=================================================================================================
5223 //
5224 // CLASS TEMPLATE SPECIALIZATION FOR SVECSVECCROSSEXPR
5225 //
5226 //=================================================================================================
5227 
5228 //*************************************************************************************************
5236 template< typename VT1 // Type of the left-hand side sparse vector
5237  , typename VT2 // Type of the right-hand side sparse vector
5238  , bool TF // Transpose flag
5239  , size_t... CSAs > // Compile time subvector arguments
5240 class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
5241  : public View< DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
5242  , private SubvectorData<CSAs...>
5243 {
5244  private:
5245  //**Type definitions****************************************************************************
5246  using CPE = SVecSVecCrossExpr<VT1,VT2,TF>;
5247  using RT = ResultType_t<CPE>;
5248  using DataType = SubvectorData<CSAs...>;
5249  //**********************************************************************************************
5250 
5251  public:
5252  //**Type definitions****************************************************************************
5254  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
5255 
5256  using BaseType = DenseVector<This,TF>;
5257  using ViewedType = CPE;
5258  using ResultType = SubvectorTrait_t<RT,CSAs...>;
5259  using TransposeType = TransposeType_t<ResultType>;
5260  using ElementType = ElementType_t<CPE>;
5261  using ReturnType = ReturnType_t<CPE>;
5262  using CompositeType = const ResultType;
5263  //**********************************************************************************************
5264 
5265  //**Compilation flags***************************************************************************
5267  static constexpr bool simdEnabled = false;
5268 
5270  static constexpr bool smpAssignable = false;
5271  //**********************************************************************************************
5272 
5273  //**Constructor*********************************************************************************
5280  template< typename... RSAs > // Optional subvector arguments
5281  explicit inline Subvector( const CPE& vector, RSAs... args )
5282  : DataType( args... ) // Base class initialization
5283  , vector_ ( vector ) // The sparse vector/sparse vector cross product expression
5284  {
5285  if( Contains_v< TypeList<RSAs...>, Unchecked > ) {
5286  if( offset() + size() > vector.size() ) {
5287  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
5288  }
5289  }
5290  else {
5291  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
5292  }
5293  }
5294  //**********************************************************************************************
5295 
5296  //**Subscript operator**************************************************************************
5302  inline ReturnType operator[]( size_t index ) const {
5303  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5304  return vector_[offset()+index];
5305  }
5306  //**********************************************************************************************
5307 
5308  //**At function*********************************************************************************
5315  inline ReturnType at( size_t index ) const {
5316  if( index >= size() ) {
5317  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5318  }
5319  return (*this)[index];
5320  }
5321  //**********************************************************************************************
5322 
5323  //**********************************************************************************************
5324  using DataType::offset;
5325  using DataType::size;
5326  //**********************************************************************************************
5327 
5328  //**Operand access******************************************************************************
5333  inline CPE operand() const noexcept {
5334  return vector_;
5335  }
5336  //**********************************************************************************************
5337 
5338  //**********************************************************************************************
5344  template< typename T >
5345  inline bool canAlias( const T* alias ) const noexcept {
5346  return vector_.canAlias( alias );
5347  }
5348  //**********************************************************************************************
5349 
5350  //**********************************************************************************************
5356  template< typename T >
5357  inline bool isAliased( const T* alias ) const {
5358  return vector_.isAliased( alias );
5359  }
5360  //**********************************************************************************************
5361 
5362  private:
5363  //**Member variables****************************************************************************
5364  CPE vector_;
5365  //**********************************************************************************************
5366 };
5368 //*************************************************************************************************
5369 
5370 } // namespace blaze
5371 
5372 #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.
constexpr bool IsContiguous_v
Auxiliary variable template for the IsContiguous type trait.The IsContiguous_v variable template prov...
Definition: IsContiguous.h:145
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:354
Header file for the alignment flag values.
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr 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:750
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:169
Header file for the View base class.
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:188
#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:332
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3077
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3079
Header file for the DenseVector base class.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3084
constexpr bool IsReference_v
Auxiliary variable template for the IsReference type trait.The IsReference_v variable template provid...
Definition: IsReference.h:95
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
Header file for the Computation base class.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3085
#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
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
STL namespace.
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:482
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:416
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
auto smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:220
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.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
Header file for the DisableIf class template.
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3083
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 the If class template.
Header file for the implementation of a vector representation of an initializer list.
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:189
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3080
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
constexpr bool HasSIMDDiv_v
Auxiliary variable template for the HasSIMDDiv type trait.The HasSIMDDiv_v variable template provides...
Definition: HasSIMDDiv.h:172
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:370
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:446
Header file for the implementation of the Subvector base template.
Header file for the implementation of the SubvectorData class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:253
Header file for the subvector trait.
Header file for all SIMD functionality.
constexpr bool Contains_v
Auxiliary variable template for the Contains type trait.The Contains_v variable template provides a c...
Definition: Contains.h:139
Constraint on the data type.
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
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.
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
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:8908
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
Constraint on the data type.
Header file for all forward declarations for expression class templates.
typename SubvectorTrait< VT, CSAs... >::Type SubvectorTrait_t
Auxiliary alias declaration for the SubvectorTrait type trait.The SubvectorTrait_t alias declaration ...
Definition: SubvectorTrait.h:171
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:611
Header file for the CrossExpr base class.
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
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.
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
Header file for the Unique class template.
Header file for the IsContiguous type trait.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance...
Definition: Check.h:96
Header file for the cache size of the target architecture.
Header file for the isDefault shim.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
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:408
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
constexpr 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:718
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
#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
#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
Header file for the HasSIMDDiv type trait.
Flag for unaligned vectors and matrices.
Definition: AlignmentFlag.h:64
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3082
Header file for the alignment check function.
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:188
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:290
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
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
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
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
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:191
Header file for the clear shim.
Header file for the IsExpression type trait class.