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