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