Dense.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_ELEMENTS_DENSE_H_
36 #define _BLAZE_MATH_VIEWS_ELEMENTS_DENSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <blaze/math/Aliases.h>
52 #include <blaze/math/Exception.h>
57 #include <blaze/math/shims/Clear.h>
59 #include <blaze/math/shims/Reset.h>
66 #include <blaze/math/views/Check.h>
70 #include <blaze/util/Assert.h>
72 #include <blaze/util/mpl/If.h>
73 #include <blaze/util/mpl/Not.h>
74 #include <blaze/util/TypeList.h>
77 
78 
79 namespace blaze {
80 
81 //=================================================================================================
82 //
83 // CLASS TEMPLATE SPECIALIZATION FOR DENSE VECTORS
84 //
85 //=================================================================================================
86 
87 //*************************************************************************************************
94 template< typename VT // Type of the dense vector
95  , bool TF // Transpose flag
96  , size_t... CEAs > // Compile time element arguments
97 class Elements<VT,TF,true,CEAs...>
98  : public View< DenseVector< Elements<VT,TF,true,CEAs...>, TF > >
99  , private ElementsData<CEAs...>
100 {
101  private:
102  //**Type definitions****************************************************************************
103  using DataType = ElementsData<CEAs...>;
104  using Operand = If_< IsExpression<VT>, VT, VT& >;
105  //**********************************************************************************************
106 
107  public:
108  //**Type definitions****************************************************************************
110  using This = Elements<VT,TF,true,CEAs...>;
111 
112  using BaseType = DenseVector<This,TF>;
113  using ViewedType = VT;
114  using ResultType = ElementsTrait_<VT,CEAs...>;
115  using TransposeType = TransposeType_<ResultType>;
116  using ElementType = ElementType_<VT>;
117  using ReturnType = ReturnType_<VT>;
118  using CompositeType = const Elements&;
119 
121  using ConstReference = ConstReference_<VT>;
122 
124  using Reference = If_< IsConst<VT>, ConstReference, Reference_<VT> >;
125 
127  using ConstPointer = ConstPointer_<VT>;
128 
130  using Pointer = If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, Pointer_<VT> >;
131  //**********************************************************************************************
132 
133  //**ElementsIterator class definition***********************************************************
136  template< typename ElementsType // Type of the element selection
137  , typename IteratorType > // Type of the dense vector iterator
138  class ElementsIterator
139  {
140  public:
141  //**Type definitions*************************************************************************
143  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
144 
146  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
147 
149  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
150 
152  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
153 
155  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
156 
157  // STL iterator requirements
158  using iterator_category = IteratorCategory;
159  using value_type = ValueType;
160  using pointer = PointerType;
161  using reference = ReferenceType;
162  using difference_type = DifferenceType;
163  //*******************************************************************************************
164 
165  //**Constructor******************************************************************************
168  inline ElementsIterator()
169  : elements_( nullptr ) // Pointer to the element selection
170  , index_ ( 0UL ) // Index of the current element of the element selection
171  , pos_ () // Iterator to the current element
172  {}
173  //*******************************************************************************************
174 
175  //**Constructor******************************************************************************
181  inline ElementsIterator( ElementsType* elements, size_t index )
182  : elements_( elements ) // Pointer to the element selection
183  , index_ ( index ) // Index of the current element of the element selection
184  , pos_ () // Iterator to the current element
185  {
186  if( index_ < elements_->size() )
187  pos_ = elements_->operand().begin() + elements_->idx( index_ );
188  }
189  //*******************************************************************************************
190 
191  //**Constructor******************************************************************************
196  template< typename ElementsType2, typename IteratorType2 >
197  inline ElementsIterator( const ElementsIterator<ElementsType2,IteratorType2>& it )
198  : elements_( it.elements_ ) // Pointer to the element selection
199  , index_ ( it.index_ ) // Index of the current element of the element selection
200  , pos_ ( it.pos_ ) // Iterator to the current element
201  {}
202  //*******************************************************************************************
203 
204  //**Addition assignment operator*************************************************************
210  inline ElementsIterator& operator+=( size_t inc ) {
211  using blaze::reset;
212  index_ += inc;
213  if( index_ < elements_->size() )
214  pos_ = elements_->operand().begin() + elements_->idx( index_ );
215  else reset( pos_ );
216  return *this;
217  }
218  //*******************************************************************************************
219 
220  //**Subtraction assignment operator**********************************************************
226  inline ElementsIterator& operator-=( size_t dec ) {
227  using blaze::reset;
228  index_ -= dec;
229  if( index_ < elements_->size() )
230  pos_ = elements_->operand().begin() + elements_->idx( index_ );
231  else reset( pos_ );
232  return *this;
233  }
234  //*******************************************************************************************
235 
236  //**Prefix increment operator****************************************************************
241  inline ElementsIterator& operator++() {
242  using blaze::reset;
243  ++index_;
244  if( index_ < elements_->size() )
245  pos_ = elements_->operand().begin() + elements_->idx( index_ );
246  else reset( pos_ );
247  return *this;
248  }
249  //*******************************************************************************************
250 
251  //**Postfix increment operator***************************************************************
256  inline const ElementsIterator operator++( int ) {
257  const ElementsIterator tmp( *this );
258  ++(*this);
259  return tmp;
260  }
261  //*******************************************************************************************
262 
263  //**Prefix decrement operator****************************************************************
268  inline ElementsIterator& operator--() {
269  using blaze::reset;
270  --index_;
271  if( index_ < elements_->size() )
272  pos_ = elements_->operand().begin() + elements_->idx( index_ );
273  else reset( pos_ );
274  return *this;
275  }
276  //*******************************************************************************************
277 
278  //**Postfix decrement operator***************************************************************
283  inline const ElementsIterator operator--( int ) {
284  const ElementsIterator tmp( *this );
285  --(*this);
286  return tmp;
287  }
288  //*******************************************************************************************
289 
290  //**Subscript operator***********************************************************************
296  inline ReferenceType operator[]( size_t index ) const {
297  const IteratorType pos( elements_->operand().begin() + elements_->idx( index_ + index ) );
298  return *pos;
299  }
300  //*******************************************************************************************
301 
302  //**Element access operator******************************************************************
307  inline ReferenceType operator*() const {
308  return *pos_;
309  }
310  //*******************************************************************************************
311 
312  //**Element access operator******************************************************************
317  inline PointerType operator->() const {
318  return pos_;
319  }
320  //*******************************************************************************************
321 
322  //**Equality operator************************************************************************
328  inline bool operator==( const ElementsIterator& rhs ) const {
329  return index_ == rhs.index_;
330  }
331  //*******************************************************************************************
332 
333  //**Inequality operator**********************************************************************
339  inline bool operator!=( const ElementsIterator& rhs ) const {
340  return index_ != rhs.index_;
341  }
342  //*******************************************************************************************
343 
344  //**Less-than operator***********************************************************************
350  inline bool operator<( const ElementsIterator& rhs ) const {
351  return index_ < rhs.index_;
352  }
353  //*******************************************************************************************
354 
355  //**Greater-than operator********************************************************************
361  inline bool operator>( const ElementsIterator& rhs ) const {
362  return index_ > rhs.index_;
363  }
364  //*******************************************************************************************
365 
366  //**Less-or-equal-than operator**************************************************************
372  inline bool operator<=( const ElementsIterator& rhs ) const {
373  return index_ <= rhs.index_;
374  }
375  //*******************************************************************************************
376 
377  //**Greater-or-equal-than operator***********************************************************
383  inline bool operator>=( const ElementsIterator& rhs ) const {
384  return index_ >= rhs.index_;
385  }
386  //*******************************************************************************************
387 
388  //**Subtraction operator*********************************************************************
394  inline DifferenceType operator-( const ElementsIterator& rhs ) const {
395  return index_ - rhs.index_;
396  }
397  //*******************************************************************************************
398 
399  //**Addition operator************************************************************************
406  friend inline const ElementsIterator operator+( const ElementsIterator& it, size_t inc ) {
407  return ElementsIterator( it.elements_, it.index_ + inc );
408  }
409  //*******************************************************************************************
410 
411  //**Addition operator************************************************************************
418  friend inline const ElementsIterator operator+( size_t inc, const ElementsIterator& it ) {
419  return ElementsIterator( it.elements_, it.index_ + inc );
420  }
421  //*******************************************************************************************
422 
423  //**Subtraction operator*********************************************************************
430  friend inline const ElementsIterator operator-( const ElementsIterator& it, size_t dec ) {
431  return ElementsIterator( it.elements_, it.index_ - dec );
432  }
433  //*******************************************************************************************
434 
435  private:
436  //**Member variables*************************************************************************
437  ElementsType* elements_;
438  size_t index_;
439  IteratorType pos_;
440  //*******************************************************************************************
441 
442  //**Friend declarations**********************************************************************
443  template< typename ElementsType2, typename IteratorType2 > friend class ElementsIterator;
444  //*******************************************************************************************
445  };
446  //**********************************************************************************************
447 
448  //**Type definitions****************************************************************************
450  using ConstIterator = ElementsIterator< const This, ConstIterator_<VT> >;
451 
453  using Iterator = If_< IsConst<VT>, ConstIterator, ElementsIterator< This, Iterator_<VT> > >;
454  //**********************************************************************************************
455 
456  //**Compilation flags***************************************************************************
458  enum : bool { simdEnabled = false };
459 
461  enum : bool { smpAssignable = VT::smpAssignable };
462  //**********************************************************************************************
463 
464  //**Constructors********************************************************************************
467  template< typename... REAs >
468  explicit inline Elements( VT& vector, REAs... args );
469 
470  inline Elements( const Elements& ) = default;
471  inline Elements( Elements&& ) = default;
473  //**********************************************************************************************
474 
475  //**Destructor**********************************************************************************
476  // No explicitly declared destructor.
477  //**********************************************************************************************
478 
479  //**Data access functions***********************************************************************
482  inline Reference operator[]( size_t index );
483  inline ConstReference operator[]( size_t index ) const;
484  inline Reference at( size_t index );
485  inline ConstReference at( size_t index ) const;
486  inline Pointer data () noexcept;
487  inline ConstPointer data () const noexcept;
488  inline Iterator begin ();
489  inline ConstIterator begin () const;
490  inline ConstIterator cbegin() const;
491  inline Iterator end ();
492  inline ConstIterator end () const;
493  inline ConstIterator cend () const;
495  //**********************************************************************************************
496 
497  //**Assignment operators************************************************************************
500  inline Elements& operator= ( const ElementType& rhs );
501  inline Elements& operator= ( initializer_list<ElementType> list );
502  inline Elements& operator= ( const Elements& rhs );
503  template< typename VT2 > inline Elements& operator= ( const Vector<VT2,TF>& rhs );
504  template< typename VT2 > inline Elements& operator+=( const Vector<VT2,TF>& rhs );
505  template< typename VT2 > inline Elements& operator-=( const Vector<VT2,TF>& rhs );
506  template< typename VT2 > inline Elements& operator*=( const Vector<VT2,TF>& rhs );
507  template< typename VT2 > inline Elements& operator/=( const DenseVector<VT2,TF>& rhs );
508  template< typename VT2 > inline Elements& operator%=( const Vector<VT2,TF>& rhs );
510  //**********************************************************************************************
511 
512  //**Utility functions***************************************************************************
515  using DataType::idces;
516  using DataType::idx;
517  using DataType::size;
518 
519  inline VT& operand() noexcept;
520  inline const VT& operand() const noexcept;
521 
522  inline size_t spacing() const noexcept;
523  inline size_t capacity() const noexcept;
524  inline size_t nonZeros() const;
525  inline void reset();
527  //**********************************************************************************************
528 
529  //**Numeric functions***************************************************************************
532  template< typename Other > inline Elements& scale( const Other& scalar );
534  //**********************************************************************************************
535 
536  //**Expression template evaluation functions****************************************************
539  template< typename Other >
540  inline bool canAlias( const Other* alias ) const noexcept;
541 
542  template< typename Other >
543  inline bool isAliased( const Other* alias ) const noexcept;
544 
545  inline bool isAligned () const noexcept;
546  inline bool canSMPAssign() const noexcept;
547 
548  template< typename VT2 > inline void assign ( const DenseVector <VT2,TF>& rhs );
549  template< typename VT2 > inline void assign ( const SparseVector<VT2,TF>& rhs );
550  template< typename VT2 > inline void addAssign ( const DenseVector <VT2,TF>& rhs );
551  template< typename VT2 > inline void addAssign ( const SparseVector<VT2,TF>& rhs );
552  template< typename VT2 > inline void subAssign ( const DenseVector <VT2,TF>& rhs );
553  template< typename VT2 > inline void subAssign ( const SparseVector<VT2,TF>& rhs );
554  template< typename VT2 > inline void multAssign( const DenseVector <VT2,TF>& rhs );
555  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
556  template< typename VT2 > inline void divAssign ( const DenseVector <VT2,TF>& rhs );
558  //**********************************************************************************************
559 
560  private:
561  //**Member variables****************************************************************************
564  Operand vector_;
565 
566  //**********************************************************************************************
567 
568  //**Compile time checks*************************************************************************
574  //**********************************************************************************************
575 };
577 //*************************************************************************************************
578 
579 
580 
581 
582 //=================================================================================================
583 //
584 // CONSTRUCTORS
585 //
586 //=================================================================================================
587 
588 //*************************************************************************************************
601 template< typename VT // Type of the dense vector
602  , bool TF // Transpose flag
603  , size_t... CEAs > // Compile time element arguments
604 template< typename... REAs > // Optional arguments
605 inline Elements<VT,TF,true,CEAs...>::Elements( VT& vector, REAs... args )
606  : DataType( args... ) // Base class initialization
607  , vector_ ( vector ) // The vector containing the elements
608 {
609  if( !Contains< TypeList<REAs...>, Unchecked >::value ) {
610  for( size_t i=0UL; i<size(); ++i ) {
611  if( vector_.size() <= idx(i) ) {
612  BLAZE_THROW_INVALID_ARGUMENT( "Invalid element access index" );
613  }
614  }
615  }
616 }
618 //*************************************************************************************************
619 
620 
621 
622 
623 //=================================================================================================
624 //
625 // DATA ACCESS FUNCTIONS
626 //
627 //=================================================================================================
628 
629 //*************************************************************************************************
639 template< typename VT // Type of the dense vector
640  , bool TF // Transpose flag
641  , size_t... CEAs > // Compile time element arguments
642 inline typename Elements<VT,TF,true,CEAs...>::Reference
643  Elements<VT,TF,true,CEAs...>::operator[]( size_t index )
644 {
645  BLAZE_USER_ASSERT( index < size(), "Invalid element access index" );
646  return vector_[idx(index)];
647 }
649 //*************************************************************************************************
650 
651 
652 //*************************************************************************************************
662 template< typename VT // Type of the dense vector
663  , bool TF // Transpose flag
664  , size_t... CEAs > // Compile time element arguments
665 inline typename Elements<VT,TF,true,CEAs...>::ConstReference
666  Elements<VT,TF,true,CEAs...>::operator[]( size_t index ) const
667 {
668  BLAZE_USER_ASSERT( index < size(), "Invalid element access index" );
669  return const_cast<const VT&>( vector_ )[idx(index)];
670 }
672 //*************************************************************************************************
673 
674 
675 //*************************************************************************************************
686 template< typename VT // Type of the dense vector
687  , bool TF // Transpose flag
688  , size_t... CEAs > // Compile time element arguments
689 inline typename Elements<VT,TF,true,CEAs...>::Reference
690  Elements<VT,TF,true,CEAs...>::at( size_t index )
691 {
692  if( index >= size() ) {
693  BLAZE_THROW_OUT_OF_RANGE( "Invalid element access index" );
694  }
695  return (*this)[index];
696 }
698 //*************************************************************************************************
699 
700 
701 //*************************************************************************************************
712 template< typename VT // Type of the dense vector
713  , bool TF // Transpose flag
714  , size_t... CEAs > // Compile time element arguments
715 inline typename Elements<VT,TF,true,CEAs...>::ConstReference
716  Elements<VT,TF,true,CEAs...>::at( size_t index ) const
717 {
718  if( index >= size() ) {
719  BLAZE_THROW_OUT_OF_RANGE( "Invalid element access index" );
720  }
721  return (*this)[index];
722 }
724 //*************************************************************************************************
725 
726 
727 //*************************************************************************************************
735 template< typename VT // Type of the dense vector
736  , bool TF // Transpose flag
737  , size_t... CEAs > // Compile time element arguments
738 inline typename Elements<VT,TF,true,CEAs...>::Pointer
740 {
741  return vector_.data() + idx(0UL);
742 }
744 //*************************************************************************************************
745 
746 
747 //*************************************************************************************************
755 template< typename VT // Type of the dense vector
756  , bool TF // Transpose flag
757  , size_t... CEAs > // Compile time element arguments
758 inline typename Elements<VT,TF,true,CEAs...>::ConstPointer
759  Elements<VT,TF,true,CEAs...>::data() const noexcept
760 {
761  return vector_.data() + idx(0UL);
762 }
764 //*************************************************************************************************
765 
766 
767 //*************************************************************************************************
775 template< typename VT // Type of the dense vector
776  , bool TF // Transpose flag
777  , size_t... CEAs > // Compile time element arguments
778 inline typename Elements<VT,TF,true,CEAs...>::Iterator
780 {
781  return Iterator( this, 0UL );
782 }
784 //*************************************************************************************************
785 
786 
787 //*************************************************************************************************
795 template< typename VT // Type of the dense vector
796  , bool TF // Transpose flag
797  , size_t... CEAs > // Compile time element arguments
798 inline typename Elements<VT,TF,true,CEAs...>::ConstIterator
800 {
801  return ConstIterator( this, 0UL );
802 }
804 //*************************************************************************************************
805 
806 
807 //*************************************************************************************************
815 template< typename VT // Type of the dense vector
816  , bool TF // Transpose flag
817  , size_t... CEAs > // Compile time element arguments
818 inline typename Elements<VT,TF,true,CEAs...>::ConstIterator
820 {
821  return ConstIterator( this, 0UL );
822 }
824 //*************************************************************************************************
825 
826 
827 //*************************************************************************************************
835 template< typename VT // Type of the dense vector
836  , bool TF // Transpose flag
837  , size_t... CEAs > // Compile time element arguments
838 inline typename Elements<VT,TF,true,CEAs...>::Iterator
840 {
841  return Iterator( this, size() );
842 }
844 //*************************************************************************************************
845 
846 
847 //*************************************************************************************************
855 template< typename VT // Type of the dense vector
856  , bool TF // Transpose flag
857  , size_t... CEAs > // Compile time element arguments
858 inline typename Elements<VT,TF,true,CEAs...>::ConstIterator
860 {
861  return ConstIterator( this, size() );
862 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
875 template< typename VT // Type of the dense vector
876  , bool TF // Transpose flag
877  , size_t... CEAs > // Compile time element arguments
878 inline typename Elements<VT,TF,true,CEAs...>::ConstIterator
880 {
881  return ConstIterator( this, size() );
882 }
884 //*************************************************************************************************
885 
886 
887 
888 
889 //=================================================================================================
890 //
891 // ASSIGNMENT OPERATORS
892 //
893 //=================================================================================================
894 
895 //*************************************************************************************************
902 template< typename VT // Type of the dense vector
903  , bool TF // Transpose flag
904  , size_t... CEAs > // Compile time element arguments
905 inline Elements<VT,TF,true,CEAs...>&
906  Elements<VT,TF,true,CEAs...>::operator=( const ElementType& rhs )
907 {
908  decltype(auto) left( derestrict( vector_ ) );
909 
910  for( size_t i=0UL; i<size(); ++i ) {
911  const size_t index( idx(i) );
912  if( !IsRestricted<VT>::value || trySet( vector_, index, rhs ) )
913  left[index] = rhs;
914  }
915 
916  return *this;
917 }
919 //*************************************************************************************************
920 
921 
922 //*************************************************************************************************
938 template< typename VT // Type of the dense vector
939  , bool TF // Transpose flag
940  , size_t... CEAs > // Compile time element arguments
941 inline Elements<VT,TF,true,CEAs...>&
942  Elements<VT,TF,true,CEAs...>::operator=( initializer_list<ElementType> list )
943 {
944  if( list.size() > size() ) {
945  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to elements" );
946  }
947 
948  const InitializerVector<ElementType,TF> tmp( list, size() );
949 
950  if( IsRestricted<VT>::value ) {
951  for( size_t i=0UL; i<size(); ++i ) {
952  if( !trySet( vector_, idx(i), tmp[i] ) ) {
953  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
954  }
955  }
956  }
957 
958  decltype(auto) left( derestrict( vector_ ) );
959  for( size_t i=0UL; i<size(); ++i ) {
960  left[idx(i)] = tmp[i];
961  }
962 
963  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
964 
965  return *this;
966 }
968 //*************************************************************************************************
969 
970 
971 //*************************************************************************************************
983 template< typename VT // Type of the dense vector
984  , bool TF // Transpose flag
985  , size_t... CEAs > // Compile time element arguments
986 inline Elements<VT,TF,true,CEAs...>&
987  Elements<VT,TF,true,CEAs...>::operator=( const Elements& rhs )
988 {
991 
992  if( &rhs == this || ( &vector_ == &rhs.vector_ && idces() == rhs.idces() ) )
993  return *this;
994 
995  if( size() != rhs.size() ) {
996  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
997  }
998 
999  if( IsRestricted<VT>::value ) {
1000  for( size_t i=0UL; i<size(); ++i ) {
1001  if( !trySet( vector_, idx(i), rhs[i] ) ) {
1002  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1003  }
1004  }
1005  }
1006 
1007  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1008 
1009  if( rhs.canAlias( &vector_ ) ) {
1010  const ResultType tmp( rhs );
1011  smpAssign( left, tmp );
1012  }
1013  else {
1014  smpAssign( left, rhs );
1015  }
1016 
1017  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1018 
1019  return *this;
1020 }
1022 //*************************************************************************************************
1023 
1024 
1025 //*************************************************************************************************
1037 template< typename VT // Type of the dense vector
1038  , bool TF // Transpose flag
1039  , size_t... CEAs > // Compile time element arguments
1040 template< typename VT2 > // Type of the right-hand side vector
1041 inline Elements<VT,TF,true,CEAs...>&
1042  Elements<VT,TF,true,CEAs...>::operator=( const Vector<VT2,TF>& rhs )
1043 {
1046 
1047  if( size() != (~rhs).size() ) {
1048  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1049  }
1050 
1051  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1052  Right right( ~rhs );
1053 
1054  if( IsRestricted<VT>::value ) {
1055  for( size_t i=0UL; i<size(); ++i ) {
1056  if( !trySet( vector_, idx(i), right[i] ) ) {
1057  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1058  }
1059  }
1060  }
1061 
1062  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1063 
1064  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1065  const ResultType_<VT2> tmp( right );
1066  smpAssign( left, tmp );
1067  }
1068  else {
1069  if( IsSparseVector<VT2>::value )
1070  reset();
1071  smpAssign( left, right );
1072  }
1073 
1074  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1075 
1076  return *this;
1077 }
1079 //*************************************************************************************************
1080 
1081 
1082 //*************************************************************************************************
1094 template< typename VT // Type of the dense vector
1095  , bool TF // Transpose flag
1096  , size_t... CEAs > // Compile time element arguments
1097 template< typename VT2 > // Type of the right-hand side vector
1098 inline Elements<VT,TF,true,CEAs...>&
1099  Elements<VT,TF,true,CEAs...>::operator+=( const Vector<VT2,TF>& rhs )
1100 {
1103 
1104  if( size() != (~rhs).size() ) {
1105  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1106  }
1107 
1108  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1109  Right right( ~rhs );
1110 
1111  if( IsRestricted<VT>::value ) {
1112  for( size_t i=0UL; i<size(); ++i ) {
1113  if( !tryAdd( vector_, idx(i), right[i] ) ) {
1114  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1115  }
1116  }
1117  }
1118 
1119  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1120 
1121  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1122  const ResultType_<VT2> tmp( right );
1123  smpAddAssign( left, tmp );
1124  }
1125  else {
1126  smpAddAssign( left, right );
1127  }
1128 
1129  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1130 
1131  return *this;
1132 }
1134 //*************************************************************************************************
1135 
1136 
1137 //*************************************************************************************************
1149 template< typename VT // Type of the dense vector
1150  , bool TF // Transpose flag
1151  , size_t... CEAs > // Compile time element arguments
1152 template< typename VT2 > // Type of the right-hand side vector
1153 inline Elements<VT,TF,true,CEAs...>&
1154  Elements<VT,TF,true,CEAs...>::operator-=( const Vector<VT2,TF>& rhs )
1155 {
1158 
1159  if( size() != (~rhs).size() ) {
1160  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1161  }
1162 
1163  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1164  Right right( ~rhs );
1165 
1166  if( IsRestricted<VT>::value ) {
1167  for( size_t i=0UL; i<size(); ++i ) {
1168  if( !trySub( vector_, idx(i), right[i] ) ) {
1169  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1170  }
1171  }
1172  }
1173 
1174  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1175 
1176  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1177  const ResultType_<VT2> tmp( right );
1178  smpSubAssign( left, tmp );
1179  }
1180  else {
1181  smpSubAssign( left, right );
1182  }
1183 
1184  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1185 
1186  return *this;
1187 }
1189 //*************************************************************************************************
1190 
1191 
1192 //*************************************************************************************************
1205 template< typename VT // Type of the dense vector
1206  , bool TF // Transpose flag
1207  , size_t... CEAs > // Compile time element arguments
1208 template< typename VT2 > // Type of the right-hand side vector
1209 inline Elements<VT,TF,true,CEAs...>&
1210  Elements<VT,TF,true,CEAs...>::operator*=( const Vector<VT2,TF>& rhs )
1211 {
1214 
1215  if( size() != (~rhs).size() ) {
1216  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1217  }
1218 
1219  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1220  Right right( ~rhs );
1221 
1222  if( IsRestricted<VT>::value ) {
1223  for( size_t i=0UL; i<size(); ++i ) {
1224  if( !tryMult( vector_, idx(i), right[i] ) ) {
1225  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1226  }
1227  }
1228  }
1229 
1230  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1231 
1232  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1233  const ResultType_<VT2> tmp( right );
1234  smpMultAssign( left, tmp );
1235  }
1236  else {
1237  smpMultAssign( left, right );
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... CEAs > // Compile time element arguments
1263 template< typename VT2 > // Type of the right-hand side dense vector
1264 inline Elements<VT,TF,true,CEAs...>&
1265  Elements<VT,TF,true,CEAs...>::operator/=( const DenseVector<VT2,TF>& rhs )
1266 {
1269 
1270  if( size() != (~rhs).size() ) {
1271  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1272  }
1273 
1274  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1275  Right right( ~rhs );
1276 
1277  if( IsRestricted<VT>::value ) {
1278  for( size_t i=0UL; i<size(); ++i ) {
1279  if( !tryDiv( vector_, idx(i), right[i] ) ) {
1280  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1281  }
1282  }
1283  }
1284 
1285  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1286 
1287  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1288  const ResultType_<VT2> tmp( right );
1289  smpDivAssign( left, tmp );
1290  }
1291  else {
1292  smpDivAssign( left, right );
1293  }
1294 
1295  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1296 
1297  return *this;
1298 }
1300 //*************************************************************************************************
1301 
1302 
1303 //*************************************************************************************************
1316 template< typename VT // Type of the dense vector
1317  , bool TF // Transpose flag
1318  , size_t... CEAs > // Compile time element arguments
1319 template< typename VT2 > // Type of the right-hand side vector
1320 inline Elements<VT,TF,true,CEAs...>&
1321  Elements<VT,TF,true,CEAs...>::operator%=( const Vector<VT2,TF>& rhs )
1322 {
1323  using blaze::assign;
1324 
1327 
1328  using CrossType = CrossTrait_< ResultType, ResultType_<VT2> >;
1329 
1333 
1334  if( size() != 3UL || (~rhs).size() != 3UL ) {
1335  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1336  }
1337 
1338  const CrossType tmp( *this % (~rhs) );
1339 
1340  if( IsRestricted<VT>::value ) {
1341  for( size_t i=0UL; i<size(); ++i ) {
1342  if( !trySet( vector_, idx(i), tmp[i] ) ) {
1343  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1344  }
1345  }
1346  }
1347 
1348  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1349 
1350  assign( left, tmp );
1351 
1352  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1353 
1354  return *this;
1355 }
1357 //*************************************************************************************************
1358 
1359 
1360 
1361 
1362 //=================================================================================================
1363 //
1364 // UTILITY FUNCTIONS
1365 //
1366 //=================================================================================================
1367 
1368 //*************************************************************************************************
1374 template< typename VT // Type of the dense vector
1375  , bool TF // Transpose flag
1376  , size_t... CEAs > // Compile time element arguments
1377 inline VT& Elements<VT,TF,true,CEAs...>::operand() noexcept
1378 {
1379  return vector_;
1380 }
1382 //*************************************************************************************************
1383 
1384 
1385 //*************************************************************************************************
1391 template< typename VT // Type of the dense vector
1392  , bool TF // Transpose flag
1393  , size_t... CEAs > // Compile time element arguments
1394 inline const VT& Elements<VT,TF,true,CEAs...>::operand() const noexcept
1395 {
1396  return vector_;
1397 }
1399 //*************************************************************************************************
1400 
1401 
1402 //*************************************************************************************************
1408 template< typename VT // Type of the dense vector
1409  , bool TF // Transpose flag
1410  , size_t... CEAs > // Compile time element arguments
1411 inline size_t Elements<VT,TF,true,CEAs...>::spacing() const noexcept
1412 {
1413  return size();
1414 }
1416 //*************************************************************************************************
1417 
1418 
1419 //*************************************************************************************************
1425 template< typename VT // Type of the dense vector
1426  , bool TF // Transpose flag
1427  , size_t... CEAs > // Compile time element arguments
1428 inline size_t Elements<VT,TF,true,CEAs...>::capacity() const noexcept
1429 {
1430  return size();
1431 }
1433 //*************************************************************************************************
1434 
1435 
1436 //*************************************************************************************************
1445 template< typename VT // Type of the dense vector
1446  , bool TF // Transpose flag
1447  , size_t... CEAs > // Compile time element arguments
1448 inline size_t Elements<VT,TF,true,CEAs...>::nonZeros() const
1449 {
1450  size_t nonzeros( 0 );
1451 
1452  for( size_t i=0UL; i<size(); ++i ) {
1453  if( !isDefault( vector_[idx(i)] ) )
1454  ++nonzeros;
1455  }
1456 
1457  return nonzeros;
1458 }
1460 //*************************************************************************************************
1461 
1462 
1463 //*************************************************************************************************
1469 template< typename VT // Type of the dense vector
1470  , bool TF // Transpose flag
1471  , size_t... CEAs > // Compile time element arguments
1473 {
1474  using blaze::clear;
1475 
1476  for( size_t i=0UL; i<size(); ++i )
1477  clear( vector_[idx(i)] );
1478 }
1480 //*************************************************************************************************
1481 
1482 
1483 
1484 
1485 //=================================================================================================
1486 //
1487 // NUMERIC FUNCTIONS
1488 //
1489 //=================================================================================================
1490 
1491 //*************************************************************************************************
1502 template< typename VT // Type of the dense vector
1503  , bool TF // Transpose flag
1504  , size_t... CEAs > // Compile time element arguments
1505 template< typename Other > // Data type of the scalar value
1506 inline Elements<VT,TF,true,CEAs...>&
1507  Elements<VT,TF,true,CEAs...>::scale( const Other& scalar )
1508 {
1509  for( size_t i=0UL; i<size(); ++i )
1510  vector_[idx(i)] *= scalar;
1511  return *this;
1512 }
1514 //*************************************************************************************************
1515 
1516 
1517 
1518 
1519 //=================================================================================================
1520 //
1521 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1522 //
1523 //=================================================================================================
1524 
1525 //*************************************************************************************************
1536 template< typename VT // Type of the dense vector
1537  , bool TF // Transpose flag
1538  , size_t... CEAs > // Compile time element arguments
1539 template< typename Other > // Data type of the foreign expression
1540 inline bool Elements<VT,TF,true,CEAs...>::canAlias( const Other* alias ) const noexcept
1541 {
1542  return vector_.isAliased( alias );
1543 }
1545 //*************************************************************************************************
1546 
1547 
1548 //*************************************************************************************************
1559 template< typename VT // Type of the dense vector
1560  , bool TF // Transpose flag
1561  , size_t... CEAs > // Compile time element arguments
1562 template< typename Other > // Data type of the foreign expression
1563 inline bool Elements<VT,TF,true,CEAs...>::isAliased( const Other* alias ) const noexcept
1564 {
1565  return vector_.isAliased( alias );
1566 }
1568 //*************************************************************************************************
1569 
1570 
1571 //*************************************************************************************************
1581 template< typename VT // Type of the dense vector
1582  , bool TF // Transpose flag
1583  , size_t... CEAs > // Compile time element arguments
1584 inline bool Elements<VT,TF,true,CEAs...>::isAligned() const noexcept
1585 {
1586  return false;
1587 }
1589 //*************************************************************************************************
1590 
1591 
1592 //*************************************************************************************************
1603 template< typename VT // Type of the dense vector
1604  , bool TF // Transpose flag
1605  , size_t... CEAs > // Compile time element arguments
1606 inline bool Elements<VT,TF,true,CEAs...>::canSMPAssign() const noexcept
1607 {
1608  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1609 }
1611 //*************************************************************************************************
1612 
1613 
1614 //*************************************************************************************************
1626 template< typename VT // Type of the dense vector
1627  , bool TF // Transpose flag
1628  , size_t... CEAs > // Compile time element arguments
1629 template< typename VT2 > // Type of the right-hand side dense vector
1630 inline void Elements<VT,TF,true,CEAs...>::assign( const DenseVector<VT2,TF>& rhs )
1631 {
1632  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1633 
1634  const size_t ipos( size() & size_t(-2) );
1635  for( size_t i=0UL; i<ipos; i+=2UL ) {
1636  vector_[idx(i )] = (~rhs)[i ];
1637  vector_[idx(i+1UL)] = (~rhs)[i+1UL];
1638  }
1639  if( ipos < size() ) {
1640  vector_[idx(ipos)] = (~rhs)[ipos];
1641  }
1642 }
1644 //*************************************************************************************************
1645 
1646 
1647 //*************************************************************************************************
1659 template< typename VT // Type of the dense vector
1660  , bool TF // Transpose flag
1661  , size_t... CEAs > // Compile time element arguments
1662 template< typename VT2 > // Type of the right-hand side sparse vector
1663 inline void Elements<VT,TF,true,CEAs...>::assign( const SparseVector<VT2,TF>& rhs )
1664 {
1665  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1666 
1667  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1668  vector_[idx(element->index())] = element->value();
1669 }
1671 //*************************************************************************************************
1672 
1673 
1674 //*************************************************************************************************
1686 template< typename VT // Type of the dense vector
1687  , bool TF // Transpose flag
1688  , size_t... CEAs > // Compile time element arguments
1689 template< typename VT2 > // Type of the right-hand side dense vector
1690 inline void Elements<VT,TF,true,CEAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
1691 {
1692  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1693 
1694  const size_t ipos( size() & size_t(-2) );
1695  for( size_t i=0UL; i<ipos; i+=2UL ) {
1696  vector_[idx(i )] += (~rhs)[i ];
1697  vector_[idx(i+1UL)] += (~rhs)[i+1UL];
1698  }
1699  if( ipos < size() ) {
1700  vector_[idx(ipos)] += (~rhs)[ipos];
1701  }
1702 }
1704 //*************************************************************************************************
1705 
1706 
1707 //*************************************************************************************************
1719 template< typename VT // Type of the dense vector
1720  , bool TF // Transpose flag
1721  , size_t... CEAs > // Compile time element arguments
1722 template< typename VT2 > // Type of the right-hand side sparse vector
1723 inline void Elements<VT,TF,true,CEAs...>::addAssign( const SparseVector<VT2,TF>& rhs )
1724 {
1725  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1726 
1727  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1728  vector_[idx(element->index())] += element->value();
1729 }
1731 //*************************************************************************************************
1732 
1733 
1734 //*************************************************************************************************
1746 template< typename VT // Type of the dense vector
1747  , bool TF // Transpose flag
1748  , size_t... CEAs > // Compile time element arguments
1749 template< typename VT2 > // Type of the right-hand side dense vector
1750 inline void Elements<VT,TF,true,CEAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
1751 {
1752  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1753 
1754  const size_t ipos( size() & size_t(-2) );
1755  for( size_t i=0UL; i<ipos; i+=2UL ) {
1756  vector_[idx(i )] -= (~rhs)[i ];
1757  vector_[idx(i+1UL)] -= (~rhs)[i+1UL];
1758  }
1759  if( ipos < size() ) {
1760  vector_[idx(ipos)] -= (~rhs)[ipos];
1761  }
1762 }
1764 //*************************************************************************************************
1765 
1766 
1767 //*************************************************************************************************
1779 template< typename VT // Type of the dense vector
1780  , bool TF // Transpose flag
1781  , size_t... CEAs > // Compile time element arguments
1782 template< typename VT2 > // Type of the right-hand side sparse vector
1783 inline void Elements<VT,TF,true,CEAs...>::subAssign( const SparseVector<VT2,TF>& rhs )
1784 {
1785  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1786 
1787  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1788  vector_[idx(element->index())] -= element->value();
1789 }
1791 //*************************************************************************************************
1792 
1793 
1794 //*************************************************************************************************
1806 template< typename VT // Type of the dense vector
1807  , bool TF // Transpose flag
1808  , size_t... CEAs > // Compile time element arguments
1809 template< typename VT2 > // Type of the right-hand side dense vector
1810 inline void Elements<VT,TF,true,CEAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
1811 {
1812  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1813 
1814  const size_t ipos( size() & size_t(-2) );
1815  for( size_t i=0UL; i<ipos; i+=2UL ) {
1816  vector_[idx(i )] *= (~rhs)[i ];
1817  vector_[idx(i+1UL)] *= (~rhs)[i+1UL];
1818  }
1819  if( ipos < size() ) {
1820  vector_[idx(ipos)] *= (~rhs)[ipos];
1821  }
1822 }
1824 //*************************************************************************************************
1825 
1826 
1827 //*************************************************************************************************
1839 template< typename VT // Type of the dense vector
1840  , bool TF // Transpose flag
1841  , size_t... CEAs > // Compile time element arguments
1842 template< typename VT2 > // Type of the right-hand side sparse vector
1843 inline void Elements<VT,TF,true,CEAs...>::multAssign( const SparseVector<VT2,TF>& rhs )
1844 {
1845  using blaze::reset;
1846 
1847  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1848 
1849  size_t i( 0UL );
1850 
1851  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
1852  const size_t index( element->index() );
1853  for( ; i<index; ++i )
1854  reset( vector_[idx(i)] );
1855  vector_[idx(i)] *= element->value();
1856  ++i;
1857  }
1858 
1859  for( ; i<size(); ++i ) {
1860  reset( vector_[idx(i)] );
1861  }
1862 }
1864 //*************************************************************************************************
1865 
1866 
1867 //*************************************************************************************************
1879 template< typename VT // Type of the dense vector
1880  , bool TF // Transpose flag
1881  , size_t... CEAs > // Compile time element arguments
1882 template< typename VT2 > // Type of the right-hand side dense vector
1883 inline void Elements<VT,TF,true,CEAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
1884 {
1885  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1886 
1887  const size_t ipos( size() & size_t(-2) );
1888  for( size_t i=0UL; i<ipos; i+=2UL ) {
1889  vector_[idx(i )] /= (~rhs)[i ];
1890  vector_[idx(i+1UL)] /= (~rhs)[i+1UL];
1891  }
1892  if( ipos < size() ) {
1893  vector_[idx(ipos)] /= (~rhs)[ipos];
1894  }
1895 }
1897 //*************************************************************************************************
1898 
1899 
1900 
1901 
1902 
1903 
1904 
1905 
1906 //=================================================================================================
1907 //
1908 // CLASS TEMPLATE SPECIALIZATION FOR DVECDVECCROSSEXPR
1909 //
1910 //=================================================================================================
1911 
1912 //*************************************************************************************************
1920 template< typename VT1 // Type of the left-hand side dense vector
1921  , typename VT2 // Type of the right-hand side dense vector
1922  , bool TF // Transpose flag
1923  , size_t... CEAs > // Compile time element arguments
1924 class Elements< DVecDVecCrossExpr<VT1,VT2,TF>, TF, true, CEAs... >
1925  : public View< DenseVector< Elements< DVecDVecCrossExpr<VT1,VT2,TF>, TF, true, CEAs... >, TF > >
1926  , private ElementsData<CEAs...>
1927 {
1928  private:
1929  //**Type definitions****************************************************************************
1930  using CPE = DVecDVecCrossExpr<VT1,VT2,TF>;
1931  using RT = ResultType_<CPE>;
1932  using DataType = ElementsData<CEAs...>;
1933  //**********************************************************************************************
1934 
1935  public:
1936  //**Type definitions****************************************************************************
1938  using This = Elements<CPE,TF,true,CEAs...>;
1939 
1940  using BaseType = DenseVector<This,TF>;
1941  using ViewedType = CPE;
1942  using ResultType = ElementsTrait_<RT,CEAs...>;
1943  using TransposeType = TransposeType_<ResultType>;
1944  using ElementType = ElementType_<CPE>;
1945  using ReturnType = ReturnType_<CPE>;
1946  using CompositeType = const ResultType;
1947  //**********************************************************************************************
1948 
1949  //**Compilation flags***************************************************************************
1951  enum : bool { simdEnabled = false };
1952 
1954  enum : bool { smpAssignable = false };
1955  //**********************************************************************************************
1956 
1957  //**Constructor*********************************************************************************
1964  template< typename... REAs > // Optional element arguments
1965  explicit inline Elements( const CPE& vector, REAs... args )
1966  : DataType( args... ) // Base class initialization
1967  , vector_ ( vector ) // The dense vector/dense vector cross product expression
1968  {
1969  if( !Contains< TypeList<REAs...>, Unchecked >::value ) {
1970  for( size_t i=0UL; i<size(); ++i ) {
1971  if( vector_.size() <= idx(i) ) {
1972  BLAZE_THROW_INVALID_ARGUMENT( "Invalid element access index" );
1973  }
1974  }
1975  }
1976  }
1977  //**********************************************************************************************
1978 
1979  //**Subscript operator**************************************************************************
1985  inline ReturnType operator[]( size_t index ) const {
1986  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
1987  return vector_[idx(index)];
1988  }
1989  //**********************************************************************************************
1990 
1991  //**At function*********************************************************************************
1998  inline ReturnType at( size_t index ) const {
1999  if( index >= size() ) {
2000  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
2001  }
2002  return (*this)[index];
2003  }
2004  //**********************************************************************************************
2005 
2006  //**********************************************************************************************
2007  using DataType::idces;
2008  using DataType::idx;
2009  using DataType::size;
2010  //**********************************************************************************************
2011 
2012  //**Operand access******************************************************************************
2017  inline CPE operand() const noexcept {
2018  return vector_;
2019  }
2020  //**********************************************************************************************
2021 
2022  //**********************************************************************************************
2028  template< typename T >
2029  inline bool canAlias( const T* alias ) const noexcept {
2030  return vector_.canAlias( alias );
2031  }
2032  //**********************************************************************************************
2033 
2034  //**********************************************************************************************
2040  template< typename T >
2041  inline bool isAliased( const T* alias ) const noexcept {
2042  return vector_.isAliased( alias );
2043  }
2044  //**********************************************************************************************
2045 
2046  private:
2047  //**Member variables****************************************************************************
2048  CPE vector_;
2049  //**********************************************************************************************
2050 };
2052 //*************************************************************************************************
2053 
2054 
2055 
2056 
2057 
2058 
2059 
2060 
2061 //=================================================================================================
2062 //
2063 // CLASS TEMPLATE SPECIALIZATION FOR DVECSVECCROSSEXPR
2064 //
2065 //=================================================================================================
2066 
2067 //*************************************************************************************************
2075 template< typename VT1 // Type of the left-hand side dense vector
2076  , typename VT2 // Type of the right-hand side sparse vector
2077  , bool TF // Transpose flag
2078  , size_t... CEAs > // Compile time element arguments
2079 class Elements< DVecSVecCrossExpr<VT1,VT2,TF>, TF, true, CEAs... >
2080  : public View< DenseVector< Elements< DVecSVecCrossExpr<VT1,VT2,TF>, TF, true, CEAs... >, TF > >
2081  , private ElementsData<CEAs...>
2082 {
2083  private:
2084  //**Type definitions****************************************************************************
2085  using CPE = DVecSVecCrossExpr<VT1,VT2,TF>;
2086  using RT = ResultType_<CPE>;
2087  using DataType = ElementsData<CEAs...>;
2088  //**********************************************************************************************
2089 
2090  public:
2091  //**Type definitions****************************************************************************
2093  using This = Elements<CPE,TF,true,CEAs...>;
2094 
2095  using BaseType = DenseVector<This,TF>;
2096  using ViewedType = CPE;
2097  using ResultType = ElementsTrait_<RT,CEAs...>;
2098  using TransposeType = TransposeType_<ResultType>;
2099  using ElementType = ElementType_<CPE>;
2100  using ReturnType = ReturnType_<CPE>;
2101  using CompositeType = const ResultType;
2102  //**********************************************************************************************
2103 
2104  //**Compilation flags***************************************************************************
2106  enum : bool { simdEnabled = false };
2107 
2109  enum : bool { smpAssignable = false };
2110  //**********************************************************************************************
2111 
2112  //**Constructor*********************************************************************************
2119  template< typename... REAs > // Optional element arguments
2120  explicit inline Elements( const CPE& vector, REAs... args )
2121  : DataType( args... ) // Base class initialization
2122  , vector_ ( vector ) // The dense vector/sparse vector cross product expression
2123  {
2124  if( !Contains< TypeList<REAs...>, Unchecked >::value ) {
2125  for( size_t i=0UL; i<size(); ++i ) {
2126  if( vector_.size() <= idx(i) ) {
2127  BLAZE_THROW_INVALID_ARGUMENT( "Invalid element access index" );
2128  }
2129  }
2130  }
2131  }
2132  //**********************************************************************************************
2133 
2134  //**Subscript operator**************************************************************************
2140  inline ReturnType operator[]( size_t index ) const {
2141  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
2142  return vector_[idx(index)];
2143  }
2144  //**********************************************************************************************
2145 
2146  //**At function*********************************************************************************
2153  inline ReturnType at( size_t index ) const {
2154  if( index >= size() ) {
2155  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
2156  }
2157  return (*this)[index];
2158  }
2159  //**********************************************************************************************
2160 
2161  //**********************************************************************************************
2162  using DataType::idces;
2163  using DataType::idx;
2164  using DataType::size;
2165  //**********************************************************************************************
2166 
2167  //**Operand access******************************************************************************
2172  inline CPE operand() const noexcept {
2173  return vector_;
2174  }
2175  //**********************************************************************************************
2176 
2177  //**********************************************************************************************
2183  template< typename T >
2184  inline bool canAlias( const T* alias ) const noexcept {
2185  return vector_.canAlias( alias );
2186  }
2187  //**********************************************************************************************
2188 
2189  //**********************************************************************************************
2195  template< typename T >
2196  inline bool isAliased( const T* alias ) const noexcept {
2197  return vector_.isAliased( alias );
2198  }
2199  //**********************************************************************************************
2200 
2201  private:
2202  //**Member variables****************************************************************************
2203  CPE vector_;
2204  //**********************************************************************************************
2205 };
2207 //*************************************************************************************************
2208 
2209 
2210 
2211 
2212 
2213 
2214 
2215 
2216 //=================================================================================================
2217 //
2218 // CLASS TEMPLATE SPECIALIZATION FOR SVECDVECCROSSEXPR
2219 //
2220 //=================================================================================================
2221 
2222 //*************************************************************************************************
2230 template< typename VT1 // Type of the left-hand side sparse vector
2231  , typename VT2 // Type of the right-hand side dense vector
2232  , bool TF // Transpose flag
2233  , size_t... CEAs > // Compile time element arguments
2234 class Elements< SVecDVecCrossExpr<VT1,VT2,TF>, TF, true, CEAs... >
2235  : public View< DenseVector< Elements< SVecDVecCrossExpr<VT1,VT2,TF>, TF, true, CEAs... >, TF > >
2236  , private ElementsData<CEAs...>
2237 {
2238  private:
2239  //**Type definitions****************************************************************************
2240  using CPE = SVecDVecCrossExpr<VT1,VT2,TF>;
2241  using RT = ResultType_<CPE>;
2242  using DataType = ElementsData<CEAs...>;
2243  //**********************************************************************************************
2244 
2245  public:
2246  //**Type definitions****************************************************************************
2248  using This = Elements<CPE,TF,true,CEAs...>;
2249 
2250  using BaseType = DenseVector<This,TF>;
2251  using ViewedType = CPE;
2252  using ResultType = ElementsTrait_<RT,CEAs...>;
2253  using TransposeType = TransposeType_<ResultType>;
2254  using ElementType = ElementType_<CPE>;
2255  using ReturnType = ReturnType_<CPE>;
2256  using CompositeType = const ResultType;
2257  //**********************************************************************************************
2258 
2259  //**Compilation flags***************************************************************************
2261  enum : bool { simdEnabled = false };
2262 
2264  enum : bool { smpAssignable = false };
2265  //**********************************************************************************************
2266 
2267  //**Constructor*********************************************************************************
2274  template< typename... REAs > // Optional element arguments
2275  explicit inline Elements( const CPE& vector, REAs... args )
2276  : DataType( args... ) // Base class initialization
2277  , vector_ ( vector ) // The sparse vector/dense vector cross product expression
2278  {
2279  if( !Contains< TypeList<REAs...>, Unchecked >::value ) {
2280  for( size_t i=0UL; i<size(); ++i ) {
2281  if( vector_.size() <= idx(i) ) {
2282  BLAZE_THROW_INVALID_ARGUMENT( "Invalid element access index" );
2283  }
2284  }
2285  }
2286  }
2287  //**********************************************************************************************
2288 
2289  //**Subscript operator**************************************************************************
2295  inline ReturnType operator[]( size_t index ) const {
2296  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
2297  return vector_[idx(index)];
2298  }
2299  //**********************************************************************************************
2300 
2301  //**At function*********************************************************************************
2308  inline ReturnType at( size_t index ) const {
2309  if( index >= size() ) {
2310  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
2311  }
2312  return (*this)[index];
2313  }
2314  //**********************************************************************************************
2315 
2316  //**********************************************************************************************
2317  using DataType::idces;
2318  using DataType::idx;
2319  using DataType::size;
2320  //**********************************************************************************************
2321 
2322  //**Operand access******************************************************************************
2327  inline CPE operand() const noexcept {
2328  return vector_;
2329  }
2330  //**********************************************************************************************
2331 
2332  //**********************************************************************************************
2338  template< typename T >
2339  inline bool canAlias( const T* alias ) const noexcept {
2340  return vector_.canAlias( alias );
2341  }
2342  //**********************************************************************************************
2343 
2344  //**********************************************************************************************
2350  template< typename T >
2351  inline bool isAliased( const T* alias ) const noexcept {
2352  return vector_.isAliased( alias );
2353  }
2354  //**********************************************************************************************
2355 
2356  private:
2357  //**Member variables****************************************************************************
2358  CPE vector_;
2359  //**********************************************************************************************
2360 };
2362 //*************************************************************************************************
2363 
2364 
2365 
2366 
2367 
2368 
2369 
2370 
2371 //=================================================================================================
2372 //
2373 // CLASS TEMPLATE SPECIALIZATION FOR SVECSVECCROSSEXPR
2374 //
2375 //=================================================================================================
2376 
2377 //*************************************************************************************************
2385 template< typename VT1 // Type of the left-hand side sparse vector
2386  , typename VT2 // Type of the right-hand side sparse vector
2387  , bool TF // Transpose flag
2388  , size_t... CEAs > // Compile time element arguments
2389 class Elements< SVecSVecCrossExpr<VT1,VT2,TF>, TF, true, CEAs... >
2390  : public View< DenseVector< Elements< SVecSVecCrossExpr<VT1,VT2,TF>, TF, true, CEAs... >, TF > >
2391  , private ElementsData<CEAs...>
2392 {
2393  private:
2394  //**Type definitions****************************************************************************
2395  using CPE = SVecSVecCrossExpr<VT1,VT2,TF>;
2396  using RT = ResultType_<CPE>;
2397  using DataType = ElementsData<CEAs...>;
2398  //**********************************************************************************************
2399 
2400  public:
2401  //**Type definitions****************************************************************************
2403  using This = Elements<CPE,TF,true,CEAs...>;
2404 
2405  using BaseType = DenseVector<This,TF>;
2406  using ViewedType = CPE;
2407  using ResultType = ElementsTrait_<RT,CEAs...>;
2408  using TransposeType = TransposeType_<ResultType>;
2409  using ElementType = ElementType_<CPE>;
2410  using ReturnType = ReturnType_<CPE>;
2411  using CompositeType = const ResultType;
2412  //**********************************************************************************************
2413 
2414  //**Compilation flags***************************************************************************
2416  enum : bool { simdEnabled = false };
2417 
2419  enum : bool { smpAssignable = false };
2420  //**********************************************************************************************
2421 
2422  //**Constructor*********************************************************************************
2429  template< typename... REAs > // Optional element arguments
2430  explicit inline Elements( const CPE& vector, REAs... args )
2431  : DataType( args... ) // Base class initialization
2432  , vector_ ( vector ) // The sparse vector/sparse vector cross product expression
2433  {
2434  if( !Contains< TypeList<REAs...>, Unchecked >::value ) {
2435  for( size_t i=0UL; i<size(); ++i ) {
2436  if( vector_.size() <= idx(i) ) {
2437  BLAZE_THROW_INVALID_ARGUMENT( "Invalid element access index" );
2438  }
2439  }
2440  }
2441  }
2442  //**********************************************************************************************
2443 
2444  //**Subscript operator**************************************************************************
2450  inline ReturnType operator[]( size_t index ) const {
2451  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
2452  return vector_[idx(index)];
2453  }
2454  //**********************************************************************************************
2455 
2456  //**At function*********************************************************************************
2463  inline ReturnType at( size_t index ) const {
2464  if( index >= size() ) {
2465  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
2466  }
2467  return (*this)[index];
2468  }
2469  //**********************************************************************************************
2470 
2471  //**********************************************************************************************
2472  using DataType::idces;
2473  using DataType::idx;
2474  using DataType::size;
2475  //**********************************************************************************************
2476 
2477  //**Operand access******************************************************************************
2482  inline CPE operand() const noexcept {
2483  return vector_;
2484  }
2485  //**********************************************************************************************
2486 
2487  //**********************************************************************************************
2493  template< typename T >
2494  inline bool canAlias( const T* alias ) const noexcept {
2495  return vector_.canAlias( alias );
2496  }
2497  //**********************************************************************************************
2498 
2499  //**********************************************************************************************
2505  template< typename T >
2506  inline bool isAliased( const T* alias ) const noexcept {
2507  return vector_.isAliased( alias );
2508  }
2509  //**********************************************************************************************
2510 
2511  private:
2512  //**Member variables****************************************************************************
2513  CPE vector_;
2514  //**********************************************************************************************
2515 };
2517 //*************************************************************************************************
2518 
2519 } // namespace blaze
2520 
2521 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
Header file for the blaze::checked and blaze::unchecked instances.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:522
Header file for the View base class.
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:329
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3076
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:364
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3074
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:701
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3078
Header file for the DenseVector base class.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3083
Constraint on the data type.
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:560
Header file for the decltype(auto) workaround.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:733
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3084
typename ElementsTrait< VT, CEAs... >::Type ElementsTrait_
Auxiliary alias declaration for the ElementsTrait type trait.The ElementsTrait_ alias declaration pro...
Definition: ElementsTrait.h:144
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
Header file for the extended initializer_list functionality.
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
Header file for the elements trait.
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:474
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:408
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:252
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3082
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
Header file for the implementation of a vector representation of an initializer list.
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3079
#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
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:367
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:443
Header file for the Not class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ELEMENTS_TYPE(T)
Constraint on the data type.In case the given data type T is an element selection (i...
Definition: Elements.h:81
Constraint on the data type.
Header file for the implementation of the Elements base template.
Constraint on the data type.
decltype(auto) elements(Vector< VT, TF > &vector, REAs... args)
Creating a view on a selection of elements of the given vector.
Definition: Elements.h:134
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:430
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for all forward declarations for expression class templates.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:608
Header file for the IsSparseVector type trait.
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the cross product trait.
Header file for the Unique class template.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance...
Definition: Check.h:96
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
Header file for the reset shim.
Header file for the isDefault shim.
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:405
Header file for the HasMutableDataAccess type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
BLAZE_ALWAYS_INLINE MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:169
EnableIf_< IsNumeric< ST >, MT &> operator/=(DenseMatrix< MT, SO > &mat, ST scalar)
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:655
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3081
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
Header file for the implementation of the ElementsData class template.
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
EnableIf_< IsNumeric< ST >, MT &> operator*=(DenseMatrix< MT, SO > &mat, ST scalar)
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:593
Header file for the IsRestricted type trait.
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the IsExpression type trait class.