Blaze  3.6
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/shims/Reset.h>
63 #include <blaze/math/SIMD.h>
76 #include <blaze/math/views/Check.h>
79 #include <blaze/system/CacheSize.h>
81 #include <blaze/system/Inline.h>
85 #include <blaze/util/Assert.h>
87 #include <blaze/util/DisableIf.h>
88 #include <blaze/util/EnableIf.h>
89 #include <blaze/util/mpl/If.h>
90 #include <blaze/util/TypeList.h>
91 #include <blaze/util/Types.h>
93 
94 
95 namespace blaze {
96 
97 //=================================================================================================
98 //
99 // CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED DENSE SUBVECTORS
100 //
101 //=================================================================================================
102 
103 //*************************************************************************************************
111 template< typename VT // Type of the dense vector
112  , bool TF // Transpose flag
113  , size_t... CSAs > // Compile time subvector arguments
114 class Subvector<VT,unaligned,TF,true,CSAs...>
115  : public View< DenseVector< Subvector<VT,unaligned,TF,true,CSAs...>, TF > >
116  , private SubvectorData<CSAs...>
117 {
118  private:
119  //**Type definitions****************************************************************************
120  using DataType = SubvectorData<CSAs...>;
121  using Operand = If_t< IsExpression_v<VT>, VT, VT& >;
122  //**********************************************************************************************
123 
124  public:
125  //**Type definitions****************************************************************************
127  using This = Subvector<VT,unaligned,TF,true,CSAs...>;
128 
129  using BaseType = DenseVector<This,TF>;
130  using ViewedType = VT;
131  using ResultType = SubvectorTrait_t<VT,CSAs...>;
132  using TransposeType = TransposeType_t<ResultType>;
133  using ElementType = ElementType_t<VT>;
134  using SIMDType = SIMDTrait_t<ElementType>;
135  using ReturnType = ReturnType_t<VT>;
136  using CompositeType = const Subvector&;
137 
139  using ConstReference = ConstReference_t<VT>;
140 
142  using Reference = If_t< IsConst_v<VT>, ConstReference, Reference_t<VT> >;
143 
145  using ConstPointer = ConstPointer_t<VT>;
146 
148  using Pointer = If_t< IsConst_v<VT> || !HasMutableDataAccess_v<VT>, ConstPointer, Pointer_t<VT> >;
149  //**********************************************************************************************
150 
151  //**SubvectorIterator class definition**********************************************************
154  template< typename IteratorType > // Type of the dense vector iterator
155  class SubvectorIterator
156  {
157  public:
158  //**Type definitions*************************************************************************
160  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
161 
163  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
164 
166  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
167 
169  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
170 
172  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
173 
174  // STL iterator requirements
175  using iterator_category = IteratorCategory;
176  using value_type = ValueType;
177  using pointer = PointerType;
178  using reference = ReferenceType;
179  using difference_type = DifferenceType;
180  //*******************************************************************************************
181 
182  //**Constructor******************************************************************************
185  inline BLAZE_DEVICE_CALLABLE SubvectorIterator()
186  : iterator_ ( ) // Iterator to the current subvector element
187  , isAligned_( false ) // Memory alignment flag
188  {}
189  //*******************************************************************************************
190 
191  //**Constructor******************************************************************************
197  inline BLAZE_DEVICE_CALLABLE SubvectorIterator( IteratorType iterator, bool isMemoryAligned )
198  : iterator_ ( iterator ) // Iterator to the current subvector element
199  , isAligned_( isMemoryAligned ) // Memory alignment flag
200  {}
201  //*******************************************************************************************
202 
203  //**Constructor******************************************************************************
208  template< typename IteratorType2 >
209  inline BLAZE_DEVICE_CALLABLE SubvectorIterator( const SubvectorIterator<IteratorType2>& it )
210  : iterator_ ( it.base() ) // Iterator to the current subvector element
211  , isAligned_( it.isAligned() ) // Memory alignment flag
212  {}
213  //*******************************************************************************************
214 
215  //**Addition assignment operator*************************************************************
221  inline BLAZE_DEVICE_CALLABLE SubvectorIterator& operator+=( size_t inc ) {
222  iterator_ += inc;
223  return *this;
224  }
225  //*******************************************************************************************
226 
227  //**Subtraction assignment operator**********************************************************
233  inline BLAZE_DEVICE_CALLABLE SubvectorIterator& operator-=( size_t dec ) {
234  iterator_ -= dec;
235  return *this;
236  }
237  //*******************************************************************************************
238 
239  //**Prefix increment operator****************************************************************
244  inline BLAZE_DEVICE_CALLABLE SubvectorIterator& operator++() {
245  ++iterator_;
246  return *this;
247  }
248  //*******************************************************************************************
249 
250  //**Postfix increment operator***************************************************************
255  inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator++( int ) {
256  return SubvectorIterator( iterator_++, isAligned_ );
257  }
258  //*******************************************************************************************
259 
260  //**Prefix decrement operator****************************************************************
265  inline BLAZE_DEVICE_CALLABLE SubvectorIterator& operator--() {
266  --iterator_;
267  return *this;
268  }
269  //*******************************************************************************************
270 
271  //**Postfix decrement operator***************************************************************
276  inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator--( int ) {
277  return SubvectorIterator( iterator_--, isAligned_ );
278  }
279  //*******************************************************************************************
280 
281  //**Element access operator******************************************************************
286  inline BLAZE_DEVICE_CALLABLE ReferenceType operator*() const {
287  return *iterator_;
288  }
289  //*******************************************************************************************
290 
291  //**Element access operator******************************************************************
296  inline BLAZE_DEVICE_CALLABLE IteratorType operator->() const {
297  return iterator_;
298  }
299  //*******************************************************************************************
300 
301  //**Load function****************************************************************************
311  inline SIMDType load() const {
312  if( isAligned_ ) {
313  return loada();
314  }
315  else {
316  return loadu();
317  }
318  }
319  //*******************************************************************************************
320 
321  //**Loada function***************************************************************************
331  inline SIMDType loada() const {
332  return iterator_.loada();
333  }
334  //*******************************************************************************************
335 
336  //**Loadu function***************************************************************************
346  inline SIMDType loadu() const {
347  return iterator_.loadu();
348  }
349  //*******************************************************************************************
350 
351  //**Store function***************************************************************************
362  inline void store( const SIMDType& value ) const {
363  if( isAligned_ ) {
364  storea( value );
365  }
366  else {
367  storeu( value );
368  }
369  }
370  //*******************************************************************************************
371 
372  //**Storea function**************************************************************************
383  inline void storea( const SIMDType& value ) const {
384  iterator_.storea( value );
385  }
386  //*******************************************************************************************
387 
388  //**Storeu function**************************************************************************
399  inline void storeu( const SIMDType& value ) const {
400  iterator_.storeu( value );
401  }
402  //*******************************************************************************************
403 
404  //**Stream function**************************************************************************
415  inline void stream( const SIMDType& value ) const {
416  iterator_.stream( value );
417  }
418  //*******************************************************************************************
419 
420  //**Equality operator************************************************************************
426  inline BLAZE_DEVICE_CALLABLE bool operator==( const SubvectorIterator& rhs ) const {
427  return iterator_ == rhs.iterator_;
428  }
429  //*******************************************************************************************
430 
431  //**Inequality operator**********************************************************************
437  inline BLAZE_DEVICE_CALLABLE bool operator!=( const SubvectorIterator& rhs ) const {
438  return iterator_ != rhs.iterator_;
439  }
440  //*******************************************************************************************
441 
442  //**Less-than operator***********************************************************************
448  inline BLAZE_DEVICE_CALLABLE bool operator<( const SubvectorIterator& rhs ) const {
449  return iterator_ < rhs.iterator_;
450  }
451  //*******************************************************************************************
452 
453  //**Greater-than operator********************************************************************
459  inline BLAZE_DEVICE_CALLABLE bool operator>( const SubvectorIterator& rhs ) const {
460  return iterator_ > rhs.iterator_;
461  }
462  //*******************************************************************************************
463 
464  //**Less-or-equal-than operator**************************************************************
470  inline BLAZE_DEVICE_CALLABLE bool operator<=( const SubvectorIterator& rhs ) const {
471  return iterator_ <= rhs.iterator_;
472  }
473  //*******************************************************************************************
474 
475  //**Greater-or-equal-than operator***********************************************************
481  inline BLAZE_DEVICE_CALLABLE bool operator>=( const SubvectorIterator& rhs ) const {
482  return iterator_ >= rhs.iterator_;
483  }
484  //*******************************************************************************************
485 
486  //**Subtraction operator*********************************************************************
492  inline BLAZE_DEVICE_CALLABLE DifferenceType operator-( const SubvectorIterator& rhs ) const {
493  return iterator_ - rhs.iterator_;
494  }
495  //*******************************************************************************************
496 
497  //**Addition operator************************************************************************
504  friend inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator+( const SubvectorIterator& it, size_t inc ) {
505  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
506  }
507  //*******************************************************************************************
508 
509  //**Addition operator************************************************************************
516  friend inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator+( size_t inc, const SubvectorIterator& it ) {
517  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
518  }
519  //*******************************************************************************************
520 
521  //**Subtraction operator*********************************************************************
528  friend inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator-( const SubvectorIterator& it, size_t dec ) {
529  return SubvectorIterator( it.iterator_ - dec, it.isAligned_ );
530  }
531  //*******************************************************************************************
532 
533  //**Base function****************************************************************************
538  inline BLAZE_DEVICE_CALLABLE IteratorType base() const {
539  return iterator_;
540  }
541  //*******************************************************************************************
542 
543  //**IsAligned function***********************************************************************
548  inline bool isAligned() const {
549  return isAligned_;
550  }
551  //*******************************************************************************************
552 
553  private:
554  //**Member variables*************************************************************************
555  IteratorType iterator_;
556  bool isAligned_;
557  //*******************************************************************************************
558  };
559  //**********************************************************************************************
560 
561  //**Type definitions****************************************************************************
563  using ConstIterator = SubvectorIterator< ConstIterator_t<VT> >;
564 
566  using Iterator = If_t< IsConst_v<VT>, ConstIterator, SubvectorIterator< Iterator_t<VT> > >;
567  //**********************************************************************************************
568 
569  //**Compilation flags***************************************************************************
571  static constexpr bool simdEnabled = VT::simdEnabled;
572 
574  static constexpr bool smpAssignable = VT::smpAssignable;
575 
577  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
578  //**********************************************************************************************
579 
580  //**Constructors********************************************************************************
583  template< typename... RSAs >
584  explicit inline Subvector( VT& vector, RSAs... args );
585 
586  Subvector( const Subvector& ) = default;
588  //**********************************************************************************************
589 
590  //**Destructor**********************************************************************************
593  ~Subvector() = default;
595  //**********************************************************************************************
596 
597  //**Data access functions***********************************************************************
600  inline Reference operator[]( size_t index );
601  inline ConstReference operator[]( size_t index ) const;
602  inline Reference at( size_t index );
603  inline ConstReference at( size_t index ) const;
604  inline Pointer data () noexcept;
605  inline ConstPointer data () const noexcept;
606  inline Iterator begin ();
607  inline ConstIterator begin () const;
608  inline ConstIterator cbegin() const;
609  inline Iterator end ();
610  inline ConstIterator end () const;
611  inline ConstIterator cend () const;
613  //**********************************************************************************************
614 
615  //**Assignment operators************************************************************************
618  inline Subvector& operator= ( const ElementType& rhs );
619  inline Subvector& operator= ( initializer_list<ElementType> list );
620  inline Subvector& operator= ( const Subvector& rhs );
621  template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
622  template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
623  template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
624  template< typename VT2 > inline Subvector& operator*=( const Vector<VT2,TF>& rhs );
625  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
626  template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
628  //**********************************************************************************************
629 
630  //**Utility functions***************************************************************************
633  using DataType::offset;
634  using DataType::size;
635 
636  inline VT& operand() noexcept;
637  inline const VT& operand() const noexcept;
638 
639  inline size_t spacing() const noexcept;
640  inline size_t capacity() const noexcept;
641  inline size_t nonZeros() const;
642  inline void reset();
644  //**********************************************************************************************
645 
646  //**Numeric functions***************************************************************************
649  template< typename Other > inline Subvector& scale( const Other& scalar );
651  //**********************************************************************************************
652 
653  private:
654  //**********************************************************************************************
656  template< typename VT2 >
657  static constexpr bool VectorizedAssign_v =
658  ( useOptimizedKernels &&
659  simdEnabled && VT2::simdEnabled &&
660  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > );
661  //**********************************************************************************************
662 
663  //**********************************************************************************************
665  template< typename VT2 >
666  static constexpr bool VectorizedAddAssign_v =
667  ( useOptimizedKernels &&
668  simdEnabled && VT2::simdEnabled &&
669  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > &&
670  HasSIMDAdd_v< ElementType, ElementType_t<VT2> > );
671  //**********************************************************************************************
672 
673  //**********************************************************************************************
675  template< typename VT2 >
676  static constexpr bool VectorizedSubAssign_v =
677  ( useOptimizedKernels &&
678  simdEnabled && VT2::simdEnabled &&
679  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > &&
680  HasSIMDSub_v< ElementType, ElementType_t<VT2> > );
681  //**********************************************************************************************
682 
683  //**********************************************************************************************
685  template< typename VT2 >
686  static constexpr bool VectorizedMultAssign_v =
687  ( useOptimizedKernels &&
688  simdEnabled && VT2::simdEnabled &&
689  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > &&
690  HasSIMDMult_v< ElementType, ElementType_t<VT2> > );
691  //**********************************************************************************************
692 
693  //**********************************************************************************************
695  template< typename VT2 >
696  static constexpr bool VectorizedDivAssign_v =
697  ( useOptimizedKernels &&
698  simdEnabled && VT2::simdEnabled &&
699  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > &&
700  HasSIMDDiv_v< ElementType, ElementType_t<VT2> > );
701  //**********************************************************************************************
702 
703  //**SIMD properties*****************************************************************************
705  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
706  //**********************************************************************************************
707 
708  public:
709  //**Expression template evaluation functions****************************************************
712  template< typename Other >
713  inline bool canAlias( const Other* alias ) const noexcept;
714 
715  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
716  inline bool canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
717 
718  template< typename Other >
719  inline bool isAliased( const Other* alias ) const noexcept;
720 
721  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
722  inline bool isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
723 
724  inline bool isAligned () const noexcept;
725  inline bool canSMPAssign() const noexcept;
726 
727  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
728  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
729  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
730 
731  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
732  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
733  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
734  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
735 
736  template< typename VT2 >
737  inline auto assign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT2> >;
738 
739  template< typename VT2 >
740  inline auto assign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT2> >;
741 
742  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
743 
744  template< typename VT2 >
745  inline auto addAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT2> >;
746 
747  template< typename VT2 >
748  inline auto addAssign ( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT2> >;
749 
750  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
751 
752  template< typename VT2 >
753  inline auto subAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT2> >;
754 
755  template< typename VT2 >
756  inline auto subAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT2> >;
757 
758  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
759 
760  template< typename VT2 >
761  inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT2> >;
762 
763  template< typename VT2 >
764  inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT2> >;
765 
766  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
767 
768  template< typename VT2 >
769  inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT2> >;
770 
771  template< typename VT2 >
772  inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT2> >;
774  //**********************************************************************************************
775 
776  private:
777  //**Member variables****************************************************************************
780  Operand vector_;
781  const bool isAligned_;
782 
789  //**********************************************************************************************
790 
791  //**Friend declarations*************************************************************************
792  template< typename VT2, AlignmentFlag AF2, bool TF2, bool DF2, size_t... CSAs2 > friend class Subvector;
793  //**********************************************************************************************
794 
795  //**Compile time checks*************************************************************************
801  //**********************************************************************************************
802 };
804 //*************************************************************************************************
805 
806 
807 
808 
809 //=================================================================================================
810 //
811 // CONSTRUCTORS
812 //
813 //=================================================================================================
814 
815 //*************************************************************************************************
829 template< typename VT // Type of the dense vector
830  , bool TF // Transpose flag
831  , size_t... CSAs > // Compile time subvector arguments
832 template< typename... RSAs > // Runtime subvector arguments
833 inline Subvector<VT,unaligned,TF,true,CSAs...>::Subvector( VT& vector, RSAs... args )
834  : DataType ( args... ) // Base class initialization
835  , vector_ ( vector ) // The vector containing the subvector
836  , isAligned_( simdEnabled && IsContiguous_v<VT> &&
837  vector.data() != nullptr && checkAlignment( data() ) )
838 {
839  if( !Contains_v< TypeList<RSAs...>, Unchecked > ) {
840  if( offset() + size() > vector.size() ) {
841  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
842  }
843  }
844  else {
845  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
846  }
847 }
849 //*************************************************************************************************
850 
851 
852 
853 
854 //=================================================================================================
855 //
856 // DATA ACCESS FUNCTIONS
857 //
858 //=================================================================================================
859 
860 //*************************************************************************************************
870 template< typename VT // Type of the dense vector
871  , bool TF // Transpose flag
872  , size_t... CSAs > // Compile time subvector arguments
873 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Reference
874  Subvector<VT,unaligned,TF,true,CSAs...>::operator[]( size_t index )
875 {
876  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
877  return vector_[offset()+index];
878 }
880 //*************************************************************************************************
881 
882 
883 //*************************************************************************************************
893 template< typename VT // Type of the dense vector
894  , bool TF // Transpose flag
895  , size_t... CSAs > // Compile time subvector arguments
896 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstReference
897  Subvector<VT,unaligned,TF,true,CSAs...>::operator[]( size_t index ) const
898 {
899  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
900  return const_cast<const VT&>( vector_ )[offset()+index];
901 }
903 //*************************************************************************************************
904 
905 
906 //*************************************************************************************************
917 template< typename VT // Type of the dense vector
918  , bool TF // Transpose flag
919  , size_t... CSAs > // Compile time subvector arguments
920 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Reference
921  Subvector<VT,unaligned,TF,true,CSAs...>::at( size_t index )
922 {
923  if( index >= size() ) {
924  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
925  }
926  return (*this)[index];
927 }
929 //*************************************************************************************************
930 
931 
932 //*************************************************************************************************
943 template< typename VT // Type of the dense vector
944  , bool TF // Transpose flag
945  , size_t... CSAs > // Compile time subvector arguments
946 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstReference
947  Subvector<VT,unaligned,TF,true,CSAs...>::at( size_t index ) const
948 {
949  if( index >= size() ) {
950  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
951  }
952  return (*this)[index];
953 }
955 //*************************************************************************************************
956 
957 
958 //*************************************************************************************************
966 template< typename VT // Type of the dense vector
967  , bool TF // Transpose flag
968  , size_t... CSAs > // Compile time subvector arguments
969 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Pointer
971 {
972  return vector_.data() + offset();
973 }
975 //*************************************************************************************************
976 
977 
978 //*************************************************************************************************
986 template< typename VT // Type of the dense vector
987  , bool TF // Transpose flag
988  , size_t... CSAs > // Compile time subvector arguments
989 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstPointer
991 {
992  return vector_.data() + offset();
993 }
995 //*************************************************************************************************
996 
997 
998 //*************************************************************************************************
1006 template< typename VT // Type of the dense vector
1007  , bool TF // Transpose flag
1008  , size_t... CSAs > // Compile time subvector arguments
1009 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Iterator
1011 {
1012  return Iterator( vector_.begin() + offset(), isAligned_ );
1013 }
1015 //*************************************************************************************************
1016 
1017 
1018 //*************************************************************************************************
1026 template< typename VT // Type of the dense vector
1027  , bool TF // Transpose flag
1028  , size_t... CSAs > // Compile time subvector arguments
1029 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1031 {
1032  return ConstIterator( vector_.cbegin() + offset(), isAligned_ );
1033 }
1035 //*************************************************************************************************
1036 
1037 
1038 //*************************************************************************************************
1046 template< typename VT // Type of the dense vector
1047  , bool TF // Transpose flag
1048  , size_t... CSAs > // Compile time subvector arguments
1049 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1051 {
1052  return ConstIterator( vector_.cbegin() + offset(), isAligned_ );
1053 }
1055 //*************************************************************************************************
1056 
1057 
1058 //*************************************************************************************************
1066 template< typename VT // Type of the dense vector
1067  , bool TF // Transpose flag
1068  , size_t... CSAs > // Compile time subvector arguments
1069 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Iterator
1071 {
1072  return Iterator( vector_.begin() + offset() + size(), isAligned_ );
1073 }
1075 //*************************************************************************************************
1076 
1077 
1078 //*************************************************************************************************
1086 template< typename VT // Type of the dense vector
1087  , bool TF // Transpose flag
1088  , size_t... CSAs > // Compile time subvector arguments
1089 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1091 {
1092  return ConstIterator( vector_.cbegin() + offset() + size(), isAligned_ );
1093 }
1095 //*************************************************************************************************
1096 
1097 
1098 //*************************************************************************************************
1106 template< typename VT // Type of the dense vector
1107  , bool TF // Transpose flag
1108  , size_t... CSAs > // Compile time subvector arguments
1109 inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1111 {
1112  return ConstIterator( vector_.cbegin() + offset() + size(), isAligned_ );
1113 }
1115 //*************************************************************************************************
1116 
1117 
1118 
1119 
1120 //=================================================================================================
1121 //
1122 // ASSIGNMENT OPERATORS
1123 //
1124 //=================================================================================================
1125 
1126 //*************************************************************************************************
1133 template< typename VT // Type of the dense vector
1134  , bool TF // Transpose flag
1135  , size_t... CSAs > // Compile time subvector arguments
1136 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1137  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const ElementType& rhs )
1138 {
1139  const size_t iend( offset() + size() );
1140  decltype(auto) left( derestrict( vector_ ) );
1141 
1142  for( size_t i=offset(); i<iend; ++i ) {
1143  if( !IsRestricted_v<VT> || trySet( vector_, i, rhs ) )
1144  left[i] = rhs;
1145  }
1146 
1147  return *this;
1148 }
1150 //*************************************************************************************************
1151 
1152 
1153 //*************************************************************************************************
1169 template< typename VT // Type of the dense vector
1170  , bool TF // Transpose flag
1171  , size_t... CSAs > // Compile time subvector arguments
1172 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1173  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( initializer_list<ElementType> list )
1174 {
1175  if( list.size() > size() ) {
1176  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
1177  }
1178 
1179  if( IsRestricted_v<VT> ) {
1180  const InitializerVector<ElementType,TF> tmp( list, size() );
1181  if( !tryAssign( vector_, tmp, offset() ) ) {
1182  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1183  }
1184  }
1185 
1186  decltype(auto) left( derestrict( *this ) );
1187 
1188  std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
1189 
1190  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1191 
1192  return *this;
1193 }
1195 //*************************************************************************************************
1196 
1197 
1198 //*************************************************************************************************
1210 template< typename VT // Type of the dense vector
1211  , bool TF // Transpose flag
1212  , size_t... CSAs > // Compile time subvector arguments
1213 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1214  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const Subvector& rhs )
1215 {
1218 
1219  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset() == rhs.offset() ) )
1220  return *this;
1221 
1222  if( size() != rhs.size() ) {
1223  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
1224  }
1225 
1226  if( !tryAssign( vector_, rhs, offset() ) ) {
1227  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1228  }
1229 
1230  decltype(auto) left( derestrict( *this ) );
1231 
1232  if( rhs.canAlias( &vector_ ) ) {
1233  const ResultType tmp( rhs );
1234  smpAssign( left, tmp );
1235  }
1236  else {
1237  smpAssign( left, rhs );
1238  }
1239 
1240  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1241 
1242  return *this;
1243 }
1245 //*************************************************************************************************
1246 
1247 
1248 //*************************************************************************************************
1260 template< typename VT // Type of the dense vector
1261  , bool TF // Transpose flag
1262  , size_t... CSAs > // Compile time subvector arguments
1263 template< typename VT2 > // Type of the right-hand side vector
1264 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1265  Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const Vector<VT2,TF>& rhs )
1266 {
1267  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1268  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1269 
1270  if( size() != (~rhs).size() ) {
1271  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1272  }
1273 
1274  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1275  Right right( ~rhs );
1276 
1277  if( !tryAssign( vector_, right, offset() ) ) {
1278  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1279  }
1280 
1281  decltype(auto) left( derestrict( *this ) );
1282 
1283  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1284  const ResultType_t<VT2> tmp( right );
1285  smpAssign( left, tmp );
1286  }
1287  else {
1288  if( IsSparseVector_v<VT2> )
1289  reset();
1290  smpAssign( left, right );
1291  }
1292 
1293  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1294 
1295  return *this;
1296 }
1298 //*************************************************************************************************
1299 
1300 
1301 //*************************************************************************************************
1313 template< typename VT // Type of the dense vector
1314  , bool TF // Transpose flag
1315  , size_t... CSAs > // Compile time subvector arguments
1316 template< typename VT2 > // Type of the right-hand side vector
1317 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1318  Subvector<VT,unaligned,TF,true,CSAs...>::operator+=( const Vector<VT2,TF>& rhs )
1319 {
1320  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1321  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1322 
1323  if( size() != (~rhs).size() ) {
1324  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1325  }
1326 
1327  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1328  Right right( ~rhs );
1329 
1330  if( !tryAddAssign( vector_, right, offset() ) ) {
1331  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1332  }
1333 
1334  decltype(auto) left( derestrict( *this ) );
1335 
1336  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1337  const ResultType_t<VT2> tmp( right );
1338  smpAddAssign( left, tmp );
1339  }
1340  else {
1341  smpAddAssign( left, right );
1342  }
1343 
1344  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1345 
1346  return *this;
1347 }
1349 //*************************************************************************************************
1350 
1351 
1352 //*************************************************************************************************
1364 template< typename VT // Type of the dense vector
1365  , bool TF // Transpose flag
1366  , size_t... CSAs > // Compile time subvector arguments
1367 template< typename VT2 > // Type of the right-hand side vector
1368 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1369  Subvector<VT,unaligned,TF,true,CSAs...>::operator-=( const Vector<VT2,TF>& rhs )
1370 {
1371  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1372  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1373 
1374  if( size() != (~rhs).size() ) {
1375  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1376  }
1377 
1378  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1379  Right right( ~rhs );
1380 
1381  if( !trySubAssign( vector_, right, offset() ) ) {
1382  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1383  }
1384 
1385  decltype(auto) left( derestrict( *this ) );
1386 
1387  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1388  const ResultType_t<VT2> tmp( right );
1389  smpSubAssign( left, tmp );
1390  }
1391  else {
1392  smpSubAssign( left, right );
1393  }
1394 
1395  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1396 
1397  return *this;
1398 }
1400 //*************************************************************************************************
1401 
1402 
1403 //*************************************************************************************************
1416 template< typename VT // Type of the dense vector
1417  , bool TF // Transpose flag
1418  , size_t... CSAs > // Compile time subvector arguments
1419 template< typename VT2 > // Type of the right-hand side vector
1420 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1421  Subvector<VT,unaligned,TF,true,CSAs...>::operator*=( const Vector<VT2,TF>& rhs )
1422 {
1423  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1424  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1425 
1426  if( size() != (~rhs).size() ) {
1427  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1428  }
1429 
1430  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1431  Right right( ~rhs );
1432 
1433  if( !tryMultAssign( vector_, right, offset() ) ) {
1434  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1435  }
1436 
1437  decltype(auto) left( derestrict( *this ) );
1438 
1439  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1440  const ResultType_t<VT2> tmp( right );
1441  smpMultAssign( left, tmp );
1442  }
1443  else {
1444  smpMultAssign( left, right );
1445  }
1446 
1447  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1448 
1449  return *this;
1450 }
1452 //*************************************************************************************************
1453 
1454 
1455 //*************************************************************************************************
1467 template< typename VT // Type of the dense vector
1468  , bool TF // Transpose flag
1469  , size_t... CSAs > // Compile time subvector arguments
1470 template< typename VT2 > // Type of the right-hand side dense vector
1471 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1472  Subvector<VT,unaligned,TF,true,CSAs...>::operator/=( const DenseVector<VT2,TF>& rhs )
1473 {
1474  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1475  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1476 
1477  if( size() != (~rhs).size() ) {
1478  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1479  }
1480 
1481  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1482  Right right( ~rhs );
1483 
1484  if( !tryDivAssign( vector_, right, offset() ) ) {
1485  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1486  }
1487 
1488  decltype(auto) left( derestrict( *this ) );
1489 
1490  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
1491  const ResultType_t<VT2> tmp( right );
1492  smpDivAssign( left, tmp );
1493  }
1494  else {
1495  smpDivAssign( left, right );
1496  }
1497 
1498  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1499 
1500  return *this;
1501 }
1503 //*************************************************************************************************
1504 
1505 
1506 //*************************************************************************************************
1519 template< typename VT // Type of the dense vector
1520  , bool TF // Transpose flag
1521  , size_t... CSAs > // Compile time subvector arguments
1522 template< typename VT2 > // Type of the right-hand side vector
1523 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1524  Subvector<VT,unaligned,TF,true,CSAs...>::operator%=( const Vector<VT2,TF>& rhs )
1525 {
1526  using blaze::assign;
1527 
1528  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
1529  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
1530 
1531  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT2> >;
1532 
1536 
1537  if( size() != 3UL || (~rhs).size() != 3UL ) {
1538  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1539  }
1540 
1541  const CrossType tmp( *this % (~rhs) );
1542 
1543  if( !tryAssign( vector_, tmp, offset() ) ) {
1544  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1545  }
1546 
1547  decltype(auto) left( derestrict( *this ) );
1548 
1549  assign( left, tmp );
1550 
1551  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1552 
1553  return *this;
1554 }
1556 //*************************************************************************************************
1557 
1558 
1559 
1560 
1561 //=================================================================================================
1562 //
1563 // UTILITY FUNCTIONS
1564 //
1565 //=================================================================================================
1566 
1567 //*************************************************************************************************
1573 template< typename VT // Type of the dense vector
1574  , bool TF // Transpose flag
1575  , size_t... CSAs > // Compile time subvector arguments
1576 inline VT& Subvector<VT,unaligned,TF,true,CSAs...>::operand() noexcept
1577 {
1578  return vector_;
1579 }
1581 //*************************************************************************************************
1582 
1583 
1584 //*************************************************************************************************
1590 template< typename VT // Type of the dense vector
1591  , bool TF // Transpose flag
1592  , size_t... CSAs > // Compile time subvector arguments
1593 inline const VT& Subvector<VT,unaligned,TF,true,CSAs...>::operand() const noexcept
1594 {
1595  return vector_;
1596 }
1598 //*************************************************************************************************
1599 
1600 
1601 //*************************************************************************************************
1610 template< typename VT // Type of the dense vector
1611  , bool TF // Transpose flag
1612  , size_t... CSAs > // Compile time subvector arguments
1613 inline size_t Subvector<VT,unaligned,TF,true,CSAs...>::spacing() const noexcept
1614 {
1615  return vector_.spacing() - offset();
1616 }
1618 //*************************************************************************************************
1619 
1620 
1621 //*************************************************************************************************
1627 template< typename VT // Type of the dense vector
1628  , bool TF // Transpose flag
1629  , size_t... CSAs > // Compile time subvector arguments
1630 inline size_t Subvector<VT,unaligned,TF,true,CSAs...>::capacity() const noexcept
1631 {
1632  return vector_.capacity() - offset();
1633 }
1635 //*************************************************************************************************
1636 
1637 
1638 //*************************************************************************************************
1647 template< typename VT // Type of the dense vector
1648  , bool TF // Transpose flag
1649  , size_t... CSAs > // Compile time subvector arguments
1651 {
1652  size_t nonzeros( 0 );
1653 
1654  const size_t iend( offset() + size() );
1655  for( size_t i=offset(); i<iend; ++i ) {
1656  if( !isDefault( vector_[i] ) )
1657  ++nonzeros;
1658  }
1659 
1660  return nonzeros;
1661 }
1663 //*************************************************************************************************
1664 
1665 
1666 //*************************************************************************************************
1672 template< typename VT // Type of the dense vector
1673  , bool TF // Transpose flag
1674  , size_t... CSAs > // Compile time subvector arguments
1676 {
1677  using blaze::clear;
1678 
1679  const size_t iend( offset() + size() );
1680  for( size_t i=offset(); i<iend; ++i )
1681  clear( vector_[i] );
1682 }
1684 //*************************************************************************************************
1685 
1686 
1687 
1688 
1689 //=================================================================================================
1690 //
1691 // NUMERIC FUNCTIONS
1692 //
1693 //=================================================================================================
1694 
1695 //*************************************************************************************************
1706 template< typename VT // Type of the dense vector
1707  , bool TF // Transpose flag
1708  , size_t... CSAs > // Compile time subvector arguments
1709 template< typename Other > // Data type of the scalar value
1710 inline Subvector<VT,unaligned,TF,true,CSAs...>&
1711  Subvector<VT,unaligned,TF,true,CSAs...>::scale( const Other& scalar )
1712 {
1713  const size_t iend( offset() + size() );
1714  for( size_t i=offset(); i<iend; ++i )
1715  vector_[i] *= scalar;
1716  return *this;
1717 }
1719 //*************************************************************************************************
1720 
1721 
1722 
1723 
1724 //=================================================================================================
1725 //
1726 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1727 //
1728 //=================================================================================================
1729 
1730 //*************************************************************************************************
1741 template< typename VT // Type of the dense vector
1742  , bool TF // Transpose flag
1743  , size_t... CSAs > // Compile time subvector arguments
1744 template< typename Other > // Data type of the foreign expression
1745 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::canAlias( const Other* alias ) const noexcept
1746 {
1747  return vector_.isAliased( alias );
1748 }
1750 //*************************************************************************************************
1751 
1752 
1753 //*************************************************************************************************
1764 template< typename VT // Type of the dense vector
1765  , bool TF // Transpose flag
1766  , size_t... CSAs > // Compile time subvector arguments
1767 template< typename VT2 // Data type of the foreign dense subvector
1768  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
1769  , bool TF2 // Transpose flag of the foreign dense subvector
1770  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
1771 inline bool
1772  Subvector<VT,unaligned,TF,true,CSAs...>::canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
1773 {
1774  return ( vector_.isAliased( &alias->vector_ ) &&
1775  ( offset() + size() > alias->offset() ) &&
1776  ( offset() < alias->offset() + alias->size() ) );
1777 }
1779 //*************************************************************************************************
1780 
1781 
1782 //*************************************************************************************************
1793 template< typename VT // Type of the dense vector
1794  , bool TF // Transpose flag
1795  , size_t... CSAs > // Compile time subvector arguments
1796 template< typename Other > // Data type of the foreign expression
1797 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::isAliased( const Other* alias ) const noexcept
1798 {
1799  return vector_.isAliased( alias );
1800 }
1802 //*************************************************************************************************
1803 
1804 
1805 //*************************************************************************************************
1816 template< typename VT // Type of the dense vector
1817  , bool TF // Transpose flag
1818  , size_t... CSAs > // Compile time subvector arguments
1819 template< typename VT2 // Data type of the foreign dense subvector
1820  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
1821  , bool TF2 // Transpose flag of the foreign dense subvector
1822  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
1823 inline bool
1824  Subvector<VT,unaligned,TF,true,CSAs...>::isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
1825 {
1826  return ( vector_.isAliased( &alias->vector_ ) &&
1827  ( offset() + size() > alias->offset() ) &&
1828  ( offset() < alias->offset() + alias->size() ) );
1829 }
1831 //*************************************************************************************************
1832 
1833 
1834 //*************************************************************************************************
1844 template< typename VT // Type of the dense vector
1845  , bool TF // Transpose flag
1846  , size_t... CSAs > // Compile time subvector arguments
1847 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::isAligned() const noexcept
1848 {
1849  return isAligned_;
1850 }
1852 //*************************************************************************************************
1853 
1854 
1855 //*************************************************************************************************
1866 template< typename VT // Type of the dense vector
1867  , bool TF // Transpose flag
1868  , size_t... CSAs > // Compile time subvector arguments
1869 inline bool Subvector<VT,unaligned,TF,true,CSAs...>::canSMPAssign() const noexcept
1870 {
1871  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1872 }
1874 //*************************************************************************************************
1875 
1876 
1877 //*************************************************************************************************
1891 template< typename VT // Type of the dense vector
1892  , bool TF // Transpose flag
1893  , size_t... CSAs > // Compile time subvector arguments
1894 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1895  Subvector<VT,unaligned,TF,true,CSAs...>::load( size_t index ) const noexcept
1896 {
1897  if( isAligned_ )
1898  return loada( index );
1899  else
1900  return loadu( index );
1901 }
1903 //*************************************************************************************************
1904 
1905 
1906 //*************************************************************************************************
1920 template< typename VT // Type of the dense vector
1921  , bool TF // Transpose flag
1922  , size_t... CSAs > // Compile time subvector arguments
1923 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1924  Subvector<VT,unaligned,TF,true,CSAs...>::loada( size_t index ) const noexcept
1925 {
1927 
1928  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1929  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1930  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1931 
1932  return vector_.loada( offset()+index );
1933 }
1935 //*************************************************************************************************
1936 
1937 
1938 //*************************************************************************************************
1952 template< typename VT // Type of the dense vector
1953  , bool TF // Transpose flag
1954  , size_t... CSAs > // Compile time subvector arguments
1955 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1956  Subvector<VT,unaligned,TF,true,CSAs...>::loadu( size_t index ) const noexcept
1957 {
1959 
1960  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1961  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1962 
1963  return vector_.loadu( offset()+index );
1964 }
1966 //*************************************************************************************************
1967 
1968 
1969 //*************************************************************************************************
1984 template< typename VT // Type of the dense vector
1985  , bool TF // Transpose flag
1986  , size_t... CSAs > // Compile time subvector arguments
1988  Subvector<VT,unaligned,TF,true,CSAs...>::store( size_t index, const SIMDType& value ) noexcept
1989 {
1990  if( isAligned_ )
1991  storea( index, value );
1992  else
1993  storeu( index, value );
1994 }
1996 //*************************************************************************************************
1997 
1998 
1999 //*************************************************************************************************
2014 template< typename VT // Type of the dense vector
2015  , bool TF // Transpose flag
2016  , size_t... CSAs > // Compile time subvector arguments
2018  Subvector<VT,unaligned,TF,true,CSAs...>::storea( size_t index, const SIMDType& value ) noexcept
2019 {
2021 
2022  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2023  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2024  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2025 
2026  vector_.storea( offset()+index, value );
2027 }
2029 //*************************************************************************************************
2030 
2031 
2032 //*************************************************************************************************
2047 template< typename VT // Type of the dense vector
2048  , bool TF // Transpose flag
2049  , size_t... CSAs > // Compile time subvector arguments
2051  Subvector<VT,unaligned,TF,true,CSAs...>::storeu( size_t index, const SIMDType& value ) noexcept
2052 {
2054 
2055  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2056  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2057 
2058  vector_.storeu( offset()+index, value );
2059 }
2061 //*************************************************************************************************
2062 
2063 
2064 //*************************************************************************************************
2079 template< typename VT // Type of the dense vector
2080  , bool TF // Transpose flag
2081  , size_t... CSAs > // Compile time subvector arguments
2083  Subvector<VT,unaligned,TF,true,CSAs...>::stream( size_t index, const SIMDType& value ) noexcept
2084 {
2086 
2087  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2088  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2089  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2090 
2091  if( isAligned_ )
2092  vector_.stream( offset()+index, value );
2093  else
2094  vector_.storeu( offset()+index, value );
2095 }
2097 //*************************************************************************************************
2098 
2099 
2100 //*************************************************************************************************
2112 template< typename VT // Type of the dense vector
2113  , bool TF // Transpose flag
2114  , size_t... CSAs > // Compile time subvector arguments
2115 template< typename VT2 > // Type of the right-hand side dense vector
2116 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
2117  -> DisableIf_t< VectorizedAssign_v<VT2> >
2118 {
2119  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2120 
2121  const size_t ipos( size() & size_t(-2) );
2122  for( size_t i=0UL; i<ipos; i+=2UL ) {
2123  vector_[offset()+i ] = (~rhs)[i ];
2124  vector_[offset()+i+1UL] = (~rhs)[i+1UL];
2125  }
2126  if( ipos < size() ) {
2127  vector_[offset()+ipos] = (~rhs)[ipos];
2128  }
2129 }
2131 //*************************************************************************************************
2132 
2133 
2134 //*************************************************************************************************
2146 template< typename VT // Type of the dense vector
2147  , bool TF // Transpose flag
2148  , size_t... CSAs > // Compile time subvector arguments
2149 template< typename VT2 > // Type of the right-hand side dense vector
2150 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
2151  -> EnableIf_t< VectorizedAssign_v<VT2> >
2152 {
2154 
2155  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2156 
2157  const size_t ipos( size() & size_t(-SIMDSIZE) );
2158  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2159 
2160  size_t i( 0UL );
2161  Iterator left( begin() );
2162  ConstIterator_t<VT2> right( (~rhs).begin() );
2163 
2164  if( useStreaming && isAligned_ &&
2165  ( size() > ( cacheSize/( sizeof(ElementType) * 3UL ) ) ) &&
2166  !(~rhs).isAliased( &vector_ ) )
2167  {
2168  for( ; i<ipos; i+=SIMDSIZE ) {
2169  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2170  }
2171  for( ; i<size(); ++i ) {
2172  *left = *right;
2173  }
2174  }
2175  else
2176  {
2177  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2178  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2179  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2180  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2181  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2182  }
2183  for( ; i<ipos; i+=SIMDSIZE ) {
2184  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2185  }
2186  for( ; i<size(); ++i ) {
2187  *left = *right; ++left; ++right;
2188  }
2189  }
2190 }
2192 //*************************************************************************************************
2193 
2194 
2195 //*************************************************************************************************
2207 template< typename VT // Type of the dense vector
2208  , bool TF // Transpose flag
2209  , size_t... CSAs > // Compile time subvector arguments
2210 template< typename VT2 > // Type of the right-hand side sparse vector
2211 inline void Subvector<VT,unaligned,TF,true,CSAs...>::assign( const SparseVector<VT2,TF>& rhs )
2212 {
2213  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2214 
2215  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2216  vector_[offset()+element->index()] = element->value();
2217 }
2219 //*************************************************************************************************
2220 
2221 
2222 //*************************************************************************************************
2234 template< typename VT // Type of the dense vector
2235  , bool TF // Transpose flag
2236  , size_t... CSAs > // Compile time subvector arguments
2237 template< typename VT2 > // Type of the right-hand side dense vector
2238 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
2239  -> DisableIf_t< VectorizedAddAssign_v<VT2> >
2240 {
2241  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2242 
2243  const size_t ipos( size() & size_t(-2) );
2244  for( size_t i=0UL; i<ipos; i+=2UL ) {
2245  vector_[offset()+i ] += (~rhs)[i ];
2246  vector_[offset()+i+1UL] += (~rhs)[i+1UL];
2247  }
2248  if( ipos < size() ) {
2249  vector_[offset()+ipos] += (~rhs)[ipos];
2250  }
2251 }
2253 //*************************************************************************************************
2254 
2255 
2256 //*************************************************************************************************
2268 template< typename VT // Type of the dense vector
2269  , bool TF // Transpose flag
2270  , size_t... CSAs > // Compile time subvector arguments
2271 template< typename VT2 > // Type of the right-hand side dense vector
2272 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
2273  -> EnableIf_t< VectorizedAddAssign_v<VT2> >
2274 {
2276 
2277  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2278 
2279  const size_t ipos( size() & size_t(-SIMDSIZE) );
2280  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2281 
2282  size_t i( 0UL );
2283  Iterator left( begin() );
2284  ConstIterator_t<VT2> right( (~rhs).begin() );
2285 
2286  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2287  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2288  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2289  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2290  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2291  }
2292  for( ; i<ipos; i+=SIMDSIZE ) {
2293  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2294  }
2295  for( ; i<size(); ++i ) {
2296  *left += *right; ++left; ++right;
2297  }
2298 }
2300 //*************************************************************************************************
2301 
2302 
2303 //*************************************************************************************************
2315 template< typename VT // Type of the dense vector
2316  , bool TF // Transpose flag
2317  , size_t... CSAs > // Compile time subvector arguments
2318 template< typename VT2 > // Type of the right-hand side sparse vector
2319 inline void Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const SparseVector<VT2,TF>& rhs )
2320 {
2321  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2322 
2323  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2324  vector_[offset()+element->index()] += element->value();
2325 }
2327 //*************************************************************************************************
2328 
2329 
2330 //*************************************************************************************************
2342 template< typename VT // Type of the dense vector
2343  , bool TF // Transpose flag
2344  , size_t... CSAs > // Compile time subvector arguments
2345 template< typename VT2 > // Type of the right-hand side dense vector
2346 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
2347  -> DisableIf_t< VectorizedSubAssign_v<VT2> >
2348 {
2349  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2350 
2351  const size_t ipos( size() & size_t(-2) );
2352  for( size_t i=0UL; i<ipos; i+=2UL ) {
2353  vector_[offset()+i ] -= (~rhs)[i ];
2354  vector_[offset()+i+1UL] -= (~rhs)[i+1UL];
2355  }
2356  if( ipos < size() ) {
2357  vector_[offset()+ipos] -= (~rhs)[ipos];
2358  }
2359 }
2361 //*************************************************************************************************
2362 
2363 
2364 //*************************************************************************************************
2376 template< typename VT // Type of the dense vector
2377  , bool TF // Transpose flag
2378  , size_t... CSAs > // Compile time subvector arguments
2379 template< typename VT2 > // Type of the right-hand side dense vector
2380 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
2381  -> EnableIf_t< VectorizedSubAssign_v<VT2> >
2382 {
2384 
2385  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2386 
2387  const size_t ipos( size() & size_t(-SIMDSIZE) );
2388  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2389 
2390  size_t i( 0UL );
2391  Iterator left( begin() );
2392  ConstIterator_t<VT2> right( (~rhs).begin() );
2393 
2394  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2395  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2396  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2397  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2398  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2399  }
2400  for( ; i<ipos; i+=SIMDSIZE ) {
2401  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2402  }
2403  for( ; i<size(); ++i ) {
2404  *left -= *right; ++left; ++right;
2405  }
2406 }
2408 //*************************************************************************************************
2409 
2410 
2411 //*************************************************************************************************
2423 template< typename VT // Type of the dense vector
2424  , bool TF // Transpose flag
2425  , size_t... CSAs > // Compile time subvector arguments
2426 template< typename VT2 > // Type of the right-hand side sparse vector
2427 inline void Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const SparseVector<VT2,TF>& rhs )
2428 {
2429  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2430 
2431  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2432  vector_[offset()+element->index()] -= element->value();
2433 }
2435 //*************************************************************************************************
2436 
2437 
2438 //*************************************************************************************************
2450 template< typename VT // Type of the dense vector
2451  , bool TF // Transpose flag
2452  , size_t... CSAs > // Compile time subvector arguments
2453 template< typename VT2 > // Type of the right-hand side dense vector
2454 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
2455  -> DisableIf_t< VectorizedMultAssign_v<VT2> >
2456 {
2457  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2458 
2459  const size_t ipos( size() & size_t(-2) );
2460  for( size_t i=0UL; i<ipos; i+=2UL ) {
2461  vector_[offset()+i ] *= (~rhs)[i ];
2462  vector_[offset()+i+1UL] *= (~rhs)[i+1UL];
2463  }
2464  if( ipos < size() ) {
2465  vector_[offset()+ipos] *= (~rhs)[ipos];
2466  }
2467 }
2469 //*************************************************************************************************
2470 
2471 
2472 //*************************************************************************************************
2484 template< typename VT // Type of the dense vector
2485  , bool TF // Transpose flag
2486  , size_t... CSAs > // Compile time subvector arguments
2487 template< typename VT2 > // Type of the right-hand side dense vector
2488 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
2489  -> EnableIf_t< VectorizedMultAssign_v<VT2> >
2490 {
2492 
2493  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2494 
2495  const size_t ipos( size() & size_t(-SIMDSIZE) );
2496  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2497 
2498  size_t i( 0UL );
2499  Iterator left( begin() );
2500  ConstIterator_t<VT2> right( (~rhs).begin() );
2501 
2502  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2503  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2504  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2505  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2506  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2507  }
2508  for( ; i<ipos; i+=SIMDSIZE ) {
2509  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2510  }
2511  for( ; i<size(); ++i ) {
2512  *left *= *right; ++left; ++right;
2513  }
2514 }
2516 //*************************************************************************************************
2517 
2518 
2519 //*************************************************************************************************
2531 template< typename VT // Type of the dense vector
2532  , bool TF // Transpose flag
2533  , size_t... CSAs > // Compile time subvector arguments
2534 template< typename VT2 > // Type of the right-hand side sparse vector
2535 inline void Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const SparseVector<VT2,TF>& rhs )
2536 {
2537  using blaze::reset;
2538 
2539  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2540 
2541  size_t i( 0UL );
2542 
2543  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2544  const size_t index( element->index() );
2545  for( ; i<index; ++i )
2546  reset( vector_[offset()+i] );
2547  vector_[offset()+i] *= element->value();
2548  ++i;
2549  }
2550 
2551  for( ; i<size(); ++i ) {
2552  reset( vector_[offset()+i] );
2553  }
2554 }
2556 //*************************************************************************************************
2557 
2558 
2559 //*************************************************************************************************
2571 template< typename VT // Type of the dense vector
2572  , bool TF // Transpose flag
2573  , size_t... CSAs > // Compile time subvector arguments
2574 template< typename VT2 > // Type of the right-hand side dense vector
2575 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
2576  -> DisableIf_t< VectorizedDivAssign_v<VT2> >
2577 {
2578  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2579 
2580  const size_t ipos( size() & size_t(-2) );
2581  for( size_t i=0UL; i<ipos; i+=2UL ) {
2582  vector_[offset()+i ] /= (~rhs)[i ];
2583  vector_[offset()+i+1UL] /= (~rhs)[i+1UL];
2584  }
2585  if( ipos < size() ) {
2586  vector_[offset()+ipos] /= (~rhs)[ipos];
2587  }
2588 }
2590 //*************************************************************************************************
2591 
2592 
2593 //*************************************************************************************************
2605 template< typename VT // Type of the dense vector
2606  , bool TF // Transpose flag
2607  , size_t... CSAs > // Compile time subvector arguments
2608 template< typename VT2 > // Type of the right-hand side dense vector
2609 inline auto Subvector<VT,unaligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
2610  -> EnableIf_t< VectorizedDivAssign_v<VT2> >
2611 {
2613 
2614  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2615 
2616  const size_t ipos( size() & size_t(-SIMDSIZE) );
2617  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2618 
2619  size_t i( 0UL );
2620  Iterator left( begin() );
2621  ConstIterator_t<VT2> right( (~rhs).begin() );
2622 
2623  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2624  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2625  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2626  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2627  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2628  }
2629  for( ; i<ipos; i+=SIMDSIZE ) {
2630  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2631  }
2632  for( ; i<size(); ++i ) {
2633  *left /= *right; ++left; ++right;
2634  }
2635 }
2637 //*************************************************************************************************
2638 
2639 
2640 
2641 
2642 
2643 
2644 
2645 
2646 //=================================================================================================
2647 //
2648 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED DENSE SUBVECTORS
2649 //
2650 //=================================================================================================
2651 
2652 //*************************************************************************************************
2660 template< typename VT // Type of the dense vector
2661  , bool TF // Transpose flag
2662  , size_t... CSAs > // Compile time subvector arguments
2663 class Subvector<VT,aligned,TF,true,CSAs...>
2664  : public View< DenseVector< Subvector<VT,aligned,TF,true,CSAs...>, TF > >
2665  , private SubvectorData<CSAs...>
2666 {
2667  private:
2668  //**Type definitions****************************************************************************
2669  using DataType = SubvectorData<CSAs...>;
2670  using Operand = If_t< IsExpression_v<VT>, VT, VT& >;
2671  //**********************************************************************************************
2672 
2673  public:
2674  //**Type definitions****************************************************************************
2676  using This = Subvector<VT,aligned,TF,true,CSAs...>;
2677 
2678  using BaseType = DenseVector<This,TF>;
2679  using ViewedType = VT;
2680  using ResultType = SubvectorTrait_t<VT,CSAs...>;
2681  using TransposeType = TransposeType_t<ResultType>;
2682  using ElementType = ElementType_t<VT>;
2683  using SIMDType = SIMDTrait_t<ElementType>;
2684  using ReturnType = ReturnType_t<VT>;
2685  using CompositeType = const Subvector&;
2686 
2688  using ConstReference = ConstReference_t<VT>;
2689 
2691  using Reference = If_t< IsConst_v<VT>, ConstReference, Reference_t<VT> >;
2692 
2694  using ConstPointer = ConstPointer_t<VT>;
2695 
2697  using Pointer = If_t< IsConst_v<VT> || !HasMutableDataAccess_v<VT>, ConstPointer, Pointer_t<VT> >;
2698 
2700  using ConstIterator = ConstIterator_t<VT>;
2701 
2703  using Iterator = If_t< IsConst_v<VT>, ConstIterator, Iterator_t<VT> >;
2704  //**********************************************************************************************
2705 
2706  //**Compilation flags***************************************************************************
2708  static constexpr bool simdEnabled = VT::simdEnabled;
2709 
2711  static constexpr bool smpAssignable = VT::smpAssignable;
2712 
2714  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2715  //**********************************************************************************************
2716 
2717  //**Constructors********************************************************************************
2720  template< typename... RSAs >
2721  explicit inline Subvector( VT& vector, RSAs... args );
2722 
2723  Subvector( const Subvector& ) = default;
2725  //**********************************************************************************************
2726 
2727  //**Destructor**********************************************************************************
2730  ~Subvector() = default;
2732  //**********************************************************************************************
2733 
2734  //**Data access functions***********************************************************************
2737  inline Reference operator[]( size_t index );
2738  inline ConstReference operator[]( size_t index ) const;
2739  inline Reference at( size_t index );
2740  inline ConstReference at( size_t index ) const;
2741  inline Pointer data () noexcept;
2742  inline ConstPointer data () const noexcept;
2743  inline Iterator begin ();
2744  inline ConstIterator begin () const;
2745  inline ConstIterator cbegin() const;
2746  inline Iterator end ();
2747  inline ConstIterator end () const;
2748  inline ConstIterator cend () const;
2750  //**********************************************************************************************
2751 
2752  //**Assignment operators************************************************************************
2755  inline Subvector& operator= ( const ElementType& rhs );
2756  inline Subvector& operator= ( initializer_list<ElementType> list );
2757  inline Subvector& operator= ( const Subvector& rhs );
2758  template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
2759  template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
2760  template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
2761  template< typename VT2 > inline Subvector& operator*=( const Vector<VT2,TF>& rhs );
2762  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2763  template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
2765  //**********************************************************************************************
2766 
2767  //**Utility functions***************************************************************************
2770  using DataType::offset;
2771  using DataType::size;
2772 
2773  inline VT& operand() noexcept;
2774  inline const VT& operand() const noexcept;
2775 
2776  inline size_t spacing() const noexcept;
2777  inline size_t capacity() const noexcept;
2778  inline size_t nonZeros() const;
2779  inline void reset();
2781  //**********************************************************************************************
2782 
2783  //**Numeric functions***************************************************************************
2786  template< typename Other > inline Subvector& scale( const Other& scalar );
2788  //**********************************************************************************************
2789 
2790  private:
2791  //**********************************************************************************************
2793  template< typename VT2 >
2794  static constexpr bool VectorizedAssign_v =
2795  ( useOptimizedKernels &&
2796  simdEnabled && VT2::simdEnabled &&
2797  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > );
2798  //**********************************************************************************************
2799 
2800  //**********************************************************************************************
2802  template< typename VT2 >
2803  static constexpr bool VectorizedAddAssign_v =
2804  ( useOptimizedKernels &&
2805  simdEnabled && VT2::simdEnabled &&
2806  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > &&
2807  HasSIMDAdd_v< ElementType, ElementType_t<VT2> > );
2808  //**********************************************************************************************
2809 
2810  //**********************************************************************************************
2812  template< typename VT2 >
2813  static constexpr bool VectorizedSubAssign_v =
2814  ( useOptimizedKernels &&
2815  simdEnabled && VT2::simdEnabled &&
2816  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > &&
2817  HasSIMDSub_v< ElementType, ElementType_t<VT2> > );
2818  //**********************************************************************************************
2819 
2820  //**********************************************************************************************
2822  template< typename VT2 >
2823  static constexpr bool VectorizedMultAssign_v =
2824  ( useOptimizedKernels &&
2825  simdEnabled && VT2::simdEnabled &&
2826  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > &&
2827  HasSIMDMult_v< ElementType, ElementType_t<VT2> > );
2828  //**********************************************************************************************
2829 
2830  //**********************************************************************************************
2832  template< typename VT2 >
2833  static constexpr bool VectorizedDivAssign_v =
2834  ( useOptimizedKernels &&
2835  simdEnabled && VT2::simdEnabled &&
2836  IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > &&
2837  HasSIMDDiv_v< ElementType, ElementType_t<VT2> > );
2838  //**********************************************************************************************
2839 
2840  //**SIMD properties*****************************************************************************
2842  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
2843  //**********************************************************************************************
2844 
2845  public:
2846  //**Expression template evaluation functions****************************************************
2849  template< typename Other >
2850  inline bool canAlias( const Other* alias ) const noexcept;
2851 
2852  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
2853  inline bool canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
2854 
2855  template< typename Other >
2856  inline bool isAliased( const Other* alias ) const noexcept;
2857 
2858  template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
2859  inline bool isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
2860 
2861  inline bool isAligned () const noexcept;
2862  inline bool canSMPAssign() const noexcept;
2863 
2864  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
2865  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
2866  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
2867 
2868  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
2869  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
2870  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
2871  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
2872 
2873  template< typename VT2 >
2874  inline auto assign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT2> >;
2875 
2876  template< typename VT2 >
2877  inline auto assign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT2> >;
2878 
2879  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
2880 
2881  template< typename VT2 >
2882  inline auto addAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT2> >;
2883 
2884  template< typename VT2 >
2885  inline auto addAssign ( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT2> >;
2886 
2887  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
2888 
2889  template< typename VT2 >
2890  inline auto subAssign ( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT2> >;
2891 
2892  template< typename VT2 >
2893  inline auto subAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT2> >;
2894 
2895  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
2896 
2897  template< typename VT2 >
2898  inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT2> >;
2899 
2900  template< typename VT2 >
2901  inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT2> >;
2902 
2903  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
2904 
2905  template< typename VT2 >
2906  inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT2> >;
2907 
2908  template< typename VT2 >
2909  inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT2> >;
2911  //**********************************************************************************************
2912 
2913  private:
2914  //**Member variables****************************************************************************
2917  Operand vector_;
2918 
2919  //**********************************************************************************************
2920 
2921  //**Friend declarations*************************************************************************
2922  template< typename VT2, AlignmentFlag AF2, bool TF2, bool DF2, size_t... CSAs2 > friend class Subvector;
2923  //**********************************************************************************************
2924 
2925  //**Compile time checks*************************************************************************
2931  //**********************************************************************************************
2932 };
2934 //*************************************************************************************************
2935 
2936 
2937 
2938 
2939 //=================================================================================================
2940 //
2941 // CONSTRUCTORS
2942 //
2943 //=================================================================================================
2944 
2945 //*************************************************************************************************
2959 template< typename VT // Type of the dense vector
2960  , bool TF // Transpose flag
2961  , size_t... CSAs > // Compile time subvector arguments
2962 template< typename... RSAs > // Runtime subvector arguments
2963 inline Subvector<VT,aligned,TF,true,CSAs...>::Subvector( VT& vector, RSAs... args )
2964  : DataType( args... ) // Base class initialization
2965  , vector_ ( vector ) // The vector containing the subvector
2966 {
2967  if( !Contains_v< TypeList<RSAs...>, Unchecked > )
2968  {
2969  if( offset() + size() > vector.size() ) {
2970  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
2971  }
2972 
2973  if( simdEnabled && IsContiguous_v<VT> && !checkAlignment( data() ) ) {
2974  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector alignment" );
2975  }
2976  }
2977  else
2978  {
2979  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
2980  BLAZE_USER_ASSERT( !simdEnabled || !IsContiguous_v<VT> || checkAlignment( data() ), "Invalid subvector alignment" );
2981  }
2982 }
2984 //*************************************************************************************************
2985 
2986 
2987 
2988 
2989 //=================================================================================================
2990 //
2991 // DATA ACCESS FUNCTIONS
2992 //
2993 //=================================================================================================
2994 
2995 //*************************************************************************************************
3002 template< typename VT // Type of the dense vector
3003  , bool TF // Transpose flag
3004  , size_t... CSAs > // Compile time subvector arguments
3005 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Reference
3006  Subvector<VT,aligned,TF,true,CSAs...>::operator[]( size_t index )
3007 {
3008  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
3009  return vector_[offset()+index];
3010 }
3012 //*************************************************************************************************
3013 
3014 
3015 //*************************************************************************************************
3022 template< typename VT // Type of the dense vector
3023  , bool TF // Transpose flag
3024  , size_t... CSAs > // Compile time subvector arguments
3025 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstReference
3026  Subvector<VT,aligned,TF,true,CSAs...>::operator[]( size_t index ) const
3027 {
3028  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
3029  return const_cast<const VT&>( vector_ )[offset()+index];
3030 }
3032 //*************************************************************************************************
3033 
3034 
3035 //*************************************************************************************************
3046 template< typename VT // Type of the dense vector
3047  , bool TF // Transpose flag
3048  , size_t... CSAs > // Compile time subvector arguments
3049 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Reference
3050  Subvector<VT,aligned,TF,true,CSAs...>::at( size_t index )
3051 {
3052  if( index >= size() ) {
3053  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3054  }
3055  return (*this)[index];
3056 }
3058 //*************************************************************************************************
3059 
3060 
3061 //*************************************************************************************************
3072 template< typename VT // Type of the dense vector
3073  , bool TF // Transpose flag
3074  , size_t... CSAs > // Compile time subvector arguments
3075 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstReference
3076  Subvector<VT,aligned,TF,true,CSAs...>::at( size_t index ) const
3077 {
3078  if( index >= size() ) {
3079  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3080  }
3081  return (*this)[index];
3082 }
3084 //*************************************************************************************************
3085 
3086 
3087 //*************************************************************************************************
3095 template< typename VT // Type of the dense vector
3096  , bool TF // Transpose flag
3097  , size_t... CSAs > // Compile time subvector arguments
3098 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Pointer
3100 {
3101  return vector_.data() + offset();
3102 }
3104 //*************************************************************************************************
3105 
3106 
3107 //*************************************************************************************************
3115 template< typename VT // Type of the dense vector
3116  , bool TF // Transpose flag
3117  , size_t... CSAs > // Compile time subvector arguments
3118 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstPointer
3120 {
3121  return vector_.data() + offset();
3122 }
3124 //*************************************************************************************************
3125 
3126 
3127 //*************************************************************************************************
3135 template< typename VT // Type of the dense vector
3136  , bool TF // Transpose flag
3137  , size_t... CSAs > // Compile time subvector arguments
3138 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Iterator
3140 {
3141  return ( vector_.begin() + offset() );
3142 }
3144 //*************************************************************************************************
3145 
3146 
3147 //*************************************************************************************************
3155 template< typename VT // Type of the dense vector
3156  , bool TF // Transpose flag
3157  , size_t... CSAs > // Compile time subvector arguments
3158 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3160 {
3161  return ( vector_.cbegin() + offset() );
3162 }
3164 //*************************************************************************************************
3165 
3166 
3167 //*************************************************************************************************
3175 template< typename VT // Type of the dense vector
3176  , bool TF // Transpose flag
3177  , size_t... CSAs > // Compile time subvector arguments
3178 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3180 {
3181  return ( vector_.cbegin() + offset() );
3182 }
3184 //*************************************************************************************************
3185 
3186 
3187 //*************************************************************************************************
3195 template< typename VT // Type of the dense vector
3196  , bool TF // Transpose flag
3197  , size_t... CSAs > // Compile time subvector arguments
3198 inline typename Subvector<VT,aligned,TF,true,CSAs...>::Iterator
3200 {
3201  return ( vector_.begin() + offset() + size() );
3202 }
3204 //*************************************************************************************************
3205 
3206 
3207 //*************************************************************************************************
3215 template< typename VT // Type of the dense vector
3216  , bool TF // Transpose flag
3217  , size_t... CSAs > // Compile time subvector arguments
3218 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3220 {
3221  return ( vector_.cbegin() + offset() + size() );
3222 }
3224 //*************************************************************************************************
3225 
3226 
3227 //*************************************************************************************************
3235 template< typename VT // Type of the dense vector
3236  , bool TF // Transpose flag
3237  , size_t... CSAs > // Compile time subvector arguments
3238 inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3240 {
3241  return ( vector_.cbegin() + offset() + size() );
3242 }
3244 //*************************************************************************************************
3245 
3246 
3247 
3248 
3249 //=================================================================================================
3250 //
3251 // ASSIGNMENT OPERATORS
3252 //
3253 //=================================================================================================
3254 
3255 //*************************************************************************************************
3262 template< typename VT // Type of the dense vector
3263  , bool TF // Transpose flag
3264  , size_t... CSAs > // Compile time subvector arguments
3265 inline Subvector<VT,aligned,TF,true,CSAs...>&
3266  Subvector<VT,aligned,TF,true,CSAs...>::operator=( const ElementType& rhs )
3267 {
3268  const size_t iend( offset() + size() );
3269  decltype(auto) left( derestrict( vector_ ) );
3270 
3271  for( size_t i=offset(); i<iend; ++i ) {
3272  if( !IsRestricted_v<VT> || trySet( vector_, i, rhs ) )
3273  left[i] = rhs;
3274  }
3275 
3276  return *this;
3277 }
3279 //*************************************************************************************************
3280 
3281 
3282 //*************************************************************************************************
3295 template< typename VT // Type of the dense vector
3296  , bool TF // Transpose flag
3297  , size_t... CSAs > // Compile time subvector arguments
3298 inline Subvector<VT,aligned,TF,true,CSAs...>&
3299  Subvector<VT,aligned,TF,true,CSAs...>::operator=( initializer_list<ElementType> list )
3300 {
3301  if( list.size() > size() ) {
3302  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
3303  }
3304 
3305  if( IsRestricted_v<VT> ) {
3306  const InitializerVector<ElementType,TF> tmp( list, size() );
3307  if( !tryAssign( vector_, tmp, offset() ) ) {
3308  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3309  }
3310  }
3311 
3312  decltype(auto) left( derestrict( *this ) );
3313 
3314  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
3315 
3316  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3317 
3318  return *this;
3319 }
3321 //*************************************************************************************************
3322 
3323 
3324 //*************************************************************************************************
3336 template< typename VT // Type of the dense vector
3337  , bool TF // Transpose flag
3338  , size_t... CSAs > // Compile time subvector arguments
3339 inline Subvector<VT,aligned,TF,true,CSAs...>&
3340  Subvector<VT,aligned,TF,true,CSAs...>::operator=( const Subvector& rhs )
3341 {
3344 
3345  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset() == rhs.offset() ) )
3346  return *this;
3347 
3348  if( size() != rhs.size() ) {
3349  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
3350  }
3351 
3352  if( !tryAssign( vector_, rhs, offset() ) ) {
3353  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3354  }
3355 
3356  decltype(auto) left( derestrict( *this ) );
3357 
3358  if( rhs.canAlias( &vector_ ) ) {
3359  const ResultType tmp( ~rhs );
3360  smpAssign( left, tmp );
3361  }
3362  else {
3363  smpAssign( left, rhs );
3364  }
3365 
3366  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3367 
3368  return *this;
3369 }
3371 //*************************************************************************************************
3372 
3373 
3374 //*************************************************************************************************
3386 template< typename VT // Type of the dense vector
3387  , bool TF // Transpose flag
3388  , size_t... CSAs > // Compile time subvector arguments
3389 template< typename VT2 > // Type of the right-hand side vector
3390 inline Subvector<VT,aligned,TF,true,CSAs...>&
3391  Subvector<VT,aligned,TF,true,CSAs...>::operator=( const Vector<VT2,TF>& rhs )
3392 {
3393  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3394  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3395 
3396  if( size() != (~rhs).size() ) {
3397  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3398  }
3399 
3400  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3401  Right right( ~rhs );
3402 
3403  if( !tryAssign( vector_, right, offset() ) ) {
3404  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3405  }
3406 
3407  decltype(auto) left( derestrict( *this ) );
3408 
3409  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3410  const ResultType_t<VT2> tmp( right );
3411  smpAssign( left, tmp );
3412  }
3413  else {
3414  if( IsSparseVector_v<VT2> )
3415  reset();
3416  smpAssign( left, right );
3417  }
3418 
3419  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3420 
3421  return *this;
3422 }
3424 //*************************************************************************************************
3425 
3426 
3427 //*************************************************************************************************
3439 template< typename VT // Type of the dense vector
3440  , bool TF // Transpose flag
3441  , size_t... CSAs > // Compile time subvector arguments
3442 template< typename VT2 > // Type of the right-hand side vector
3443 inline Subvector<VT,aligned,TF,true,CSAs...>&
3444  Subvector<VT,aligned,TF,true,CSAs...>::operator+=( const Vector<VT2,TF>& rhs )
3445 {
3446  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3447  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3448 
3449  if( size() != (~rhs).size() ) {
3450  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3451  }
3452 
3453  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3454  Right right( ~rhs );
3455 
3456  if( !tryAddAssign( vector_, right, offset() ) ) {
3457  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3458  }
3459 
3460  decltype(auto) left( derestrict( *this ) );
3461 
3462  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3463  const ResultType_t<VT2> tmp( right );
3464  smpAddAssign( left, tmp );
3465  }
3466  else {
3467  smpAddAssign( left, right );
3468  }
3469 
3470  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3471 
3472  return *this;
3473 }
3475 //*************************************************************************************************
3476 
3477 
3478 //*************************************************************************************************
3490 template< typename VT // Type of the dense vector
3491  , bool TF // Transpose flag
3492  , size_t... CSAs > // Compile time subvector arguments
3493 template< typename VT2 > // Type of the right-hand side vector
3494 inline Subvector<VT,aligned,TF,true,CSAs...>&
3495  Subvector<VT,aligned,TF,true,CSAs...>::operator-=( const Vector<VT2,TF>& rhs )
3496 {
3497  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3498  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3499 
3500  if( size() != (~rhs).size() ) {
3501  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3502  }
3503 
3504  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3505  Right right( ~rhs );
3506 
3507  if( !trySubAssign( vector_, right, offset() ) ) {
3508  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3509  }
3510 
3511  decltype(auto) left( derestrict( *this ) );
3512 
3513  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3514  const ResultType_t<VT2> tmp( right );
3515  smpSubAssign( left, tmp );
3516  }
3517  else {
3518  smpSubAssign( left, right );
3519  }
3520 
3521  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3522 
3523  return *this;
3524 }
3526 //*************************************************************************************************
3527 
3528 
3529 //*************************************************************************************************
3542 template< typename VT // Type of the dense vector
3543  , bool TF // Transpose flag
3544  , size_t... CSAs > // Compile time subvector arguments
3545 template< typename VT2 > // Type of the right-hand side vector
3546 inline Subvector<VT,aligned,TF,true,CSAs...>&
3547  Subvector<VT,aligned,TF,true,CSAs...>::operator*=( const Vector<VT2,TF>& rhs )
3548 {
3549  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3550  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3551 
3552  if( size() != (~rhs).size() ) {
3553  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3554  }
3555 
3556  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3557  Right right( ~rhs );
3558 
3559  if( !tryMultAssign( vector_, right, offset() ) ) {
3560  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3561  }
3562 
3563  decltype(auto) left( derestrict( *this ) );
3564 
3565  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3566  const ResultType_t<VT2> tmp( right );
3567  smpMultAssign( left, tmp );
3568  }
3569  else {
3570  smpMultAssign( left, right );
3571  }
3572 
3573  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3574 
3575  return *this;
3576 }
3578 //*************************************************************************************************
3579 
3580 
3581 //*************************************************************************************************
3593 template< typename VT // Type of the dense vector
3594  , bool TF // Transpose flag
3595  , size_t... CSAs > // Compile time subvector arguments
3596 template< typename VT2 > // Type of the right-hand side dense vector
3597 inline Subvector<VT,aligned,TF,true,CSAs...>&
3598  Subvector<VT,aligned,TF,true,CSAs...>::operator/=( const DenseVector<VT2,TF>& rhs )
3599 {
3600  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3601  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3602 
3603  if( size() != (~rhs).size() ) {
3604  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3605  }
3606 
3607  using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3608  Right right( ~rhs );
3609 
3610  if( !tryDivAssign( vector_, right, offset() ) ) {
3611  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3612  }
3613 
3614  decltype(auto) left( derestrict( *this ) );
3615 
3616  if( IsReference_v<Right> && right.canAlias( &vector_ ) ) {
3617  const ResultType_t<VT2> tmp( right );
3618  smpDivAssign( left, tmp );
3619  }
3620  else {
3621  smpDivAssign( left, right );
3622  }
3623 
3624  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3625 
3626  return *this;
3627 }
3629 //*************************************************************************************************
3630 
3631 
3632 //*************************************************************************************************
3645 template< typename VT // Type of the dense vector
3646  , bool TF // Transpose flag
3647  , size_t... CSAs > // Compile time subvector arguments
3648 template< typename VT2 > // Type of the right-hand side vector
3649 inline Subvector<VT,aligned,TF,true,CSAs...>&
3650  Subvector<VT,aligned,TF,true,CSAs...>::operator%=( const Vector<VT2,TF>& rhs )
3651 {
3652  using blaze::assign;
3653 
3654  BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( ResultType_t<VT2>, TF );
3655  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<VT2> );
3656 
3657  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT2> >;
3658 
3662 
3663  if( size() != 3UL || (~rhs).size() != 3UL ) {
3664  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3665  }
3666 
3667  const CrossType tmp( *this % (~rhs) );
3668 
3669  if( !tryAssign( vector_, tmp, offset() ) ) {
3670  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3671  }
3672 
3673  decltype(auto) left( derestrict( *this ) );
3674 
3675  assign( left, tmp );
3676 
3677  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3678 
3679  return *this;
3680 }
3682 //*************************************************************************************************
3683 
3684 
3685 
3686 
3687 //=================================================================================================
3688 //
3689 // UTILITY FUNCTIONS
3690 //
3691 //=================================================================================================
3692 
3693 //*************************************************************************************************
3699 template< typename VT // Type of the dense vector
3700  , bool TF // Transpose flag
3701  , size_t... CSAs > // Compile time subvector arguments
3702 inline VT& Subvector<VT,aligned,TF,true,CSAs...>::operand() noexcept
3703 {
3704  return vector_;
3705 }
3707 //*************************************************************************************************
3708 
3709 
3710 //*************************************************************************************************
3716 template< typename VT // Type of the dense vector
3717  , bool TF // Transpose flag
3718  , size_t... CSAs > // Compile time subvector arguments
3719 inline const VT& Subvector<VT,aligned,TF,true,CSAs...>::operand() const noexcept
3720 {
3721  return vector_;
3722 }
3724 //*************************************************************************************************
3725 
3726 
3727 //*************************************************************************************************
3736 template< typename VT // Type of the dense vector
3737  , bool TF // Transpose flag
3738  , size_t... CSAs > // Compile time subvector arguments
3739 inline size_t Subvector<VT,aligned,TF,true,CSAs...>::spacing() const noexcept
3740 {
3741  return vector_.spacing() - offset();
3742 }
3744 //*************************************************************************************************
3745 
3746 
3747 //*************************************************************************************************
3753 template< typename VT // Type of the dense vector
3754  , bool TF // Transpose flag
3755  , size_t... CSAs > // Compile time subvector arguments
3756 inline size_t Subvector<VT,aligned,TF,true,CSAs...>::capacity() const noexcept
3757 {
3758  return vector_.capacity() - offset();
3759 }
3761 //*************************************************************************************************
3762 
3763 
3764 //*************************************************************************************************
3773 template< typename VT // Type of the dense vector
3774  , bool TF // Transpose flag
3775  , size_t... CSAs > // Compile time subvector arguments
3777 {
3778  size_t nonzeros( 0 );
3779 
3780  const size_t iend( offset() + size() );
3781  for( size_t i=offset(); i<iend; ++i ) {
3782  if( !isDefault( vector_[i] ) )
3783  ++nonzeros;
3784  }
3785 
3786  return nonzeros;
3787 }
3789 //*************************************************************************************************
3790 
3791 
3792 //*************************************************************************************************
3798 template< typename VT // Type of the dense vector
3799  , bool TF // Transpose flag
3800  , size_t... CSAs > // Compile time subvector arguments
3802 {
3803  using blaze::clear;
3804 
3805  const size_t iend( offset() + size() );
3806  for( size_t i=offset(); i<iend; ++i )
3807  clear( vector_[i] );
3808 }
3810 //*************************************************************************************************
3811 
3812 
3813 
3814 
3815 //=================================================================================================
3816 //
3817 // NUMERIC FUNCTIONS
3818 //
3819 //=================================================================================================
3820 
3821 //*************************************************************************************************
3832 template< typename VT // Type of the dense vector
3833  , bool TF // Transpose flag
3834  , size_t... CSAs > // Compile time subvector arguments
3835 template< typename Other > // Data type of the scalar value
3836 inline Subvector<VT,aligned,TF,true,CSAs...>&
3837  Subvector<VT,aligned,TF,true,CSAs...>::scale( const Other& scalar )
3838 {
3839  const size_t iend( offset() + size() );
3840  for( size_t i=offset(); i<iend; ++i )
3841  vector_[i] *= scalar;
3842  return *this;
3843 }
3845 //*************************************************************************************************
3846 
3847 
3848 
3849 
3850 //=================================================================================================
3851 //
3852 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3853 //
3854 //=================================================================================================
3855 
3856 //*************************************************************************************************
3867 template< typename VT // Type of the dense vector
3868  , bool TF // Transpose flag
3869  , size_t... CSAs > // Compile time subvector arguments
3870 template< typename Other > // Data type of the foreign expression
3871 inline bool Subvector<VT,aligned,TF,true,CSAs...>::canAlias( const Other* alias ) const noexcept
3872 {
3873  return vector_.isAliased( alias );
3874 }
3876 //*************************************************************************************************
3877 
3878 
3879 //*************************************************************************************************
3890 template< typename VT // Type of the dense vector
3891  , bool TF // Transpose flag
3892  , size_t... CSAs > // Compile time subvector arguments
3893 template< typename VT2 // Data type of the foreign dense subvector
3894  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
3895  , bool TF2 // Transpose flag of the foreign dense subvector
3896  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
3897 inline bool
3898  Subvector<VT,aligned,TF,true,CSAs...>::canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
3899 {
3900  return ( vector_.isAliased( &alias->vector_ ) &&
3901  ( offset() + size() > alias->offset() ) &&
3902  ( offset() < alias->offset() + alias->size() ) );
3903 }
3905 //*************************************************************************************************
3906 
3907 
3908 //*************************************************************************************************
3919 template< typename VT // Type of the dense vector
3920  , bool TF // Transpose flag
3921  , size_t... CSAs > // Compile time subvector arguments
3922 template< typename Other > // Data type of the foreign expression
3923 inline bool Subvector<VT,aligned,TF,true,CSAs...>::isAliased( const Other* alias ) const noexcept
3924 {
3925  return vector_.isAliased( alias );
3926 }
3928 //*************************************************************************************************
3929 
3930 
3931 //*************************************************************************************************
3942 template< typename VT // Type of the dense vector
3943  , bool TF // Transpose flag
3944  , size_t... CSAs > // Compile time subvector arguments
3945 template< typename VT2 // Data type of the foreign dense subvector
3946  , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
3947  , bool TF2 // Transpose flag of the foreign dense subvector
3948  , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
3949 inline bool
3950  Subvector<VT,aligned,TF,true,CSAs...>::isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
3951 {
3952  return ( vector_.isAliased( &alias->vector_ ) &&
3953  ( offset() + size() > alias->offset() ) &&
3954  ( offset() < alias->offset() + alias->size() ) );
3955 }
3957 //*************************************************************************************************
3958 
3959 
3960 //*************************************************************************************************
3970 template< typename VT // Type of the dense vector
3971  , bool TF // Transpose flag
3972  , size_t... CSAs > // Compile time subvector arguments
3973 inline bool Subvector<VT,aligned,TF,true,CSAs...>::isAligned() const noexcept
3974 {
3975  return true;
3976 }
3978 //*************************************************************************************************
3979 
3980 
3981 //*************************************************************************************************
3992 template< typename VT // Type of the dense vector
3993  , bool TF // Transpose flag
3994  , size_t... CSAs > // Compile time subvector arguments
3995 inline bool Subvector<VT,aligned,TF,true,CSAs...>::canSMPAssign() const noexcept
3996 {
3997  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3998 }
4000 //*************************************************************************************************
4001 
4002 
4003 //*************************************************************************************************
4017 template< typename VT // Type of the dense vector
4018  , bool TF // Transpose flag
4019  , size_t... CSAs > // Compile time subvector arguments
4020 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4021  Subvector<VT,aligned,TF,true,CSAs...>::load( size_t index ) const noexcept
4022 {
4023  return loada( index );
4024 }
4026 //*************************************************************************************************
4027 
4028 
4029 //*************************************************************************************************
4043 template< typename VT // Type of the dense vector
4044  , bool TF // Transpose flag
4045  , size_t... CSAs > // Compile time subvector arguments
4046 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4047  Subvector<VT,aligned,TF,true,CSAs...>::loada( size_t index ) const noexcept
4048 {
4050 
4051  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4052  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4053  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4054 
4055  return vector_.loada( offset()+index );
4056 }
4058 //*************************************************************************************************
4059 
4060 
4061 //*************************************************************************************************
4075 template< typename VT // Type of the dense vector
4076  , bool TF // Transpose flag
4077  , size_t... CSAs > // Compile time subvector arguments
4078 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4079  Subvector<VT,aligned,TF,true,CSAs...>::loadu( size_t index ) const noexcept
4080 {
4082 
4083  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4084  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4085 
4086  return vector_.loadu( offset()+index );
4087 }
4089 //*************************************************************************************************
4090 
4091 
4092 //*************************************************************************************************
4107 template< typename VT // Type of the dense vector
4108  , bool TF // Transpose flag
4109  , size_t... CSAs > // Compile time subvector arguments
4111  Subvector<VT,aligned,TF,true,CSAs...>::store( size_t index, const SIMDType& value ) noexcept
4112 {
4113  storea( index, value );
4114 }
4116 //*************************************************************************************************
4117 
4118 
4119 //*************************************************************************************************
4134 template< typename VT // Type of the dense vector
4135  , bool TF // Transpose flag
4136  , size_t... CSAs > // Compile time subvector arguments
4138  Subvector<VT,aligned,TF,true,CSAs...>::storea( size_t index, const SIMDType& value ) noexcept
4139 {
4141 
4142  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4143  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4144  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4145 
4146  vector_.storea( offset()+index, value );
4147 }
4149 //*************************************************************************************************
4150 
4151 
4152 //*************************************************************************************************
4167 template< typename VT // Type of the dense vector
4168  , bool TF // Transpose flag
4169  , size_t... CSAs > // Compile time subvector arguments
4171  Subvector<VT,aligned,TF,true,CSAs...>::storeu( size_t index, const SIMDType& value ) noexcept
4172 {
4174 
4175  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4176  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4177 
4178  vector_.storeu( offset()+index, value );
4179 }
4181 //*************************************************************************************************
4182 
4183 
4184 //*************************************************************************************************
4199 template< typename VT // Type of the dense vector
4200  , bool TF // Transpose flag
4201  , size_t... CSAs > // Compile time subvector arguments
4203  Subvector<VT,aligned,TF,true,CSAs...>::stream( size_t index, const SIMDType& value ) noexcept
4204 {
4206 
4207  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4208  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4209  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4210 
4211  vector_.stream( offset()+index, value );
4212 }
4214 //*************************************************************************************************
4215 
4216 
4217 //*************************************************************************************************
4229 template< typename VT // Type of the dense vector
4230  , bool TF // Transpose flag
4231  , size_t... CSAs > // Compile time subvector arguments
4232 template< typename VT2 > // Type of the right-hand side dense vector
4233 inline auto Subvector<VT,aligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
4234  -> DisableIf_t< VectorizedAssign_v<VT2> >
4235 {
4236  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4237 
4238  const size_t ipos( size() & size_t(-2) );
4239  for( size_t i=0UL; i<ipos; i+=2UL ) {
4240  vector_[offset()+i ] = (~rhs)[i ];
4241  vector_[offset()+i+1UL] = (~rhs)[i+1UL];
4242  }
4243  if( ipos < size() ) {
4244  vector_[offset()+ipos] = (~rhs)[ipos];
4245  }
4246 }
4248 //*************************************************************************************************
4249 
4250 
4251 //*************************************************************************************************
4263 template< typename VT // Type of the dense vector
4264  , bool TF // Transpose flag
4265  , size_t... CSAs > // Compile time subvector arguments
4266 template< typename VT2 > // Type of the right-hand side dense vector
4267 inline auto Subvector<VT,aligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
4268  -> EnableIf_t< VectorizedAssign_v<VT2> >
4269 {
4271 
4272  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4273 
4274  const size_t ipos( size() & size_t(-SIMDSIZE) );
4275  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4276 
4277  size_t i( 0UL );
4278  Iterator left( begin() );
4279  ConstIterator_t<VT2> right( (~rhs).begin() );
4280 
4281  if( useStreaming && size() > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
4282  {
4283  for( ; i<ipos; i+=SIMDSIZE ) {
4284  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4285  }
4286  for( ; i<size(); ++i ) {
4287  *left = *right; ++left; ++right;
4288  }
4289  }
4290  else
4291  {
4292  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4293  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4294  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4295  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4296  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4297  }
4298  for( ; i<ipos; i+=SIMDSIZE ) {
4299  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4300  }
4301  for( ; i<size(); ++i ) {
4302  *left = *right; ++left; ++right;
4303  }
4304  }
4305 }
4307 //*************************************************************************************************
4308 
4309 
4310 //*************************************************************************************************
4322 template< typename VT // Type of the dense vector
4323  , bool TF // Transpose flag
4324  , size_t... CSAs > // Compile time subvector arguments
4325 template< typename VT2 > // Type of the right-hand side sparse vector
4326 inline void Subvector<VT,aligned,TF,true,CSAs...>::assign( const SparseVector<VT2,TF>& rhs )
4327 {
4328  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4329 
4330  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4331  vector_[offset()+element->index()] = element->value();
4332 }
4334 //*************************************************************************************************
4335 
4336 
4337 //*************************************************************************************************
4349 template< typename VT // Type of the dense vector
4350  , bool TF // Transpose flag
4351  , size_t... CSAs > // Compile time subvector arguments
4352 template< typename VT2 > // Type of the right-hand side dense vector
4353 inline auto Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
4354  -> DisableIf_t< VectorizedAddAssign_v<VT2> >
4355 {
4356  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4357 
4358  const size_t ipos( size() & size_t(-2) );
4359  for( size_t i=0UL; i<ipos; i+=2UL ) {
4360  vector_[offset()+i ] += (~rhs)[i ];
4361  vector_[offset()+i+1UL] += (~rhs)[i+1UL];
4362  }
4363  if( ipos < size() ) {
4364  vector_[offset()+ipos] += (~rhs)[ipos];
4365  }
4366 }
4368 //*************************************************************************************************
4369 
4370 
4371 //*************************************************************************************************
4383 template< typename VT // Type of the dense vector
4384  , bool TF // Transpose flag
4385  , size_t... CSAs > // Compile time subvector arguments
4386 template< typename VT2 > // Type of the right-hand side dense vector
4387 inline auto Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
4388  -> EnableIf_t< VectorizedAddAssign_v<VT2> >
4389 {
4391 
4392  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4393 
4394  const size_t ipos( size() & size_t(-SIMDSIZE) );
4395  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4396 
4397  size_t i( 0UL );
4398  Iterator left( begin() );
4399  ConstIterator_t<VT2> right( (~rhs).begin() );
4400 
4401  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4402  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4403  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4404  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4405  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4406  }
4407  for( ; i<ipos; i+=SIMDSIZE ) {
4408  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4409  }
4410  for( ; i<size(); ++i ) {
4411  *left += *right; ++left; ++right;
4412  }
4413 }
4415 //*************************************************************************************************
4416 
4417 
4418 //*************************************************************************************************
4430 template< typename VT // Type of the dense vector
4431  , bool TF // Transpose flag
4432  , size_t... CSAs > // Compile time subvector arguments
4433 template< typename VT2 > // Type of the right-hand side sparse vector
4434 inline void Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const SparseVector<VT2,TF>& rhs )
4435 {
4436  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4437 
4438  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4439  vector_[offset()+element->index()] += element->value();
4440 }
4442 //*************************************************************************************************
4443 
4444 
4445 //*************************************************************************************************
4457 template< typename VT // Type of the dense vector
4458  , bool TF // Transpose flag
4459  , size_t... CSAs > // Compile time subvector arguments
4460 template< typename VT2 > // Type of the right-hand side dense vector
4461 inline auto Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
4462  -> DisableIf_t< VectorizedSubAssign_v<VT2> >
4463 {
4464  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4465 
4466  const size_t ipos( size() & size_t(-2) );
4467  for( size_t i=0UL; i<ipos; i+=2UL ) {
4468  vector_[offset()+i ] -= (~rhs)[i ];
4469  vector_[offset()+i+1UL] -= (~rhs)[i+1UL];
4470  }
4471  if( ipos < size() ) {
4472  vector_[offset()+ipos] -= (~rhs)[ipos];
4473  }
4474 }
4476 //*************************************************************************************************
4477 
4478 
4479 //*************************************************************************************************
4491 template< typename VT // Type of the dense vector
4492  , bool TF // Transpose flag
4493  , size_t... CSAs > // Compile time subvector arguments
4494 template< typename VT2 > // Type of the right-hand side dense vector
4495 inline auto Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
4496  -> EnableIf_t< VectorizedSubAssign_v<VT2> >
4497 {
4499 
4500  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4501 
4502  const size_t ipos( size() & size_t(-SIMDSIZE) );
4503  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4504 
4505  size_t i( 0UL );
4506  Iterator left( begin() );
4507  ConstIterator_t<VT2> right( (~rhs).begin() );
4508 
4509  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4510  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4511  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4512  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4513  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4514  }
4515  for( ; i<ipos; i+=SIMDSIZE ) {
4516  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4517  }
4518  for( ; i<size(); ++i ) {
4519  *left -= *right; ++left; ++right;
4520  }
4521 }
4523 //*************************************************************************************************
4524 
4525 
4526 //*************************************************************************************************
4538 template< typename VT // Type of the dense vector
4539  , bool TF // Transpose flag
4540  , size_t... CSAs > // Compile time subvector arguments
4541 template< typename VT2 > // Type of the right-hand side sparse vector
4542 inline void Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const SparseVector<VT2,TF>& rhs )
4543 {
4544  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4545 
4546  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4547  vector_[offset()+element->index()] -= element->value();
4548 }
4550 //*************************************************************************************************
4551 
4552 
4553 //*************************************************************************************************
4565 template< typename VT // Type of the dense vector
4566  , bool TF // Transpose flag
4567  , size_t... CSAs > // Compile time subvector arguments
4568 template< typename VT2 > // Type of the right-hand side dense vector
4569 inline auto Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
4570  -> DisableIf_t< VectorizedMultAssign_v<VT2> >
4571 {
4572  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4573 
4574  const size_t ipos( size() & size_t(-2) );
4575  for( size_t i=0UL; i<ipos; i+=2UL ) {
4576  vector_[offset()+i ] *= (~rhs)[i ];
4577  vector_[offset()+i+1UL] *= (~rhs)[i+1UL];
4578  }
4579  if( ipos < size() ) {
4580  vector_[offset()+ipos] *= (~rhs)[ipos];
4581  }
4582 }
4584 //*************************************************************************************************
4585 
4586 
4587 //*************************************************************************************************
4599 template< typename VT // Type of the dense vector
4600  , bool TF // Transpose flag
4601  , size_t... CSAs > // Compile time subvector arguments
4602 template< typename VT2 > // Type of the right-hand side dense vector
4603 inline auto Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
4604  -> EnableIf_t< VectorizedMultAssign_v<VT2> >
4605 {
4607 
4608  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4609 
4610  const size_t ipos( size() & size_t(-SIMDSIZE) );
4611  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4612 
4613  size_t i( 0UL );
4614  Iterator left( begin() );
4615  ConstIterator_t<VT2> right( (~rhs).begin() );
4616 
4617  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4618  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4619  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4620  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4621  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4622  }
4623  for( ; i<ipos; i+=SIMDSIZE ) {
4624  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4625  }
4626  for( ; i<size(); ++i ) {
4627  *left *= *right; ++left; ++right;
4628  }
4629 }
4631 //*************************************************************************************************
4632 
4633 
4634 //*************************************************************************************************
4646 template< typename VT // Type of the dense vector
4647  , bool TF // Transpose flag
4648  , size_t... CSAs > // Compile time subvector arguments
4649 template< typename VT2 > // Type of the right-hand side sparse vector
4650 inline void Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const SparseVector<VT2,TF>& rhs )
4651 {
4652  using blaze::reset;
4653 
4654  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4655 
4656  size_t i( 0UL );
4657 
4658  for( ConstIterator_t<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
4659  const size_t index( element->index() );
4660  for( ; i<index; ++i )
4661  reset( vector_[offset()+i] );
4662  vector_[offset()+i] *= element->value();
4663  ++i;
4664  }
4665 
4666  for( ; i<size(); ++i ) {
4667  reset( vector_[offset()+i] );
4668  }
4669 }
4671 //*************************************************************************************************
4672 
4673 
4674 //*************************************************************************************************
4686 template< typename VT // Type of the dense vector
4687  , bool TF // Transpose flag
4688  , size_t... CSAs > // Compile time subvector arguments
4689 template< typename VT2 > // Type of the right-hand side dense vector
4690 inline auto Subvector<VT,aligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
4691  -> DisableIf_t< VectorizedDivAssign_v<VT2> >
4692 {
4693  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4694 
4695  const size_t ipos( size() & size_t(-2) );
4696  for( size_t i=0UL; i<ipos; i+=2UL ) {
4697  vector_[offset()+i ] /= (~rhs)[i ];
4698  vector_[offset()+i+1UL] /= (~rhs)[i+1UL];
4699  }
4700  if( ipos < size() ) {
4701  vector_[offset()+ipos] /= (~rhs)[ipos];
4702  }
4703 }
4705 //*************************************************************************************************
4706 
4707 
4708 //*************************************************************************************************
4720 template< typename VT // Type of the dense vector
4721  , bool TF // Transpose flag
4722  , size_t... CSAs > // Compile time subvector arguments
4723 template< typename VT2 > // Type of the right-hand side dense vector
4724 inline auto Subvector<VT,aligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
4725  -> EnableIf_t< VectorizedDivAssign_v<VT2> >
4726 {
4728 
4729  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4730 
4731  const size_t ipos( size() & size_t(-SIMDSIZE) );
4732  BLAZE_INTERNAL_ASSERT( ( size() - ( size() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4733 
4734  size_t i( 0UL );
4735  Iterator left( begin() );
4736  ConstIterator_t<VT2> right( (~rhs).begin() );
4737 
4738  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4739  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4740  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4741  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4742  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4743  }
4744  for( ; i<ipos; i+=SIMDSIZE ) {
4745  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4746  }
4747  for( ; i<size(); ++i ) {
4748  *left /= *right; ++left; ++right;
4749  }
4750 }
4752 //*************************************************************************************************
4753 
4754 
4755 
4756 
4757 
4758 
4759 
4760 
4761 //=================================================================================================
4762 //
4763 // CLASS TEMPLATE SPECIALIZATION FOR DVECDVECCROSSEXPR
4764 //
4765 //=================================================================================================
4766 
4767 //*************************************************************************************************
4775 template< typename VT1 // Type of the left-hand side dense vector
4776  , typename VT2 // Type of the right-hand side dense vector
4777  , bool TF // Transpose flag
4778  , size_t... CSAs > // Compile time subvector arguments
4779 class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
4780  : public View< DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
4781  , private SubvectorData<CSAs...>
4782 {
4783  private:
4784  //**Type definitions****************************************************************************
4785  using CPE = DVecDVecCrossExpr<VT1,VT2,TF>;
4786  using RT = ResultType_t<CPE>;
4787  using DataType = SubvectorData<CSAs...>;
4788  //**********************************************************************************************
4789 
4790  public:
4791  //**Type definitions****************************************************************************
4793  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
4794 
4795  using BaseType = DenseVector<This,TF>;
4796  using ViewedType = CPE;
4797  using ResultType = SubvectorTrait_t<RT,CSAs...>;
4798  using TransposeType = TransposeType_t<ResultType>;
4799  using ElementType = ElementType_t<CPE>;
4800  using ReturnType = ReturnType_t<CPE>;
4801  using CompositeType = const ResultType;
4802  //**********************************************************************************************
4803 
4804  //**Compilation flags***************************************************************************
4806  static constexpr bool simdEnabled = false;
4807 
4809  static constexpr bool smpAssignable = false;
4810 
4812  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4813  //**********************************************************************************************
4814 
4815  //**Constructor*********************************************************************************
4822  template< typename... RSAs > // Optional subvector arguments
4823  explicit inline Subvector( const CPE& vector, RSAs... args )
4824  : DataType( args... ) // Base class initialization
4825  , vector_ ( vector ) // The dense vector/dense vector cross product expression
4826  {
4827  if( Contains_v< TypeList<RSAs...>, Unchecked > ) {
4828  if( offset() + size() > vector.size() ) {
4829  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
4830  }
4831  }
4832  else {
4833  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
4834  }
4835  }
4836  //**********************************************************************************************
4837 
4838  //**Subscript operator**************************************************************************
4844  inline ReturnType operator[]( size_t index ) const {
4845  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4846  return vector_[offset()+index];
4847  }
4848  //**********************************************************************************************
4849 
4850  //**At function*********************************************************************************
4857  inline ReturnType at( size_t index ) const {
4858  if( index >= size() ) {
4859  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
4860  }
4861  return (*this)[index];
4862  }
4863  //**********************************************************************************************
4864 
4865  //**********************************************************************************************
4866  using DataType::offset;
4867  using DataType::size;
4868  //**********************************************************************************************
4869 
4870  //**Operand access******************************************************************************
4875  inline CPE operand() const noexcept {
4876  return vector_;
4877  }
4878  //**********************************************************************************************
4879 
4880  //**********************************************************************************************
4886  template< typename T >
4887  inline bool canAlias( const T* alias ) const noexcept {
4888  return vector_.canAlias( alias );
4889  }
4890  //**********************************************************************************************
4891 
4892  //**********************************************************************************************
4898  template< typename T >
4899  inline bool isAliased( const T* alias ) const noexcept {
4900  return vector_.isAliased( alias );
4901  }
4902  //**********************************************************************************************
4903 
4904  private:
4905  //**Member variables****************************************************************************
4906  CPE vector_;
4907  //**********************************************************************************************
4908 };
4910 //*************************************************************************************************
4911 
4912 
4913 
4914 
4915 
4916 
4917 
4918 
4919 //=================================================================================================
4920 //
4921 // CLASS TEMPLATE SPECIALIZATION FOR DVECSVECCROSSEXPR
4922 //
4923 //=================================================================================================
4924 
4925 //*************************************************************************************************
4933 template< typename VT1 // Type of the left-hand side dense vector
4934  , typename VT2 // Type of the right-hand side sparse vector
4935  , bool TF // Transpose flag
4936  , size_t... CSAs > // Compile time subvector arguments
4937 class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
4938  : public View< DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
4939  , private SubvectorData<CSAs...>
4940 {
4941  private:
4942  //**Type definitions****************************************************************************
4943  using CPE = DVecSVecCrossExpr<VT1,VT2,TF>;
4944  using RT = ResultType_t<CPE>;
4945  using DataType = SubvectorData<CSAs...>;
4946  //**********************************************************************************************
4947 
4948  public:
4949  //**Type definitions****************************************************************************
4951  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
4952 
4953  using BaseType = DenseVector<This,TF>;
4954  using ViewedType = CPE;
4955  using ResultType = SubvectorTrait_t<RT,CSAs...>;
4956  using TransposeType = TransposeType_t<ResultType>;
4957  using ElementType = ElementType_t<CPE>;
4958  using ReturnType = ReturnType_t<CPE>;
4959  using CompositeType = const ResultType;
4960  //**********************************************************************************************
4961 
4962  //**Compilation flags***************************************************************************
4964  static constexpr bool simdEnabled = false;
4965 
4967  static constexpr bool smpAssignable = false;
4968 
4970  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4971  //**********************************************************************************************
4972 
4973  //**Constructor*********************************************************************************
4980  template< typename... RSAs > // Optional subvector arguments
4981  explicit inline Subvector( const CPE& vector, RSAs... args )
4982  : DataType( args... ) // Base class initialization
4983  , vector_ ( vector ) // The dense vector/sparse vector cross product expression
4984  {
4985  if( Contains_v< TypeList<RSAs...>, Unchecked > ) {
4986  if( offset() + size() > vector.size() ) {
4987  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
4988  }
4989  }
4990  else {
4991  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
4992  }
4993  }
4994  //**********************************************************************************************
4995 
4996  //**Subscript operator**************************************************************************
5002  inline ReturnType operator[]( size_t index ) const {
5003  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5004  return vector_[offset()+index];
5005  }
5006  //**********************************************************************************************
5007 
5008  //**At function*********************************************************************************
5015  inline ReturnType at( size_t index ) const {
5016  if( index >= size() ) {
5017  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5018  }
5019  return (*this)[index];
5020  }
5021  //**********************************************************************************************
5022 
5023  //**********************************************************************************************
5024  using DataType::offset;
5025  using DataType::size;
5026  //**********************************************************************************************
5027 
5028  //**Operand access******************************************************************************
5033  inline CPE operand() const noexcept {
5034  return vector_;
5035  }
5036  //**********************************************************************************************
5037 
5038  //**********************************************************************************************
5044  template< typename T >
5045  inline bool canAlias( const T* alias ) const noexcept {
5046  return vector_.canAlias( alias );
5047  }
5048  //**********************************************************************************************
5049 
5050  //**********************************************************************************************
5056  template< typename T >
5057  inline bool isAliased( const T* alias ) const noexcept {
5058  return vector_.isAliased( alias );
5059  }
5060  //**********************************************************************************************
5061 
5062  private:
5063  //**Member variables****************************************************************************
5064  CPE vector_;
5065  //**********************************************************************************************
5066 };
5068 //*************************************************************************************************
5069 
5070 
5071 
5072 
5073 
5074 
5075 
5076 
5077 //=================================================================================================
5078 //
5079 // CLASS TEMPLATE SPECIALIZATION FOR SVECDVECCROSSEXPR
5080 //
5081 //=================================================================================================
5082 
5083 //*************************************************************************************************
5091 template< typename VT1 // Type of the left-hand side sparse vector
5092  , typename VT2 // Type of the right-hand side dense vector
5093  , bool TF // Transpose flag
5094  , size_t... CSAs > // Compile time subvector arguments
5095 class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
5096  : public View< DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
5097  , private SubvectorData<CSAs...>
5098 {
5099  private:
5100  //**Type definitions****************************************************************************
5101  using CPE = SVecDVecCrossExpr<VT1,VT2,TF>;
5102  using RT = ResultType_t<CPE>;
5103  using DataType = SubvectorData<CSAs...>;
5104  //**********************************************************************************************
5105 
5106  public:
5107  //**Type definitions****************************************************************************
5109  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
5110 
5111  using BaseType = DenseVector<This,TF>;
5112  using ViewedType = CPE;
5113  using ResultType = SubvectorTrait_t<RT,CSAs...>;
5114  using TransposeType = TransposeType_t<ResultType>;
5115  using ElementType = ElementType_t<CPE>;
5116  using ReturnType = ReturnType_t<CPE>;
5117  using CompositeType = const ResultType;
5118  //**********************************************************************************************
5119 
5120  //**Compilation flags***************************************************************************
5122  static constexpr bool simdEnabled = false;
5123 
5125  static constexpr bool smpAssignable = false;
5126 
5128  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
5129  //**********************************************************************************************
5130 
5131  //**Constructor*********************************************************************************
5138  template< typename... RSAs > // Optional subvector arguments
5139  explicit inline Subvector( const CPE& vector, RSAs... args )
5140  : DataType( args... ) // Base class initialization
5141  , vector_ ( vector ) // The sparse vector/dense vector cross product expression
5142  {
5143  if( Contains_v< TypeList<RSAs...>, Unchecked > ) {
5144  if( offset() + size() > vector.size() ) {
5145  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
5146  }
5147  }
5148  else {
5149  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
5150  }
5151  }
5152  //**********************************************************************************************
5153 
5154  //**Subscript operator**************************************************************************
5160  inline ReturnType operator[]( size_t index ) const {
5161  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5162  return vector_[offset()+index];
5163  }
5164  //**********************************************************************************************
5165 
5166  //**At function*********************************************************************************
5173  inline ReturnType at( size_t index ) const {
5174  if( index >= size() ) {
5175  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5176  }
5177  return (*this)[index];
5178  }
5179  //**********************************************************************************************
5180 
5181  //**********************************************************************************************
5182  using DataType::offset;
5183  using DataType::size;
5184  //**********************************************************************************************
5185 
5186  //**Operand access******************************************************************************
5191  inline CPE operand() const noexcept {
5192  return vector_;
5193  }
5194  //**********************************************************************************************
5195 
5196  //**********************************************************************************************
5202  template< typename T >
5203  inline bool canAlias( const T* alias ) const noexcept {
5204  return vector_.canAlias( alias );
5205  }
5206  //**********************************************************************************************
5207 
5208  //**********************************************************************************************
5214  template< typename T >
5215  inline bool isAliased( const T* alias ) const noexcept {
5216  return vector_.isAliased( alias );
5217  }
5218  //**********************************************************************************************
5219 
5220  private:
5221  //**Member variables****************************************************************************
5222  CPE vector_;
5223  //**********************************************************************************************
5224 };
5226 //*************************************************************************************************
5227 
5228 
5229 
5230 
5231 
5232 
5233 
5234 
5235 //=================================================================================================
5236 //
5237 // CLASS TEMPLATE SPECIALIZATION FOR SVECSVECCROSSEXPR
5238 //
5239 //=================================================================================================
5240 
5241 //*************************************************************************************************
5249 template< typename VT1 // Type of the left-hand side sparse vector
5250  , typename VT2 // Type of the right-hand side sparse vector
5251  , bool TF // Transpose flag
5252  , size_t... CSAs > // Compile time subvector arguments
5253 class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
5254  : public View< DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
5255  , private SubvectorData<CSAs...>
5256 {
5257  private:
5258  //**Type definitions****************************************************************************
5259  using CPE = SVecSVecCrossExpr<VT1,VT2,TF>;
5260  using RT = ResultType_t<CPE>;
5261  using DataType = SubvectorData<CSAs...>;
5262  //**********************************************************************************************
5263 
5264  public:
5265  //**Type definitions****************************************************************************
5267  using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
5268 
5269  using BaseType = DenseVector<This,TF>;
5270  using ViewedType = CPE;
5271  using ResultType = SubvectorTrait_t<RT,CSAs...>;
5272  using TransposeType = TransposeType_t<ResultType>;
5273  using ElementType = ElementType_t<CPE>;
5274  using ReturnType = ReturnType_t<CPE>;
5275  using CompositeType = const ResultType;
5276  //**********************************************************************************************
5277 
5278  //**Compilation flags***************************************************************************
5280  static constexpr bool simdEnabled = false;
5281 
5283  static constexpr bool smpAssignable = false;
5284 
5286  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
5287  //**********************************************************************************************
5288 
5289  //**Constructor*********************************************************************************
5296  template< typename... RSAs > // Optional subvector arguments
5297  explicit inline Subvector( const CPE& vector, RSAs... args )
5298  : DataType( args... ) // Base class initialization
5299  , vector_ ( vector ) // The sparse vector/sparse vector cross product expression
5300  {
5301  if( Contains_v< TypeList<RSAs...>, Unchecked > ) {
5302  if( offset() + size() > vector.size() ) {
5303  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
5304  }
5305  }
5306  else {
5307  BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
5308  }
5309  }
5310  //**********************************************************************************************
5311 
5312  //**Subscript operator**************************************************************************
5318  inline ReturnType operator[]( size_t index ) const {
5319  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5320  return vector_[offset()+index];
5321  }
5322  //**********************************************************************************************
5323 
5324  //**At function*********************************************************************************
5331  inline ReturnType at( size_t index ) const {
5332  if( index >= size() ) {
5333  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5334  }
5335  return (*this)[index];
5336  }
5337  //**********************************************************************************************
5338 
5339  //**********************************************************************************************
5340  using DataType::offset;
5341  using DataType::size;
5342  //**********************************************************************************************
5343 
5344  //**Operand access******************************************************************************
5349  inline CPE operand() const noexcept {
5350  return vector_;
5351  }
5352  //**********************************************************************************************
5353 
5354  //**********************************************************************************************
5360  template< typename T >
5361  inline bool canAlias( const T* alias ) const noexcept {
5362  return vector_.canAlias( alias );
5363  }
5364  //**********************************************************************************************
5365 
5366  //**********************************************************************************************
5372  template< typename T >
5373  inline bool isAliased( const T* alias ) const {
5374  return vector_.isAliased( alias );
5375  }
5376  //**********************************************************************************************
5377 
5378  private:
5379  //**Member variables****************************************************************************
5380  CPE vector_;
5381  //**********************************************************************************************
5382 };
5384 //*************************************************************************************************
5385 
5386 } // namespace blaze
5387 
5388 #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.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
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:170
Header file for the View base class.
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
#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
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
Header file for the DenseVector base class.
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.
Header file for the reset shim.
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:187
#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.
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:253
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
constexpr bool IsContiguous_v
Auxiliary variable template for the IsContiguous type trait.The IsContiguous_v variable template prov...
Definition: IsContiguous.h:144
Header file for the DisableIf class template.
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.
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:9091
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:187
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h: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.
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
Header file for the implementation of the SubvectorData class template.
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:138
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
constexpr bool HasSIMDDiv_v
Auxiliary variable template for the HasSIMDDiv type trait.The HasSIMDDiv_v variable template provides...
Definition: HasSIMDDiv.h:171
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.
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:615
Header file for the CrossExpr base class.
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
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:558
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.
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 all forward declarations for expression class templates.
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
#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....
Definition: Subvector.h:81
Macro for CUDA compatibility.
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
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:188
Header file for the alignment check function.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
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:494
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
#define BLAZE_DEVICE_CALLABLE
Conditional macro that sets host and device attributes when compiled with CUDA.
Definition: HostDevice.h:94
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,...
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.