| 124 | */ |
| 125 | template<typename _Left, typename _Right, internal::ProductArgOp _OpLeft, internal::ProductArgOp _OpRight, internal::ProductArgOp _OpOutput> |
| 126 | class ProductOp : public MatrixBase<ProductOp<_Left, _Right, _OpLeft, _OpRight, _OpOutput> > |
| 127 | { |
| 128 | public: |
| 129 | using Type = ProductOp<_Left, _Right, _OpLeft, _OpRight, _OpOutput>; |
| 130 | using Base = MatrixBase<Type>; |
| 131 | CUMAT_PUBLIC_API |
| 132 | |
| 133 | enum |
| 134 | { |
| 135 | LeftOp = int(_OpLeft), |
| 136 | RightOp = int(_OpRight), |
| 137 | OutputOp = int(_OpOutput), |
| 138 | |
| 139 | TransposedLeft = int(_OpLeft)&int(internal::ProductArgOp::TRANSPOSED) ? true : false, |
| 140 | TransposedRight = int(_OpRight)&int(internal::ProductArgOp::TRANSPOSED) ? true : false, |
| 141 | TransposedOutput = int(_OpOutput)&int(internal::ProductArgOp::TRANSPOSED) ? true : false, |
| 142 | ConjugateLeft = int(_OpLeft)&int(internal::ProductArgOp::CONJUGATED) ? true : false, |
| 143 | ConjugateRight = int(_OpRight)&int(internal::ProductArgOp::CONJUGATED) ? true : false, |
| 144 | ConjugateOutput = int(_OpOutput)&int(internal::ProductArgOp::CONJUGATED) ? true : false, |
| 145 | |
| 146 | FlagsLeft = internal::traits<_Left>::Flags, |
| 147 | RowsLeft = internal::traits<_Left>::RowsAtCompileTime, |
| 148 | ColumnsLeft = internal::traits<_Left>::ColsAtCompileTime, |
| 149 | BatchesLeft = internal::traits<_Left>::BatchesAtCompileTime, |
| 150 | |
| 151 | FlagsRight = internal::traits<_Right>::Flags, |
| 152 | RowsRight = internal::traits<_Right>::RowsAtCompileTime, |
| 153 | ColumnsRight = internal::traits<_Right>::ColsAtCompileTime, |
| 154 | BatchesRight = internal::traits<_Right>::BatchesAtCompileTime, |
| 155 | |
| 156 | RowsNonT = TransposedLeft ? ColumnsLeft : RowsLeft, |
| 157 | ColumnsNonT = TransposedRight ? RowsRight : ColumnsRight, |
| 158 | |
| 159 | IsOuterProduct = internal::traits<Type>::IsOuterProduct |
| 160 | }; |
| 161 | using Base::size; |
| 162 | |
| 163 | //if the ProductOp represents an outer product, the left and right arguments |
| 164 | //must support ReadCwise, so that coeff() is valid. |
| 165 | typedef typename MatrixReadWrapper<_Left, AccessFlags::ReadCwise>::type left_wrapped_t; |
| 166 | typedef typename MatrixReadWrapper<_Right, AccessFlags::ReadCwise>::type right_wrapped_t; |
| 167 | using LeftType = typename std::conditional<IsOuterProduct, left_wrapped_t, typename _Left::Type>::type; |
| 168 | using RightType = typename std::conditional<IsOuterProduct, right_wrapped_t, typename _Right::Type>::type; |
| 169 | |
| 170 | private: |
| 171 | LeftType left_; |
| 172 | RightType right_; |
| 173 | |
| 174 | public: |
| 175 | ProductOp(const MatrixBase<_Left>& left, const MatrixBase<_Right>& right) |
| 176 | : left_(left.derived()), right_(right.derived()) |
| 177 | { |
| 178 | CUMAT_STATIC_ASSERT((std::is_same< |
| 179 | typename internal::NumTraits<typename internal::traits<_Left>::Scalar>::ElementalType, |
| 180 | typename internal::NumTraits<typename internal::traits<_Right>::Scalar>::ElementalType>::value), |
| 181 | "No implicit casting is allowed in binary operations."); |
| 182 | |
| 183 | if (ColumnsLeft == Dynamic || RowsRight == Dynamic) |
nothing calls this directly
no test coverage detected