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