File indexing completed on 2025-09-18 09:03:39
0001 #ifndef BOOST_QVM_GEN_MAT_OPERATIONS4_HPP_INCLUDED
0002 #define BOOST_QVM_GEN_MAT_OPERATIONS4_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/qvm/assert.hpp>
0010 #include <boost/qvm/deduce_mat.hpp>
0011 #include <boost/qvm/deduce_vec.hpp>
0012 #include <boost/qvm/error.hpp>
0013 #include <boost/qvm/gen/mat_assign4.hpp>
0014 #include <boost/qvm/quat_traits.hpp>
0015 #include <boost/qvm/scalar_traits.hpp>
0016 #include <boost/qvm/throw_exception.hpp>
0017
0018 namespace boost { namespace qvm {
0019
0020 template <class A,class B>
0021 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0022 typename lazy_enable_if_c<
0023 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
0024 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
0025 deduce_mat2<A,B,4,4> >::type
0026 operator+( A const & a, B const & b )
0027 {
0028 typedef typename deduce_mat2<A,B,4,4>::type R;
0029 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
0030 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
0031 R r;
0032 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0033 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0034 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0035 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a)+mat_traits<B>::template read_element<0,3>(b));
0036 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0037 write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)+mat_traits<B>::template read_element<1,1>(b));
0038 write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)+mat_traits<B>::template read_element<1,2>(b));
0039 write_mat_element<1,3>(r,mat_traits<A>::template read_element<1,3>(a)+mat_traits<B>::template read_element<1,3>(b));
0040 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0041 write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)+mat_traits<B>::template read_element<2,1>(b));
0042 write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)+mat_traits<B>::template read_element<2,2>(b));
0043 write_mat_element<2,3>(r,mat_traits<A>::template read_element<2,3>(a)+mat_traits<B>::template read_element<2,3>(b));
0044 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a)+mat_traits<B>::template read_element<3,0>(b));
0045 write_mat_element<3,1>(r,mat_traits<A>::template read_element<3,1>(a)+mat_traits<B>::template read_element<3,1>(b));
0046 write_mat_element<3,2>(r,mat_traits<A>::template read_element<3,2>(a)+mat_traits<B>::template read_element<3,2>(b));
0047 write_mat_element<3,3>(r,mat_traits<A>::template read_element<3,3>(a)+mat_traits<B>::template read_element<3,3>(b));
0048 return r;
0049 }
0050
0051 namespace
0052 sfinae
0053 {
0054 using ::boost::qvm::operator+;
0055 }
0056
0057 namespace
0058 qvm_detail
0059 {
0060 template <int R,int C>
0061 struct plus_mm_defined;
0062
0063 template <>
0064 struct
0065 plus_mm_defined<4,4>
0066 {
0067 static bool const value=true;
0068 };
0069 }
0070
0071 template <class A,class B>
0072 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0073 typename lazy_enable_if_c<
0074 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
0075 mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0076 deduce_mat2<A,B,4,1> >::type
0077 operator+( A const & a, B const & b )
0078 {
0079 typedef typename deduce_mat2<A,B,4,1>::type R;
0080 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
0081 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
0082 R r;
0083 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0084 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0085 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0086 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a)+mat_traits<B>::template read_element<3,0>(b));
0087 return r;
0088 }
0089
0090 namespace
0091 sfinae
0092 {
0093 using ::boost::qvm::operator+;
0094 }
0095
0096 namespace
0097 qvm_detail
0098 {
0099 template <int R,int C>
0100 struct plus_mm_defined;
0101
0102 template <>
0103 struct
0104 plus_mm_defined<4,1>
0105 {
0106 static bool const value=true;
0107 };
0108 }
0109
0110 template <class A,class B>
0111 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0112 typename lazy_enable_if_c<
0113 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0114 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
0115 deduce_mat2<A,B,1,4> >::type
0116 operator+( A const & a, B const & b )
0117 {
0118 typedef typename deduce_mat2<A,B,1,4>::type R;
0119 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
0120 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
0121 R r;
0122 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0123 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0124 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0125 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a)+mat_traits<B>::template read_element<0,3>(b));
0126 return r;
0127 }
0128
0129 namespace
0130 sfinae
0131 {
0132 using ::boost::qvm::operator+;
0133 }
0134
0135 namespace
0136 qvm_detail
0137 {
0138 template <int R,int C>
0139 struct plus_mm_defined;
0140
0141 template <>
0142 struct
0143 plus_mm_defined<1,4>
0144 {
0145 static bool const value=true;
0146 };
0147 }
0148
0149 template <class A,class B>
0150 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0151 typename lazy_enable_if_c<
0152 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
0153 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
0154 deduce_mat2<A,B,4,4> >::type
0155 operator-( A const & a, B const & b )
0156 {
0157 typedef typename deduce_mat2<A,B,4,4>::type R;
0158 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
0159 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
0160 R r;
0161 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0162 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0163 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0164 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a)-mat_traits<B>::template read_element<0,3>(b));
0165 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0166 write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)-mat_traits<B>::template read_element<1,1>(b));
0167 write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)-mat_traits<B>::template read_element<1,2>(b));
0168 write_mat_element<1,3>(r,mat_traits<A>::template read_element<1,3>(a)-mat_traits<B>::template read_element<1,3>(b));
0169 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0170 write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)-mat_traits<B>::template read_element<2,1>(b));
0171 write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)-mat_traits<B>::template read_element<2,2>(b));
0172 write_mat_element<2,3>(r,mat_traits<A>::template read_element<2,3>(a)-mat_traits<B>::template read_element<2,3>(b));
0173 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a)-mat_traits<B>::template read_element<3,0>(b));
0174 write_mat_element<3,1>(r,mat_traits<A>::template read_element<3,1>(a)-mat_traits<B>::template read_element<3,1>(b));
0175 write_mat_element<3,2>(r,mat_traits<A>::template read_element<3,2>(a)-mat_traits<B>::template read_element<3,2>(b));
0176 write_mat_element<3,3>(r,mat_traits<A>::template read_element<3,3>(a)-mat_traits<B>::template read_element<3,3>(b));
0177 return r;
0178 }
0179
0180 namespace
0181 sfinae
0182 {
0183 using ::boost::qvm::operator-;
0184 }
0185
0186 namespace
0187 qvm_detail
0188 {
0189 template <int R,int C>
0190 struct minus_mm_defined;
0191
0192 template <>
0193 struct
0194 minus_mm_defined<4,4>
0195 {
0196 static bool const value=true;
0197 };
0198 }
0199
0200 template <class A,class B>
0201 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0202 typename lazy_enable_if_c<
0203 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
0204 mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0205 deduce_mat2<A,B,4,1> >::type
0206 operator-( A const & a, B const & b )
0207 {
0208 typedef typename deduce_mat2<A,B,4,1>::type R;
0209 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
0210 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
0211 R r;
0212 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0213 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0214 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0215 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a)-mat_traits<B>::template read_element<3,0>(b));
0216 return r;
0217 }
0218
0219 namespace
0220 sfinae
0221 {
0222 using ::boost::qvm::operator-;
0223 }
0224
0225 namespace
0226 qvm_detail
0227 {
0228 template <int R,int C>
0229 struct minus_mm_defined;
0230
0231 template <>
0232 struct
0233 minus_mm_defined<4,1>
0234 {
0235 static bool const value=true;
0236 };
0237 }
0238
0239 template <class A,class B>
0240 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0241 typename lazy_enable_if_c<
0242 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0243 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
0244 deduce_mat2<A,B,1,4> >::type
0245 operator-( A const & a, B const & b )
0246 {
0247 typedef typename deduce_mat2<A,B,1,4>::type R;
0248 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
0249 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
0250 R r;
0251 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0252 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0253 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0254 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a)-mat_traits<B>::template read_element<0,3>(b));
0255 return r;
0256 }
0257
0258 namespace
0259 sfinae
0260 {
0261 using ::boost::qvm::operator-;
0262 }
0263
0264 namespace
0265 qvm_detail
0266 {
0267 template <int R,int C>
0268 struct minus_mm_defined;
0269
0270 template <>
0271 struct
0272 minus_mm_defined<1,4>
0273 {
0274 static bool const value=true;
0275 };
0276 }
0277
0278 template <class A,class B>
0279 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0280 typename enable_if_c<
0281 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
0282 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
0283 A &>::type
0284 operator+=( A & a, B const & b )
0285 {
0286 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0287 write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0288 write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0289 write_mat_element<0,3>(a,mat_traits<A>::template read_element<0,3>(a)+mat_traits<B>::template read_element<0,3>(b));
0290 write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0291 write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)+mat_traits<B>::template read_element<1,1>(b));
0292 write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)+mat_traits<B>::template read_element<1,2>(b));
0293 write_mat_element<1,3>(a,mat_traits<A>::template read_element<1,3>(a)+mat_traits<B>::template read_element<1,3>(b));
0294 write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0295 write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)+mat_traits<B>::template read_element<2,1>(b));
0296 write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)+mat_traits<B>::template read_element<2,2>(b));
0297 write_mat_element<2,3>(a,mat_traits<A>::template read_element<2,3>(a)+mat_traits<B>::template read_element<2,3>(b));
0298 write_mat_element<3,0>(a,mat_traits<A>::template read_element<3,0>(a)+mat_traits<B>::template read_element<3,0>(b));
0299 write_mat_element<3,1>(a,mat_traits<A>::template read_element<3,1>(a)+mat_traits<B>::template read_element<3,1>(b));
0300 write_mat_element<3,2>(a,mat_traits<A>::template read_element<3,2>(a)+mat_traits<B>::template read_element<3,2>(b));
0301 write_mat_element<3,3>(a,mat_traits<A>::template read_element<3,3>(a)+mat_traits<B>::template read_element<3,3>(b));
0302 return a;
0303 }
0304
0305 namespace
0306 sfinae
0307 {
0308 using ::boost::qvm::operator+=;
0309 }
0310
0311 namespace
0312 qvm_detail
0313 {
0314 template <int R,int C>
0315 struct plus_eq_mm_defined;
0316
0317 template <>
0318 struct
0319 plus_eq_mm_defined<4,4>
0320 {
0321 static bool const value=true;
0322 };
0323 }
0324
0325 template <class A,class B>
0326 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0327 typename enable_if_c<
0328 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
0329 mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0330 A &>::type
0331 operator+=( A & a, B const & b )
0332 {
0333 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0334 write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0335 write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0336 write_mat_element<3,0>(a,mat_traits<A>::template read_element<3,0>(a)+mat_traits<B>::template read_element<3,0>(b));
0337 return a;
0338 }
0339
0340 namespace
0341 sfinae
0342 {
0343 using ::boost::qvm::operator+=;
0344 }
0345
0346 namespace
0347 qvm_detail
0348 {
0349 template <int R,int C>
0350 struct plus_eq_mm_defined;
0351
0352 template <>
0353 struct
0354 plus_eq_mm_defined<4,1>
0355 {
0356 static bool const value=true;
0357 };
0358 }
0359
0360 template <class A,class B>
0361 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0362 typename enable_if_c<
0363 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0364 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
0365 A &>::type
0366 operator+=( A & a, B const & b )
0367 {
0368 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0369 write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0370 write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0371 write_mat_element<0,3>(a,mat_traits<A>::template read_element<0,3>(a)+mat_traits<B>::template read_element<0,3>(b));
0372 return a;
0373 }
0374
0375 namespace
0376 sfinae
0377 {
0378 using ::boost::qvm::operator+=;
0379 }
0380
0381 namespace
0382 qvm_detail
0383 {
0384 template <int R,int C>
0385 struct plus_eq_mm_defined;
0386
0387 template <>
0388 struct
0389 plus_eq_mm_defined<1,4>
0390 {
0391 static bool const value=true;
0392 };
0393 }
0394
0395 template <class A,class B>
0396 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0397 typename enable_if_c<
0398 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
0399 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
0400 A &>::type
0401 operator-=( A & a, B const & b )
0402 {
0403 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0404 write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0405 write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0406 write_mat_element<0,3>(a,mat_traits<A>::template read_element<0,3>(a)-mat_traits<B>::template read_element<0,3>(b));
0407 write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0408 write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)-mat_traits<B>::template read_element<1,1>(b));
0409 write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)-mat_traits<B>::template read_element<1,2>(b));
0410 write_mat_element<1,3>(a,mat_traits<A>::template read_element<1,3>(a)-mat_traits<B>::template read_element<1,3>(b));
0411 write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0412 write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)-mat_traits<B>::template read_element<2,1>(b));
0413 write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)-mat_traits<B>::template read_element<2,2>(b));
0414 write_mat_element<2,3>(a,mat_traits<A>::template read_element<2,3>(a)-mat_traits<B>::template read_element<2,3>(b));
0415 write_mat_element<3,0>(a,mat_traits<A>::template read_element<3,0>(a)-mat_traits<B>::template read_element<3,0>(b));
0416 write_mat_element<3,1>(a,mat_traits<A>::template read_element<3,1>(a)-mat_traits<B>::template read_element<3,1>(b));
0417 write_mat_element<3,2>(a,mat_traits<A>::template read_element<3,2>(a)-mat_traits<B>::template read_element<3,2>(b));
0418 write_mat_element<3,3>(a,mat_traits<A>::template read_element<3,3>(a)-mat_traits<B>::template read_element<3,3>(b));
0419 return a;
0420 }
0421
0422 namespace
0423 sfinae
0424 {
0425 using ::boost::qvm::operator-=;
0426 }
0427
0428 namespace
0429 qvm_detail
0430 {
0431 template <int R,int C>
0432 struct minus_eq_mm_defined;
0433
0434 template <>
0435 struct
0436 minus_eq_mm_defined<4,4>
0437 {
0438 static bool const value=true;
0439 };
0440 }
0441
0442 template <class A,class B>
0443 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0444 typename enable_if_c<
0445 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
0446 mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0447 A &>::type
0448 operator-=( A & a, B const & b )
0449 {
0450 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0451 write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0452 write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0453 write_mat_element<3,0>(a,mat_traits<A>::template read_element<3,0>(a)-mat_traits<B>::template read_element<3,0>(b));
0454 return a;
0455 }
0456
0457 namespace
0458 sfinae
0459 {
0460 using ::boost::qvm::operator-=;
0461 }
0462
0463 namespace
0464 qvm_detail
0465 {
0466 template <int R,int C>
0467 struct minus_eq_mm_defined;
0468
0469 template <>
0470 struct
0471 minus_eq_mm_defined<4,1>
0472 {
0473 static bool const value=true;
0474 };
0475 }
0476
0477 template <class A,class B>
0478 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0479 typename enable_if_c<
0480 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0481 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
0482 A &>::type
0483 operator-=( A & a, B const & b )
0484 {
0485 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0486 write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0487 write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0488 write_mat_element<0,3>(a,mat_traits<A>::template read_element<0,3>(a)-mat_traits<B>::template read_element<0,3>(b));
0489 return a;
0490 }
0491
0492 namespace
0493 sfinae
0494 {
0495 using ::boost::qvm::operator-=;
0496 }
0497
0498 namespace
0499 qvm_detail
0500 {
0501 template <int R,int C>
0502 struct minus_eq_mm_defined;
0503
0504 template <>
0505 struct
0506 minus_eq_mm_defined<1,4>
0507 {
0508 static bool const value=true;
0509 };
0510 }
0511
0512 template <class A,class B>
0513 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0514 typename lazy_enable_if_c<
0515 mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
0516 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0517 operator*( A const & a, B b )
0518 {
0519 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0520 R r;
0521 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)*b);
0522 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)*b);
0523 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)*b);
0524 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a)*b);
0525 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)*b);
0526 write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)*b);
0527 write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)*b);
0528 write_mat_element<1,3>(r,mat_traits<A>::template read_element<1,3>(a)*b);
0529 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)*b);
0530 write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)*b);
0531 write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)*b);
0532 write_mat_element<2,3>(r,mat_traits<A>::template read_element<2,3>(a)*b);
0533 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a)*b);
0534 write_mat_element<3,1>(r,mat_traits<A>::template read_element<3,1>(a)*b);
0535 write_mat_element<3,2>(r,mat_traits<A>::template read_element<3,2>(a)*b);
0536 write_mat_element<3,3>(r,mat_traits<A>::template read_element<3,3>(a)*b);
0537 return r;
0538 }
0539
0540 namespace
0541 sfinae
0542 {
0543 using ::boost::qvm::operator*;
0544 }
0545
0546 namespace
0547 qvm_detail
0548 {
0549 template <int R,int C>
0550 struct mul_ms_defined;
0551
0552 template <>
0553 struct
0554 mul_ms_defined<4,4>
0555 {
0556 static bool const value=true;
0557 };
0558 }
0559
0560 template <class A,class B>
0561 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0562 typename lazy_enable_if_c<
0563 is_scalar<A>::value && mat_traits<B>::rows==4 && mat_traits<B>::cols==4,
0564 deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0565 operator*( A a, B const & b )
0566 {
0567 typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0568 R r;
0569 write_mat_element<0,0>(r,a*mat_traits<B>::template read_element<0,0>(b));
0570 write_mat_element<0,1>(r,a*mat_traits<B>::template read_element<0,1>(b));
0571 write_mat_element<0,2>(r,a*mat_traits<B>::template read_element<0,2>(b));
0572 write_mat_element<0,3>(r,a*mat_traits<B>::template read_element<0,3>(b));
0573 write_mat_element<1,0>(r,a*mat_traits<B>::template read_element<1,0>(b));
0574 write_mat_element<1,1>(r,a*mat_traits<B>::template read_element<1,1>(b));
0575 write_mat_element<1,2>(r,a*mat_traits<B>::template read_element<1,2>(b));
0576 write_mat_element<1,3>(r,a*mat_traits<B>::template read_element<1,3>(b));
0577 write_mat_element<2,0>(r,a*mat_traits<B>::template read_element<2,0>(b));
0578 write_mat_element<2,1>(r,a*mat_traits<B>::template read_element<2,1>(b));
0579 write_mat_element<2,2>(r,a*mat_traits<B>::template read_element<2,2>(b));
0580 write_mat_element<2,3>(r,a*mat_traits<B>::template read_element<2,3>(b));
0581 write_mat_element<3,0>(r,a*mat_traits<B>::template read_element<3,0>(b));
0582 write_mat_element<3,1>(r,a*mat_traits<B>::template read_element<3,1>(b));
0583 write_mat_element<3,2>(r,a*mat_traits<B>::template read_element<3,2>(b));
0584 write_mat_element<3,3>(r,a*mat_traits<B>::template read_element<3,3>(b));
0585 return r;
0586 }
0587
0588 namespace
0589 sfinae
0590 {
0591 using ::boost::qvm::operator*;
0592 }
0593
0594 namespace
0595 qvm_detail
0596 {
0597 template <int R,int C>
0598 struct mul_sm_defined;
0599
0600 template <>
0601 struct
0602 mul_sm_defined<4,4>
0603 {
0604 static bool const value=true;
0605 };
0606 }
0607
0608 template <class A,class B>
0609 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0610 typename lazy_enable_if_c<
0611 mat_traits<A>::rows==4 && mat_traits<A>::cols==1 && is_scalar<B>::value,
0612 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0613 operator*( A const & a, B b )
0614 {
0615 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0616 R r;
0617 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)*b);
0618 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)*b);
0619 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)*b);
0620 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a)*b);
0621 return r;
0622 }
0623
0624 namespace
0625 sfinae
0626 {
0627 using ::boost::qvm::operator*;
0628 }
0629
0630 namespace
0631 qvm_detail
0632 {
0633 template <int R,int C>
0634 struct mul_ms_defined;
0635
0636 template <>
0637 struct
0638 mul_ms_defined<4,1>
0639 {
0640 static bool const value=true;
0641 };
0642 }
0643
0644 template <class A,class B>
0645 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0646 typename lazy_enable_if_c<
0647 is_scalar<A>::value && mat_traits<B>::rows==4 && mat_traits<B>::cols==1,
0648 deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0649 operator*( A a, B const & b )
0650 {
0651 typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0652 R r;
0653 write_mat_element<0,0>(r,a*mat_traits<B>::template read_element<0,0>(b));
0654 write_mat_element<1,0>(r,a*mat_traits<B>::template read_element<1,0>(b));
0655 write_mat_element<2,0>(r,a*mat_traits<B>::template read_element<2,0>(b));
0656 write_mat_element<3,0>(r,a*mat_traits<B>::template read_element<3,0>(b));
0657 return r;
0658 }
0659
0660 namespace
0661 sfinae
0662 {
0663 using ::boost::qvm::operator*;
0664 }
0665
0666 namespace
0667 qvm_detail
0668 {
0669 template <int R,int C>
0670 struct mul_sm_defined;
0671
0672 template <>
0673 struct
0674 mul_sm_defined<4,1>
0675 {
0676 static bool const value=true;
0677 };
0678 }
0679
0680 template <class A,class B>
0681 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0682 typename lazy_enable_if_c<
0683 mat_traits<A>::rows==1 && mat_traits<A>::cols==4 && is_scalar<B>::value,
0684 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0685 operator*( A const & a, B b )
0686 {
0687 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0688 R r;
0689 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)*b);
0690 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)*b);
0691 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)*b);
0692 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a)*b);
0693 return r;
0694 }
0695
0696 namespace
0697 sfinae
0698 {
0699 using ::boost::qvm::operator*;
0700 }
0701
0702 namespace
0703 qvm_detail
0704 {
0705 template <int R,int C>
0706 struct mul_ms_defined;
0707
0708 template <>
0709 struct
0710 mul_ms_defined<1,4>
0711 {
0712 static bool const value=true;
0713 };
0714 }
0715
0716 template <class A,class B>
0717 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0718 typename lazy_enable_if_c<
0719 is_scalar<A>::value && mat_traits<B>::rows==1 && mat_traits<B>::cols==4,
0720 deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0721 operator*( A a, B const & b )
0722 {
0723 typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0724 R r;
0725 write_mat_element<0,0>(r,a*mat_traits<B>::template read_element<0,0>(b));
0726 write_mat_element<0,1>(r,a*mat_traits<B>::template read_element<0,1>(b));
0727 write_mat_element<0,2>(r,a*mat_traits<B>::template read_element<0,2>(b));
0728 write_mat_element<0,3>(r,a*mat_traits<B>::template read_element<0,3>(b));
0729 return r;
0730 }
0731
0732 namespace
0733 sfinae
0734 {
0735 using ::boost::qvm::operator*;
0736 }
0737
0738 namespace
0739 qvm_detail
0740 {
0741 template <int R,int C>
0742 struct mul_sm_defined;
0743
0744 template <>
0745 struct
0746 mul_sm_defined<1,4>
0747 {
0748 static bool const value=true;
0749 };
0750 }
0751
0752 template <class A,class B>
0753 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0754 typename enable_if_c<
0755 mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
0756 A &>::type
0757 operator*=( A & a, B b )
0758 {
0759 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)*b);
0760 write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)*b);
0761 write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)*b);
0762 write_mat_element<0,3>(a,mat_traits<A>::template read_element<0,3>(a)*b);
0763 write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)*b);
0764 write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)*b);
0765 write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)*b);
0766 write_mat_element<1,3>(a,mat_traits<A>::template read_element<1,3>(a)*b);
0767 write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)*b);
0768 write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)*b);
0769 write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)*b);
0770 write_mat_element<2,3>(a,mat_traits<A>::template read_element<2,3>(a)*b);
0771 write_mat_element<3,0>(a,mat_traits<A>::template read_element<3,0>(a)*b);
0772 write_mat_element<3,1>(a,mat_traits<A>::template read_element<3,1>(a)*b);
0773 write_mat_element<3,2>(a,mat_traits<A>::template read_element<3,2>(a)*b);
0774 write_mat_element<3,3>(a,mat_traits<A>::template read_element<3,3>(a)*b);
0775 return a;
0776 }
0777
0778 namespace
0779 sfinae
0780 {
0781 using ::boost::qvm::operator*=;
0782 }
0783
0784 namespace
0785 qvm_detail
0786 {
0787 template <int R,int C>
0788 struct mul_eq_ms_defined;
0789
0790 template <>
0791 struct
0792 mul_eq_ms_defined<4,4>
0793 {
0794 static bool const value=true;
0795 };
0796 }
0797
0798 template <class A,class B>
0799 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0800 typename enable_if_c<
0801 mat_traits<A>::rows==4 && mat_traits<A>::cols==1 && is_scalar<B>::value,
0802 A &>::type
0803 operator*=( A & a, B b )
0804 {
0805 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)*b);
0806 write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)*b);
0807 write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)*b);
0808 write_mat_element<3,0>(a,mat_traits<A>::template read_element<3,0>(a)*b);
0809 return a;
0810 }
0811
0812 namespace
0813 sfinae
0814 {
0815 using ::boost::qvm::operator*=;
0816 }
0817
0818 namespace
0819 qvm_detail
0820 {
0821 template <int R,int C>
0822 struct mul_eq_ms_defined;
0823
0824 template <>
0825 struct
0826 mul_eq_ms_defined<4,1>
0827 {
0828 static bool const value=true;
0829 };
0830 }
0831
0832 template <class A,class B>
0833 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0834 typename enable_if_c<
0835 mat_traits<A>::rows==1 && mat_traits<A>::cols==4 && is_scalar<B>::value,
0836 A &>::type
0837 operator*=( A & a, B b )
0838 {
0839 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)*b);
0840 write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)*b);
0841 write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)*b);
0842 write_mat_element<0,3>(a,mat_traits<A>::template read_element<0,3>(a)*b);
0843 return a;
0844 }
0845
0846 namespace
0847 sfinae
0848 {
0849 using ::boost::qvm::operator*=;
0850 }
0851
0852 namespace
0853 qvm_detail
0854 {
0855 template <int R,int C>
0856 struct mul_eq_ms_defined;
0857
0858 template <>
0859 struct
0860 mul_eq_ms_defined<1,4>
0861 {
0862 static bool const value=true;
0863 };
0864 }
0865
0866 template <class A,class B>
0867 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0868 typename lazy_enable_if_c<
0869 mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
0870 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0871 operator/( A const & a, B b )
0872 {
0873 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0874 R r;
0875 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)/b);
0876 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)/b);
0877 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)/b);
0878 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a)/b);
0879 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)/b);
0880 write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)/b);
0881 write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)/b);
0882 write_mat_element<1,3>(r,mat_traits<A>::template read_element<1,3>(a)/b);
0883 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)/b);
0884 write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)/b);
0885 write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)/b);
0886 write_mat_element<2,3>(r,mat_traits<A>::template read_element<2,3>(a)/b);
0887 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a)/b);
0888 write_mat_element<3,1>(r,mat_traits<A>::template read_element<3,1>(a)/b);
0889 write_mat_element<3,2>(r,mat_traits<A>::template read_element<3,2>(a)/b);
0890 write_mat_element<3,3>(r,mat_traits<A>::template read_element<3,3>(a)/b);
0891 return r;
0892 }
0893
0894 namespace
0895 sfinae
0896 {
0897 using ::boost::qvm::operator/;
0898 }
0899
0900 namespace
0901 qvm_detail
0902 {
0903 template <int R,int C>
0904 struct div_ms_defined;
0905
0906 template <>
0907 struct
0908 div_ms_defined<4,4>
0909 {
0910 static bool const value=true;
0911 };
0912 }
0913
0914 template <class A,class B>
0915 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0916 typename lazy_enable_if_c<
0917 is_scalar<A>::value && mat_traits<B>::rows==4 && mat_traits<B>::cols==4,
0918 deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0919 operator/( A a, B const & b )
0920 {
0921 typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0922 R r;
0923 write_mat_element<0,0>(r,a/mat_traits<B>::template read_element<0,0>(b));
0924 write_mat_element<0,1>(r,a/mat_traits<B>::template read_element<0,1>(b));
0925 write_mat_element<0,2>(r,a/mat_traits<B>::template read_element<0,2>(b));
0926 write_mat_element<0,3>(r,a/mat_traits<B>::template read_element<0,3>(b));
0927 write_mat_element<1,0>(r,a/mat_traits<B>::template read_element<1,0>(b));
0928 write_mat_element<1,1>(r,a/mat_traits<B>::template read_element<1,1>(b));
0929 write_mat_element<1,2>(r,a/mat_traits<B>::template read_element<1,2>(b));
0930 write_mat_element<1,3>(r,a/mat_traits<B>::template read_element<1,3>(b));
0931 write_mat_element<2,0>(r,a/mat_traits<B>::template read_element<2,0>(b));
0932 write_mat_element<2,1>(r,a/mat_traits<B>::template read_element<2,1>(b));
0933 write_mat_element<2,2>(r,a/mat_traits<B>::template read_element<2,2>(b));
0934 write_mat_element<2,3>(r,a/mat_traits<B>::template read_element<2,3>(b));
0935 write_mat_element<3,0>(r,a/mat_traits<B>::template read_element<3,0>(b));
0936 write_mat_element<3,1>(r,a/mat_traits<B>::template read_element<3,1>(b));
0937 write_mat_element<3,2>(r,a/mat_traits<B>::template read_element<3,2>(b));
0938 write_mat_element<3,3>(r,a/mat_traits<B>::template read_element<3,3>(b));
0939 return r;
0940 }
0941
0942 namespace
0943 sfinae
0944 {
0945 using ::boost::qvm::operator/;
0946 }
0947
0948 namespace
0949 qvm_detail
0950 {
0951 template <int R,int C>
0952 struct div_sm_defined;
0953
0954 template <>
0955 struct
0956 div_sm_defined<4,4>
0957 {
0958 static bool const value=true;
0959 };
0960 }
0961
0962 template <class A,class B>
0963 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0964 typename lazy_enable_if_c<
0965 mat_traits<A>::rows==4 && mat_traits<A>::cols==1 && is_scalar<B>::value,
0966 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0967 operator/( A const & a, B b )
0968 {
0969 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0970 R r;
0971 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)/b);
0972 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)/b);
0973 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)/b);
0974 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a)/b);
0975 return r;
0976 }
0977
0978 namespace
0979 sfinae
0980 {
0981 using ::boost::qvm::operator/;
0982 }
0983
0984 namespace
0985 qvm_detail
0986 {
0987 template <int R,int C>
0988 struct div_ms_defined;
0989
0990 template <>
0991 struct
0992 div_ms_defined<4,1>
0993 {
0994 static bool const value=true;
0995 };
0996 }
0997
0998 template <class A,class B>
0999 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1000 typename lazy_enable_if_c<
1001 is_scalar<A>::value && mat_traits<B>::rows==4 && mat_traits<B>::cols==1,
1002 deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
1003 operator/( A a, B const & b )
1004 {
1005 typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
1006 R r;
1007 write_mat_element<0,0>(r,a/mat_traits<B>::template read_element<0,0>(b));
1008 write_mat_element<1,0>(r,a/mat_traits<B>::template read_element<1,0>(b));
1009 write_mat_element<2,0>(r,a/mat_traits<B>::template read_element<2,0>(b));
1010 write_mat_element<3,0>(r,a/mat_traits<B>::template read_element<3,0>(b));
1011 return r;
1012 }
1013
1014 namespace
1015 sfinae
1016 {
1017 using ::boost::qvm::operator/;
1018 }
1019
1020 namespace
1021 qvm_detail
1022 {
1023 template <int R,int C>
1024 struct div_sm_defined;
1025
1026 template <>
1027 struct
1028 div_sm_defined<4,1>
1029 {
1030 static bool const value=true;
1031 };
1032 }
1033
1034 template <class A,class B>
1035 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1036 typename lazy_enable_if_c<
1037 mat_traits<A>::rows==1 && mat_traits<A>::cols==4 && is_scalar<B>::value,
1038 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
1039 operator/( A const & a, B b )
1040 {
1041 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
1042 R r;
1043 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)/b);
1044 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)/b);
1045 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)/b);
1046 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a)/b);
1047 return r;
1048 }
1049
1050 namespace
1051 sfinae
1052 {
1053 using ::boost::qvm::operator/;
1054 }
1055
1056 namespace
1057 qvm_detail
1058 {
1059 template <int R,int C>
1060 struct div_ms_defined;
1061
1062 template <>
1063 struct
1064 div_ms_defined<1,4>
1065 {
1066 static bool const value=true;
1067 };
1068 }
1069
1070 template <class A,class B>
1071 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1072 typename enable_if_c<
1073 mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
1074 A &>::type
1075 operator/=( A & a, B b )
1076 {
1077 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)/b);
1078 write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)/b);
1079 write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)/b);
1080 write_mat_element<0,3>(a,mat_traits<A>::template read_element<0,3>(a)/b);
1081 write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)/b);
1082 write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)/b);
1083 write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)/b);
1084 write_mat_element<1,3>(a,mat_traits<A>::template read_element<1,3>(a)/b);
1085 write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)/b);
1086 write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)/b);
1087 write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)/b);
1088 write_mat_element<2,3>(a,mat_traits<A>::template read_element<2,3>(a)/b);
1089 write_mat_element<3,0>(a,mat_traits<A>::template read_element<3,0>(a)/b);
1090 write_mat_element<3,1>(a,mat_traits<A>::template read_element<3,1>(a)/b);
1091 write_mat_element<3,2>(a,mat_traits<A>::template read_element<3,2>(a)/b);
1092 write_mat_element<3,3>(a,mat_traits<A>::template read_element<3,3>(a)/b);
1093 return a;
1094 }
1095
1096 namespace
1097 sfinae
1098 {
1099 using ::boost::qvm::operator/=;
1100 }
1101
1102 namespace
1103 qvm_detail
1104 {
1105 template <int R,int C>
1106 struct div_eq_ms_defined;
1107
1108 template <>
1109 struct
1110 div_eq_ms_defined<4,4>
1111 {
1112 static bool const value=true;
1113 };
1114 }
1115
1116 template <class A,class B>
1117 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1118 typename enable_if_c<
1119 mat_traits<A>::rows==4 && mat_traits<A>::cols==1 && is_scalar<B>::value,
1120 A &>::type
1121 operator/=( A & a, B b )
1122 {
1123 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)/b);
1124 write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)/b);
1125 write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)/b);
1126 write_mat_element<3,0>(a,mat_traits<A>::template read_element<3,0>(a)/b);
1127 return a;
1128 }
1129
1130 namespace
1131 sfinae
1132 {
1133 using ::boost::qvm::operator/=;
1134 }
1135
1136 namespace
1137 qvm_detail
1138 {
1139 template <int R,int C>
1140 struct div_eq_ms_defined;
1141
1142 template <>
1143 struct
1144 div_eq_ms_defined<4,1>
1145 {
1146 static bool const value=true;
1147 };
1148 }
1149
1150 template <class A,class B>
1151 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1152 typename enable_if_c<
1153 mat_traits<A>::rows==1 && mat_traits<A>::cols==4 && is_scalar<B>::value,
1154 A &>::type
1155 operator/=( A & a, B b )
1156 {
1157 write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)/b);
1158 write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)/b);
1159 write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)/b);
1160 write_mat_element<0,3>(a,mat_traits<A>::template read_element<0,3>(a)/b);
1161 return a;
1162 }
1163
1164 namespace
1165 sfinae
1166 {
1167 using ::boost::qvm::operator/=;
1168 }
1169
1170 namespace
1171 qvm_detail
1172 {
1173 template <int R,int C>
1174 struct div_eq_ms_defined;
1175
1176 template <>
1177 struct
1178 div_eq_ms_defined<1,4>
1179 {
1180 static bool const value=true;
1181 };
1182 }
1183
1184 template <class R,class A>
1185 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1186 typename enable_if_c<
1187 mat_traits<R>::rows==4 && mat_traits<A>::rows==4 &&
1188 mat_traits<R>::cols==4 && mat_traits<A>::cols==4,
1189 R>::type
1190 convert_to( A const & a )
1191 {
1192 R r;
1193 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a));
1194 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a));
1195 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a));
1196 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a));
1197 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a));
1198 write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a));
1199 write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a));
1200 write_mat_element<1,3>(r,mat_traits<A>::template read_element<1,3>(a));
1201 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a));
1202 write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a));
1203 write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a));
1204 write_mat_element<2,3>(r,mat_traits<A>::template read_element<2,3>(a));
1205 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a));
1206 write_mat_element<3,1>(r,mat_traits<A>::template read_element<3,1>(a));
1207 write_mat_element<3,2>(r,mat_traits<A>::template read_element<3,2>(a));
1208 write_mat_element<3,3>(r,mat_traits<A>::template read_element<3,3>(a));
1209 return r;
1210 }
1211
1212 template <class R,class A>
1213 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1214 typename enable_if_c<
1215 is_mat<R>::value && is_quat<A>::value &&
1216 mat_traits<R>::rows==4 && mat_traits<R>::cols==4,
1217 R>::type
1218 convert_to( A const & q )
1219 {
1220 typedef typename mat_traits<R>::scalar_type T;
1221 T const a=quat_traits<A>::template read_element<0>(q);
1222 T const b=quat_traits<A>::template read_element<1>(q);
1223 T const c=quat_traits<A>::template read_element<2>(q);
1224 T const d=quat_traits<A>::template read_element<3>(q);
1225 T const bb = b*b;
1226 T const cc = c*c;
1227 T const dd = d*d;
1228 T const bc = b*c;
1229 T const bd = b*d;
1230 T const cd = c*d;
1231 T const ab = a*b;
1232 T const ac = a*c;
1233 T const ad = a*d;
1234 T const zero = scalar_traits<T>::value(0);
1235 T const one = scalar_traits<T>::value(1);
1236 T const two = one+one;
1237 R r;
1238 write_mat_element<0,0>(r,one - two*(cc+dd));
1239 write_mat_element<0,1>(r,two*(bc-ad));
1240 write_mat_element<0,2>(r,two*(bd+ac));
1241 write_mat_element<0,3>(r,zero);
1242 write_mat_element<1,0>(r,two*(bc+ad));
1243 write_mat_element<1,1>(r,one - two*(bb+dd));
1244 write_mat_element<1,2>(r,two*(cd-ab));
1245 write_mat_element<1,3>(r,zero);
1246 write_mat_element<2,0>(r,two*(bd-ac));
1247 write_mat_element<2,1>(r,two*(cd+ab));
1248 write_mat_element<2,2>(r,one - two*(bb+cc));
1249 write_mat_element<2,3>(r,zero);
1250 write_mat_element<3,0>(r,zero);
1251 write_mat_element<3,1>(r,zero);
1252 write_mat_element<3,2>(r,zero);
1253 write_mat_element<3,3>(r,one);
1254 return r;
1255 }
1256
1257 namespace
1258 sfinae
1259 {
1260 using ::boost::qvm::convert_to;
1261 }
1262
1263 namespace
1264 qvm_detail
1265 {
1266 template <int R,int C>
1267 struct convert_to_m_defined;
1268
1269 template <>
1270 struct
1271 convert_to_m_defined<4,4>
1272 {
1273 static bool const value=true;
1274 };
1275 }
1276
1277 template <class R,class A>
1278 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1279 typename enable_if_c<
1280 mat_traits<R>::rows==4 && mat_traits<A>::rows==4 &&
1281 mat_traits<R>::cols==1 && mat_traits<A>::cols==1,
1282 R>::type
1283 convert_to( A const & a )
1284 {
1285 R r;
1286 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a));
1287 write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a));
1288 write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a));
1289 write_mat_element<3,0>(r,mat_traits<A>::template read_element<3,0>(a));
1290 return r;
1291 }
1292
1293 namespace
1294 sfinae
1295 {
1296 using ::boost::qvm::convert_to;
1297 }
1298
1299 namespace
1300 qvm_detail
1301 {
1302 template <int R,int C>
1303 struct convert_to_m_defined;
1304
1305 template <>
1306 struct
1307 convert_to_m_defined<4,1>
1308 {
1309 static bool const value=true;
1310 };
1311 }
1312
1313 template <class R,class A>
1314 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1315 typename enable_if_c<
1316 mat_traits<R>::rows==1 && mat_traits<A>::rows==1 &&
1317 mat_traits<R>::cols==4 && mat_traits<A>::cols==4,
1318 R>::type
1319 convert_to( A const & a )
1320 {
1321 R r;
1322 write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a));
1323 write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a));
1324 write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a));
1325 write_mat_element<0,3>(r,mat_traits<A>::template read_element<0,3>(a));
1326 return r;
1327 }
1328
1329 namespace
1330 sfinae
1331 {
1332 using ::boost::qvm::convert_to;
1333 }
1334
1335 namespace
1336 qvm_detail
1337 {
1338 template <int R,int C>
1339 struct convert_to_m_defined;
1340
1341 template <>
1342 struct
1343 convert_to_m_defined<1,4>
1344 {
1345 static bool const value=true;
1346 };
1347 }
1348
1349 template <class A,class B>
1350 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1351 typename enable_if_c<
1352 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
1353 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
1354 bool>::type
1355 operator==( A const & a, B const & b )
1356 {
1357 return
1358 mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
1359 mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) &&
1360 mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b) &&
1361 mat_traits<A>::template read_element<0,3>(a)==mat_traits<B>::template read_element<0,3>(b) &&
1362 mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) &&
1363 mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b) &&
1364 mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b) &&
1365 mat_traits<A>::template read_element<1,3>(a)==mat_traits<B>::template read_element<1,3>(b) &&
1366 mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b) &&
1367 mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b) &&
1368 mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b) &&
1369 mat_traits<A>::template read_element<2,3>(a)==mat_traits<B>::template read_element<2,3>(b) &&
1370 mat_traits<A>::template read_element<3,0>(a)==mat_traits<B>::template read_element<3,0>(b) &&
1371 mat_traits<A>::template read_element<3,1>(a)==mat_traits<B>::template read_element<3,1>(b) &&
1372 mat_traits<A>::template read_element<3,2>(a)==mat_traits<B>::template read_element<3,2>(b) &&
1373 mat_traits<A>::template read_element<3,3>(a)==mat_traits<B>::template read_element<3,3>(b);
1374 }
1375
1376 namespace
1377 sfinae
1378 {
1379 using ::boost::qvm::operator==;
1380 }
1381
1382 namespace
1383 qvm_detail
1384 {
1385 template <int R,int C>
1386 struct eq_mm_defined;
1387
1388 template <>
1389 struct
1390 eq_mm_defined<4,4>
1391 {
1392 static bool const value=true;
1393 };
1394 }
1395
1396 template <class A,class B>
1397 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1398 typename enable_if_c<
1399 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
1400 mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
1401 bool>::type
1402 operator==( A const & a, B const & b )
1403 {
1404 return
1405 mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
1406 mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) &&
1407 mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b) &&
1408 mat_traits<A>::template read_element<3,0>(a)==mat_traits<B>::template read_element<3,0>(b);
1409 }
1410
1411 namespace
1412 sfinae
1413 {
1414 using ::boost::qvm::operator==;
1415 }
1416
1417 namespace
1418 qvm_detail
1419 {
1420 template <int R,int C>
1421 struct eq_mm_defined;
1422
1423 template <>
1424 struct
1425 eq_mm_defined<4,1>
1426 {
1427 static bool const value=true;
1428 };
1429 }
1430
1431 template <class A,class B>
1432 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1433 typename enable_if_c<
1434 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
1435 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
1436 bool>::type
1437 operator==( A const & a, B const & b )
1438 {
1439 return
1440 mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
1441 mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) &&
1442 mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b) &&
1443 mat_traits<A>::template read_element<0,3>(a)==mat_traits<B>::template read_element<0,3>(b);
1444 }
1445
1446 namespace
1447 sfinae
1448 {
1449 using ::boost::qvm::operator==;
1450 }
1451
1452 namespace
1453 qvm_detail
1454 {
1455 template <int R,int C>
1456 struct eq_mm_defined;
1457
1458 template <>
1459 struct
1460 eq_mm_defined<1,4>
1461 {
1462 static bool const value=true;
1463 };
1464 }
1465
1466 template <class A,class B>
1467 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1468 typename enable_if_c<
1469 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
1470 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
1471 bool>::type
1472 operator!=( A const & a, B const & b )
1473 {
1474 return
1475 !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
1476 !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) ||
1477 !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b)) ||
1478 !(mat_traits<A>::template read_element<0,3>(a)==mat_traits<B>::template read_element<0,3>(b)) ||
1479 !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) ||
1480 !(mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b)) ||
1481 !(mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b)) ||
1482 !(mat_traits<A>::template read_element<1,3>(a)==mat_traits<B>::template read_element<1,3>(b)) ||
1483 !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b)) ||
1484 !(mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b)) ||
1485 !(mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b)) ||
1486 !(mat_traits<A>::template read_element<2,3>(a)==mat_traits<B>::template read_element<2,3>(b)) ||
1487 !(mat_traits<A>::template read_element<3,0>(a)==mat_traits<B>::template read_element<3,0>(b)) ||
1488 !(mat_traits<A>::template read_element<3,1>(a)==mat_traits<B>::template read_element<3,1>(b)) ||
1489 !(mat_traits<A>::template read_element<3,2>(a)==mat_traits<B>::template read_element<3,2>(b)) ||
1490 !(mat_traits<A>::template read_element<3,3>(a)==mat_traits<B>::template read_element<3,3>(b));
1491 }
1492
1493 namespace
1494 sfinae
1495 {
1496 using ::boost::qvm::operator!=;
1497 }
1498
1499 namespace
1500 qvm_detail
1501 {
1502 template <int R,int C>
1503 struct neq_mm_defined;
1504
1505 template <>
1506 struct
1507 neq_mm_defined<4,4>
1508 {
1509 static bool const value=true;
1510 };
1511 }
1512
1513 template <class A,class B>
1514 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1515 typename enable_if_c<
1516 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
1517 mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
1518 bool>::type
1519 operator!=( A const & a, B const & b )
1520 {
1521 return
1522 !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
1523 !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) ||
1524 !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b)) ||
1525 !(mat_traits<A>::template read_element<3,0>(a)==mat_traits<B>::template read_element<3,0>(b));
1526 }
1527
1528 namespace
1529 sfinae
1530 {
1531 using ::boost::qvm::operator!=;
1532 }
1533
1534 namespace
1535 qvm_detail
1536 {
1537 template <int R,int C>
1538 struct neq_mm_defined;
1539
1540 template <>
1541 struct
1542 neq_mm_defined<4,1>
1543 {
1544 static bool const value=true;
1545 };
1546 }
1547
1548 template <class A,class B>
1549 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1550 typename enable_if_c<
1551 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
1552 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
1553 bool>::type
1554 operator!=( A const & a, B const & b )
1555 {
1556 return
1557 !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
1558 !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) ||
1559 !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b)) ||
1560 !(mat_traits<A>::template read_element<0,3>(a)==mat_traits<B>::template read_element<0,3>(b));
1561 }
1562
1563 namespace
1564 sfinae
1565 {
1566 using ::boost::qvm::operator!=;
1567 }
1568
1569 namespace
1570 qvm_detail
1571 {
1572 template <int R,int C>
1573 struct neq_mm_defined;
1574
1575 template <>
1576 struct
1577 neq_mm_defined<1,4>
1578 {
1579 static bool const value=true;
1580 };
1581 }
1582
1583 template <class A>
1584 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1585 typename lazy_enable_if_c<
1586 mat_traits<A>::rows==4 && mat_traits<A>::cols==4,
1587 deduce_mat<A> >::type
1588 operator-( A const & a )
1589 {
1590 typedef typename deduce_mat<A>::type R;
1591 R r;
1592 write_mat_element<0,0>(r,-mat_traits<A>::template read_element<0,0>(a));
1593 write_mat_element<0,1>(r,-mat_traits<A>::template read_element<0,1>(a));
1594 write_mat_element<0,2>(r,-mat_traits<A>::template read_element<0,2>(a));
1595 write_mat_element<0,3>(r,-mat_traits<A>::template read_element<0,3>(a));
1596 write_mat_element<1,0>(r,-mat_traits<A>::template read_element<1,0>(a));
1597 write_mat_element<1,1>(r,-mat_traits<A>::template read_element<1,1>(a));
1598 write_mat_element<1,2>(r,-mat_traits<A>::template read_element<1,2>(a));
1599 write_mat_element<1,3>(r,-mat_traits<A>::template read_element<1,3>(a));
1600 write_mat_element<2,0>(r,-mat_traits<A>::template read_element<2,0>(a));
1601 write_mat_element<2,1>(r,-mat_traits<A>::template read_element<2,1>(a));
1602 write_mat_element<2,2>(r,-mat_traits<A>::template read_element<2,2>(a));
1603 write_mat_element<2,3>(r,-mat_traits<A>::template read_element<2,3>(a));
1604 write_mat_element<3,0>(r,-mat_traits<A>::template read_element<3,0>(a));
1605 write_mat_element<3,1>(r,-mat_traits<A>::template read_element<3,1>(a));
1606 write_mat_element<3,2>(r,-mat_traits<A>::template read_element<3,2>(a));
1607 write_mat_element<3,3>(r,-mat_traits<A>::template read_element<3,3>(a));
1608 return r;
1609 }
1610
1611 namespace
1612 sfinae
1613 {
1614 using ::boost::qvm::operator-;
1615 }
1616
1617 namespace
1618 qvm_detail
1619 {
1620 template <int R,int C>
1621 struct minus_m_defined;
1622
1623 template <>
1624 struct
1625 minus_m_defined<4,4>
1626 {
1627 static bool const value=true;
1628 };
1629 }
1630
1631 template <class A>
1632 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1633 typename lazy_enable_if_c<
1634 mat_traits<A>::rows==4 && mat_traits<A>::cols==1,
1635 deduce_mat<A> >::type
1636 operator-( A const & a )
1637 {
1638 typedef typename deduce_mat<A>::type R;
1639 R r;
1640 write_mat_element<0,0>(r,-mat_traits<A>::template read_element<0,0>(a));
1641 write_mat_element<1,0>(r,-mat_traits<A>::template read_element<1,0>(a));
1642 write_mat_element<2,0>(r,-mat_traits<A>::template read_element<2,0>(a));
1643 write_mat_element<3,0>(r,-mat_traits<A>::template read_element<3,0>(a));
1644 return r;
1645 }
1646
1647 namespace
1648 sfinae
1649 {
1650 using ::boost::qvm::operator-;
1651 }
1652
1653 namespace
1654 qvm_detail
1655 {
1656 template <int R,int C>
1657 struct minus_m_defined;
1658
1659 template <>
1660 struct
1661 minus_m_defined<4,1>
1662 {
1663 static bool const value=true;
1664 };
1665 }
1666
1667 template <class A>
1668 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1669 typename lazy_enable_if_c<
1670 mat_traits<A>::rows==1 && mat_traits<A>::cols==4,
1671 deduce_mat<A> >::type
1672 operator-( A const & a )
1673 {
1674 typedef typename deduce_mat<A>::type R;
1675 R r;
1676 write_mat_element<0,0>(r,-mat_traits<A>::template read_element<0,0>(a));
1677 write_mat_element<0,1>(r,-mat_traits<A>::template read_element<0,1>(a));
1678 write_mat_element<0,2>(r,-mat_traits<A>::template read_element<0,2>(a));
1679 write_mat_element<0,3>(r,-mat_traits<A>::template read_element<0,3>(a));
1680 return r;
1681 }
1682
1683 namespace
1684 sfinae
1685 {
1686 using ::boost::qvm::operator-;
1687 }
1688
1689 namespace
1690 qvm_detail
1691 {
1692 template <int R,int C>
1693 struct minus_m_defined;
1694
1695 template <>
1696 struct
1697 minus_m_defined<1,4>
1698 {
1699 static bool const value=true;
1700 };
1701 }
1702
1703 template <class A>
1704 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1705 typename enable_if_c<
1706 mat_traits<A>::rows==4 && mat_traits<A>::cols==4,
1707 typename mat_traits<A>::scalar_type>::type
1708 determinant( A const & a )
1709 {
1710 typedef typename mat_traits<A>::scalar_type T;
1711 T const a00=mat_traits<A>::template read_element<0,0>(a);
1712 T const a01=mat_traits<A>::template read_element<0,1>(a);
1713 T const a02=mat_traits<A>::template read_element<0,2>(a);
1714 T const a03=mat_traits<A>::template read_element<0,3>(a);
1715 T const a10=mat_traits<A>::template read_element<1,0>(a);
1716 T const a11=mat_traits<A>::template read_element<1,1>(a);
1717 T const a12=mat_traits<A>::template read_element<1,2>(a);
1718 T const a13=mat_traits<A>::template read_element<1,3>(a);
1719 T const a20=mat_traits<A>::template read_element<2,0>(a);
1720 T const a21=mat_traits<A>::template read_element<2,1>(a);
1721 T const a22=mat_traits<A>::template read_element<2,2>(a);
1722 T const a23=mat_traits<A>::template read_element<2,3>(a);
1723 T const a30=mat_traits<A>::template read_element<3,0>(a);
1724 T const a31=mat_traits<A>::template read_element<3,1>(a);
1725 T const a32=mat_traits<A>::template read_element<3,2>(a);
1726 T const a33=mat_traits<A>::template read_element<3,3>(a);
1727 T det=(a00*(a11*(a22*a33-a23*a32)-a12*(a21*a33-a23*a31)+a13*(a21*a32-a22*a31))-a01*(a10*(a22*a33-a23*a32)-a12*(a20*a33-a23*a30)+a13*(a20*a32-a22*a30))+a02*(a10*(a21*a33-a23*a31)-a11*(a20*a33-a23*a30)+a13*(a20*a31-a21*a30))-a03*(a10*(a21*a32-a22*a31)-a11*(a20*a32-a22*a30)+a12*(a20*a31-a21*a30)));
1728 return det;
1729 }
1730
1731 namespace
1732 sfinae
1733 {
1734 using ::boost::qvm::determinant;
1735 }
1736
1737 namespace
1738 qvm_detail
1739 {
1740 template <int D>
1741 struct determinant_defined;
1742
1743 template <>
1744 struct
1745 determinant_defined<4>
1746 {
1747 static bool const value=true;
1748 };
1749 }
1750
1751 template <class A,class B>
1752 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1753 typename lazy_enable_if_c<
1754 mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
1755 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
1756 inverse( A const & a, B det )
1757 {
1758 typedef typename mat_traits<A>::scalar_type T;
1759 BOOST_QVM_ASSERT(det!=scalar_traits<B>::value(0));
1760 T const a00=mat_traits<A>::template read_element<0,0>(a);
1761 T const a01=mat_traits<A>::template read_element<0,1>(a);
1762 T const a02=mat_traits<A>::template read_element<0,2>(a);
1763 T const a03=mat_traits<A>::template read_element<0,3>(a);
1764 T const a10=mat_traits<A>::template read_element<1,0>(a);
1765 T const a11=mat_traits<A>::template read_element<1,1>(a);
1766 T const a12=mat_traits<A>::template read_element<1,2>(a);
1767 T const a13=mat_traits<A>::template read_element<1,3>(a);
1768 T const a20=mat_traits<A>::template read_element<2,0>(a);
1769 T const a21=mat_traits<A>::template read_element<2,1>(a);
1770 T const a22=mat_traits<A>::template read_element<2,2>(a);
1771 T const a23=mat_traits<A>::template read_element<2,3>(a);
1772 T const a30=mat_traits<A>::template read_element<3,0>(a);
1773 T const a31=mat_traits<A>::template read_element<3,1>(a);
1774 T const a32=mat_traits<A>::template read_element<3,2>(a);
1775 T const a33=mat_traits<A>::template read_element<3,3>(a);
1776 T const f=scalar_traits<T>::value(1)/det;
1777 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
1778 R r;
1779 write_mat_element<0,0>(r, f*(a11*(a22*a33-a23*a32)-a12*(a21*a33-a23*a31)+a13*(a21*a32-a22*a31)));
1780 write_mat_element<0,1>(r,-f*(a01*(a22*a33-a23*a32)-a02*(a21*a33-a23*a31)+a03*(a21*a32-a22*a31)));
1781 write_mat_element<0,2>(r, f*(a01*(a12*a33-a13*a32)-a02*(a11*a33-a13*a31)+a03*(a11*a32-a12*a31)));
1782 write_mat_element<0,3>(r,-f*(a01*(a12*a23-a13*a22)-a02*(a11*a23-a13*a21)+a03*(a11*a22-a12*a21)));
1783 write_mat_element<1,0>(r,-f*(a10*(a22*a33-a23*a32)-a12*(a20*a33-a23*a30)+a13*(a20*a32-a22*a30)));
1784 write_mat_element<1,1>(r, f*(a00*(a22*a33-a23*a32)-a02*(a20*a33-a23*a30)+a03*(a20*a32-a22*a30)));
1785 write_mat_element<1,2>(r,-f*(a00*(a12*a33-a13*a32)-a02*(a10*a33-a13*a30)+a03*(a10*a32-a12*a30)));
1786 write_mat_element<1,3>(r, f*(a00*(a12*a23-a13*a22)-a02*(a10*a23-a13*a20)+a03*(a10*a22-a12*a20)));
1787 write_mat_element<2,0>(r, f*(a10*(a21*a33-a23*a31)-a11*(a20*a33-a23*a30)+a13*(a20*a31-a21*a30)));
1788 write_mat_element<2,1>(r,-f*(a00*(a21*a33-a23*a31)-a01*(a20*a33-a23*a30)+a03*(a20*a31-a21*a30)));
1789 write_mat_element<2,2>(r, f*(a00*(a11*a33-a13*a31)-a01*(a10*a33-a13*a30)+a03*(a10*a31-a11*a30)));
1790 write_mat_element<2,3>(r,-f*(a00*(a11*a23-a13*a21)-a01*(a10*a23-a13*a20)+a03*(a10*a21-a11*a20)));
1791 write_mat_element<3,0>(r,-f*(a10*(a21*a32-a22*a31)-a11*(a20*a32-a22*a30)+a12*(a20*a31-a21*a30)));
1792 write_mat_element<3,1>(r, f*(a00*(a21*a32-a22*a31)-a01*(a20*a32-a22*a30)+a02*(a20*a31-a21*a30)));
1793 write_mat_element<3,2>(r,-f*(a00*(a11*a32-a12*a31)-a01*(a10*a32-a12*a30)+a02*(a10*a31-a11*a30)));
1794 write_mat_element<3,3>(r, f*(a00*(a11*a22-a12*a21)-a01*(a10*a22-a12*a20)+a02*(a10*a21-a11*a20)));
1795 return r;
1796 }
1797
1798 template <class A>
1799 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1800 typename lazy_enable_if_c<
1801 mat_traits<A>::rows==4 && mat_traits<A>::cols==4,
1802 deduce_mat<A> >::type
1803 inverse( A const & a )
1804 {
1805 typedef typename mat_traits<A>::scalar_type T;
1806 T det=determinant(a);
1807 if( det==scalar_traits<T>::value(0) )
1808 BOOST_QVM_THROW_EXCEPTION(zero_determinant_error());
1809 return inverse(a,det);
1810 }
1811
1812 namespace
1813 sfinae
1814 {
1815 using ::boost::qvm::inverse;
1816 }
1817
1818 namespace
1819 qvm_detail
1820 {
1821 template <int D>
1822 struct inverse_m_defined;
1823
1824 template <>
1825 struct
1826 inverse_m_defined<4>
1827 {
1828 static bool const value=true;
1829 };
1830 }
1831
1832 template <class A,class B>
1833 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1834 typename lazy_enable_if_c<
1835 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
1836 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
1837 deduce_mat2<A,B,4,4> >::type
1838 operator*( A const & a, B const & b )
1839 {
1840 typedef typename mat_traits<A>::scalar_type Ta;
1841 typedef typename mat_traits<B>::scalar_type Tb;
1842 Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
1843 Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
1844 Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
1845 Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
1846 Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
1847 Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
1848 Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
1849 Ta const a13 = mat_traits<A>::template read_element<1,3>(a);
1850 Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
1851 Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
1852 Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
1853 Ta const a23 = mat_traits<A>::template read_element<2,3>(a);
1854 Ta const a30 = mat_traits<A>::template read_element<3,0>(a);
1855 Ta const a31 = mat_traits<A>::template read_element<3,1>(a);
1856 Ta const a32 = mat_traits<A>::template read_element<3,2>(a);
1857 Ta const a33 = mat_traits<A>::template read_element<3,3>(a);
1858 Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
1859 Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
1860 Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
1861 Tb const b03 = mat_traits<B>::template read_element<0,3>(b);
1862 Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
1863 Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
1864 Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
1865 Tb const b13 = mat_traits<B>::template read_element<1,3>(b);
1866 Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
1867 Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
1868 Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
1869 Tb const b23 = mat_traits<B>::template read_element<2,3>(b);
1870 Tb const b30 = mat_traits<B>::template read_element<3,0>(b);
1871 Tb const b31 = mat_traits<B>::template read_element<3,1>(b);
1872 Tb const b32 = mat_traits<B>::template read_element<3,2>(b);
1873 Tb const b33 = mat_traits<B>::template read_element<3,3>(b);
1874 typedef typename deduce_mat2<A,B,4,4>::type R;
1875 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
1876 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
1877 R r;
1878 write_mat_element<0,0>(r,a00*b00+a01*b10+a02*b20+a03*b30);
1879 write_mat_element<0,1>(r,a00*b01+a01*b11+a02*b21+a03*b31);
1880 write_mat_element<0,2>(r,a00*b02+a01*b12+a02*b22+a03*b32);
1881 write_mat_element<0,3>(r,a00*b03+a01*b13+a02*b23+a03*b33);
1882 write_mat_element<1,0>(r,a10*b00+a11*b10+a12*b20+a13*b30);
1883 write_mat_element<1,1>(r,a10*b01+a11*b11+a12*b21+a13*b31);
1884 write_mat_element<1,2>(r,a10*b02+a11*b12+a12*b22+a13*b32);
1885 write_mat_element<1,3>(r,a10*b03+a11*b13+a12*b23+a13*b33);
1886 write_mat_element<2,0>(r,a20*b00+a21*b10+a22*b20+a23*b30);
1887 write_mat_element<2,1>(r,a20*b01+a21*b11+a22*b21+a23*b31);
1888 write_mat_element<2,2>(r,a20*b02+a21*b12+a22*b22+a23*b32);
1889 write_mat_element<2,3>(r,a20*b03+a21*b13+a22*b23+a23*b33);
1890 write_mat_element<3,0>(r,a30*b00+a31*b10+a32*b20+a33*b30);
1891 write_mat_element<3,1>(r,a30*b01+a31*b11+a32*b21+a33*b31);
1892 write_mat_element<3,2>(r,a30*b02+a31*b12+a32*b22+a33*b32);
1893 write_mat_element<3,3>(r,a30*b03+a31*b13+a32*b23+a33*b33);
1894 return r;
1895 }
1896
1897 namespace
1898 sfinae
1899 {
1900 using ::boost::qvm::operator*;
1901 }
1902
1903 namespace
1904 qvm_detail
1905 {
1906 template <int R,int ,int C>
1907 struct mul_mm_defined;
1908
1909 template <>
1910 struct
1911 mul_mm_defined<4,4,4>
1912 {
1913 static bool const value=true;
1914 };
1915 }
1916
1917 template <class A,class B>
1918 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1919 typename enable_if_c<
1920 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
1921 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
1922 A &>::type
1923 operator*=( A & a, B const & b )
1924 {
1925 typedef typename mat_traits<A>::scalar_type Ta;
1926 typedef typename mat_traits<B>::scalar_type Tb;
1927 Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
1928 Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
1929 Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
1930 Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
1931 Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
1932 Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
1933 Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
1934 Ta const a13 = mat_traits<A>::template read_element<1,3>(a);
1935 Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
1936 Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
1937 Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
1938 Ta const a23 = mat_traits<A>::template read_element<2,3>(a);
1939 Ta const a30 = mat_traits<A>::template read_element<3,0>(a);
1940 Ta const a31 = mat_traits<A>::template read_element<3,1>(a);
1941 Ta const a32 = mat_traits<A>::template read_element<3,2>(a);
1942 Ta const a33 = mat_traits<A>::template read_element<3,3>(a);
1943 Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
1944 Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
1945 Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
1946 Tb const b03 = mat_traits<B>::template read_element<0,3>(b);
1947 Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
1948 Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
1949 Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
1950 Tb const b13 = mat_traits<B>::template read_element<1,3>(b);
1951 Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
1952 Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
1953 Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
1954 Tb const b23 = mat_traits<B>::template read_element<2,3>(b);
1955 Tb const b30 = mat_traits<B>::template read_element<3,0>(b);
1956 Tb const b31 = mat_traits<B>::template read_element<3,1>(b);
1957 Tb const b32 = mat_traits<B>::template read_element<3,2>(b);
1958 Tb const b33 = mat_traits<B>::template read_element<3,3>(b);
1959 write_mat_element<0,0>(a,a00*b00+a01*b10+a02*b20+a03*b30);
1960 write_mat_element<0,1>(a,a00*b01+a01*b11+a02*b21+a03*b31);
1961 write_mat_element<0,2>(a,a00*b02+a01*b12+a02*b22+a03*b32);
1962 write_mat_element<0,3>(a,a00*b03+a01*b13+a02*b23+a03*b33);
1963 write_mat_element<1,0>(a,a10*b00+a11*b10+a12*b20+a13*b30);
1964 write_mat_element<1,1>(a,a10*b01+a11*b11+a12*b21+a13*b31);
1965 write_mat_element<1,2>(a,a10*b02+a11*b12+a12*b22+a13*b32);
1966 write_mat_element<1,3>(a,a10*b03+a11*b13+a12*b23+a13*b33);
1967 write_mat_element<2,0>(a,a20*b00+a21*b10+a22*b20+a23*b30);
1968 write_mat_element<2,1>(a,a20*b01+a21*b11+a22*b21+a23*b31);
1969 write_mat_element<2,2>(a,a20*b02+a21*b12+a22*b22+a23*b32);
1970 write_mat_element<2,3>(a,a20*b03+a21*b13+a22*b23+a23*b33);
1971 write_mat_element<3,0>(a,a30*b00+a31*b10+a32*b20+a33*b30);
1972 write_mat_element<3,1>(a,a30*b01+a31*b11+a32*b21+a33*b31);
1973 write_mat_element<3,2>(a,a30*b02+a31*b12+a32*b22+a33*b32);
1974 write_mat_element<3,3>(a,a30*b03+a31*b13+a32*b23+a33*b33);
1975 return a;
1976 }
1977
1978 namespace
1979 sfinae
1980 {
1981 using ::boost::qvm::operator*=;
1982 }
1983
1984 namespace
1985 qvm_detail
1986 {
1987 template <int D>
1988 struct mul_eq_mm_defined;
1989
1990 template <>
1991 struct
1992 mul_eq_mm_defined<4>
1993 {
1994 static bool const value=true;
1995 };
1996 }
1997
1998 template <class A,class B>
1999 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
2000 typename lazy_enable_if_c<
2001 mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
2002 mat_traits<A>::cols==4 && mat_traits<B>::cols==1,
2003 deduce_mat2<A,B,4,1> >::type
2004 operator*( A const & a, B const & b )
2005 {
2006 typedef typename mat_traits<A>::scalar_type Ta;
2007 typedef typename mat_traits<B>::scalar_type Tb;
2008 Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
2009 Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
2010 Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
2011 Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
2012 Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
2013 Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
2014 Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
2015 Ta const a13 = mat_traits<A>::template read_element<1,3>(a);
2016 Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
2017 Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
2018 Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
2019 Ta const a23 = mat_traits<A>::template read_element<2,3>(a);
2020 Ta const a30 = mat_traits<A>::template read_element<3,0>(a);
2021 Ta const a31 = mat_traits<A>::template read_element<3,1>(a);
2022 Ta const a32 = mat_traits<A>::template read_element<3,2>(a);
2023 Ta const a33 = mat_traits<A>::template read_element<3,3>(a);
2024 Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
2025 Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
2026 Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
2027 Tb const b30 = mat_traits<B>::template read_element<3,0>(b);
2028 typedef typename deduce_mat2<A,B,4,1>::type R;
2029 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
2030 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
2031 R r;
2032 write_mat_element<0,0>(r,a00*b00+a01*b10+a02*b20+a03*b30);
2033 write_mat_element<1,0>(r,a10*b00+a11*b10+a12*b20+a13*b30);
2034 write_mat_element<2,0>(r,a20*b00+a21*b10+a22*b20+a23*b30);
2035 write_mat_element<3,0>(r,a30*b00+a31*b10+a32*b20+a33*b30);
2036 return r;
2037 }
2038
2039 namespace
2040 sfinae
2041 {
2042 using ::boost::qvm::operator*;
2043 }
2044
2045 namespace
2046 qvm_detail
2047 {
2048 template <int R,int ,int C>
2049 struct mul_mm_defined;
2050
2051 template <>
2052 struct
2053 mul_mm_defined<4,4,1>
2054 {
2055 static bool const value=true;
2056 };
2057 }
2058
2059 template <class A,class B>
2060 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
2061 typename lazy_enable_if_c<
2062 mat_traits<A>::rows==1 && mat_traits<B>::rows==4 &&
2063 mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
2064 deduce_mat2<A,B,1,4> >::type
2065 operator*( A const & a, B const & b )
2066 {
2067 typedef typename mat_traits<A>::scalar_type Ta;
2068 typedef typename mat_traits<B>::scalar_type Tb;
2069 Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
2070 Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
2071 Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
2072 Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
2073 Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
2074 Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
2075 Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
2076 Tb const b03 = mat_traits<B>::template read_element<0,3>(b);
2077 Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
2078 Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
2079 Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
2080 Tb const b13 = mat_traits<B>::template read_element<1,3>(b);
2081 Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
2082 Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
2083 Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
2084 Tb const b23 = mat_traits<B>::template read_element<2,3>(b);
2085 Tb const b30 = mat_traits<B>::template read_element<3,0>(b);
2086 Tb const b31 = mat_traits<B>::template read_element<3,1>(b);
2087 Tb const b32 = mat_traits<B>::template read_element<3,2>(b);
2088 Tb const b33 = mat_traits<B>::template read_element<3,3>(b);
2089 typedef typename deduce_mat2<A,B,1,4>::type R;
2090 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
2091 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
2092 R r;
2093 write_mat_element<0,0>(r,a00*b00+a01*b10+a02*b20+a03*b30);
2094 write_mat_element<0,1>(r,a00*b01+a01*b11+a02*b21+a03*b31);
2095 write_mat_element<0,2>(r,a00*b02+a01*b12+a02*b22+a03*b32);
2096 write_mat_element<0,3>(r,a00*b03+a01*b13+a02*b23+a03*b33);
2097 return r;
2098 }
2099
2100 namespace
2101 sfinae
2102 {
2103 using ::boost::qvm::operator*;
2104 }
2105
2106 namespace
2107 qvm_detail
2108 {
2109 template <int R,int ,int C>
2110 struct mul_mm_defined;
2111
2112 template <>
2113 struct
2114 mul_mm_defined<1,4,4>
2115 {
2116 static bool const value=true;
2117 };
2118 }
2119
2120 } }
2121
2122 #endif