1 //Copyright (c) 2008-2017 Emil Dotchevski and Reverge Studios, Inc. 2 3 //Distributed under the Boost Software License, Version 1.0. (See accompanying 4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef BOOST_QVM_171198542F112D558F56BD68879992 7 #define BOOST_QVM_171198542F112D558F56BD68879992 8 9 //This file was generated by a program. Do not edit manually. 10 11 #include <boost/qvm/assert.hpp> 12 #include <boost/qvm/deduce_mat.hpp> 13 #include <boost/qvm/deduce_vec.hpp> 14 #include <boost/qvm/error.hpp> 15 #include <boost/qvm/gen/mat_assign3.hpp> 16 #include <boost/qvm/quat_traits.hpp> 17 #include <boost/qvm/scalar_traits.hpp> 18 #include <boost/qvm/throw_exception.hpp> 19 20 namespace 21 boost 22 { 23 namespace 24 qvm 25 { 26 template <class A,class B> 27 BOOST_QVM_INLINE_OPERATIONS 28 typename lazy_enable_if_c< 29 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 30 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 31 deduce_mat2<A,B,3,3> >::type operator +(A const & a,B const & b)32 operator+( A const & a, B const & b ) 33 { 34 typedef typename deduce_mat2<A,B,3,3>::type R; 35 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3); 36 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3); 37 R r; 38 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b); 39 mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b); 40 mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b); 41 mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b); 42 mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)+mat_traits<B>::template read_element<1,1>(b); 43 mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)+mat_traits<B>::template read_element<1,2>(b); 44 mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b); 45 mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)+mat_traits<B>::template read_element<2,1>(b); 46 mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)+mat_traits<B>::template read_element<2,2>(b); 47 return r; 48 } 49 50 namespace 51 sfinae 52 { 53 using ::boost::qvm::operator+; 54 } 55 56 namespace 57 qvm_detail 58 { 59 template <int R,int C> 60 struct plus_mm_defined; 61 62 template <> 63 struct 64 plus_mm_defined<3,3> 65 { 66 static bool const value=true; 67 }; 68 } 69 70 template <class A,class B> 71 BOOST_QVM_INLINE_OPERATIONS 72 typename lazy_enable_if_c< 73 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 74 mat_traits<A>::cols==1 && mat_traits<B>::cols==1, 75 deduce_mat2<A,B,3,1> >::type operator +(A const & a,B const & b)76 operator+( A const & a, B const & b ) 77 { 78 typedef typename deduce_mat2<A,B,3,1>::type R; 79 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3); 80 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1); 81 R r; 82 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b); 83 mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b); 84 mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b); 85 return r; 86 } 87 88 namespace 89 sfinae 90 { 91 using ::boost::qvm::operator+; 92 } 93 94 namespace 95 qvm_detail 96 { 97 template <int R,int C> 98 struct plus_mm_defined; 99 100 template <> 101 struct 102 plus_mm_defined<3,1> 103 { 104 static bool const value=true; 105 }; 106 } 107 108 template <class A,class B> 109 BOOST_QVM_INLINE_OPERATIONS 110 typename lazy_enable_if_c< 111 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 && 112 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 113 deduce_mat2<A,B,1,3> >::type operator +(A const & a,B const & b)114 operator+( A const & a, B const & b ) 115 { 116 typedef typename deduce_mat2<A,B,1,3>::type R; 117 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1); 118 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3); 119 R r; 120 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b); 121 mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b); 122 mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b); 123 return r; 124 } 125 126 namespace 127 sfinae 128 { 129 using ::boost::qvm::operator+; 130 } 131 132 namespace 133 qvm_detail 134 { 135 template <int R,int C> 136 struct plus_mm_defined; 137 138 template <> 139 struct 140 plus_mm_defined<1,3> 141 { 142 static bool const value=true; 143 }; 144 } 145 146 template <class A,class B> 147 BOOST_QVM_INLINE_OPERATIONS 148 typename lazy_enable_if_c< 149 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 150 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 151 deduce_mat2<A,B,3,3> >::type operator -(A const & a,B const & b)152 operator-( A const & a, B const & b ) 153 { 154 typedef typename deduce_mat2<A,B,3,3>::type R; 155 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3); 156 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3); 157 R r; 158 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b); 159 mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b); 160 mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b); 161 mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b); 162 mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)-mat_traits<B>::template read_element<1,1>(b); 163 mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)-mat_traits<B>::template read_element<1,2>(b); 164 mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b); 165 mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)-mat_traits<B>::template read_element<2,1>(b); 166 mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)-mat_traits<B>::template read_element<2,2>(b); 167 return r; 168 } 169 170 namespace 171 sfinae 172 { 173 using ::boost::qvm::operator-; 174 } 175 176 namespace 177 qvm_detail 178 { 179 template <int R,int C> 180 struct minus_mm_defined; 181 182 template <> 183 struct 184 minus_mm_defined<3,3> 185 { 186 static bool const value=true; 187 }; 188 } 189 190 template <class A,class B> 191 BOOST_QVM_INLINE_OPERATIONS 192 typename lazy_enable_if_c< 193 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 194 mat_traits<A>::cols==1 && mat_traits<B>::cols==1, 195 deduce_mat2<A,B,3,1> >::type operator -(A const & a,B const & b)196 operator-( A const & a, B const & b ) 197 { 198 typedef typename deduce_mat2<A,B,3,1>::type R; 199 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3); 200 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1); 201 R r; 202 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b); 203 mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b); 204 mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b); 205 return r; 206 } 207 208 namespace 209 sfinae 210 { 211 using ::boost::qvm::operator-; 212 } 213 214 namespace 215 qvm_detail 216 { 217 template <int R,int C> 218 struct minus_mm_defined; 219 220 template <> 221 struct 222 minus_mm_defined<3,1> 223 { 224 static bool const value=true; 225 }; 226 } 227 228 template <class A,class B> 229 BOOST_QVM_INLINE_OPERATIONS 230 typename lazy_enable_if_c< 231 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 && 232 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 233 deduce_mat2<A,B,1,3> >::type operator -(A const & a,B const & b)234 operator-( A const & a, B const & b ) 235 { 236 typedef typename deduce_mat2<A,B,1,3>::type R; 237 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1); 238 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3); 239 R r; 240 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b); 241 mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b); 242 mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b); 243 return r; 244 } 245 246 namespace 247 sfinae 248 { 249 using ::boost::qvm::operator-; 250 } 251 252 namespace 253 qvm_detail 254 { 255 template <int R,int C> 256 struct minus_mm_defined; 257 258 template <> 259 struct 260 minus_mm_defined<1,3> 261 { 262 static bool const value=true; 263 }; 264 } 265 266 template <class A,class B> 267 BOOST_QVM_INLINE_OPERATIONS 268 typename enable_if_c< 269 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 270 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 271 A &>::type operator +=(A & a,B const & b)272 operator+=( A & a, B const & b ) 273 { 274 mat_traits<A>::template write_element<0,0>(a)+=mat_traits<B>::template read_element<0,0>(b); 275 mat_traits<A>::template write_element<0,1>(a)+=mat_traits<B>::template read_element<0,1>(b); 276 mat_traits<A>::template write_element<0,2>(a)+=mat_traits<B>::template read_element<0,2>(b); 277 mat_traits<A>::template write_element<1,0>(a)+=mat_traits<B>::template read_element<1,0>(b); 278 mat_traits<A>::template write_element<1,1>(a)+=mat_traits<B>::template read_element<1,1>(b); 279 mat_traits<A>::template write_element<1,2>(a)+=mat_traits<B>::template read_element<1,2>(b); 280 mat_traits<A>::template write_element<2,0>(a)+=mat_traits<B>::template read_element<2,0>(b); 281 mat_traits<A>::template write_element<2,1>(a)+=mat_traits<B>::template read_element<2,1>(b); 282 mat_traits<A>::template write_element<2,2>(a)+=mat_traits<B>::template read_element<2,2>(b); 283 return a; 284 } 285 286 namespace 287 sfinae 288 { 289 using ::boost::qvm::operator+=; 290 } 291 292 namespace 293 qvm_detail 294 { 295 template <int R,int C> 296 struct plus_eq_mm_defined; 297 298 template <> 299 struct 300 plus_eq_mm_defined<3,3> 301 { 302 static bool const value=true; 303 }; 304 } 305 306 template <class A,class B> 307 BOOST_QVM_INLINE_OPERATIONS 308 typename enable_if_c< 309 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 310 mat_traits<A>::cols==1 && mat_traits<B>::cols==1, 311 A &>::type operator +=(A & a,B const & b)312 operator+=( A & a, B const & b ) 313 { 314 mat_traits<A>::template write_element<0,0>(a)+=mat_traits<B>::template read_element<0,0>(b); 315 mat_traits<A>::template write_element<1,0>(a)+=mat_traits<B>::template read_element<1,0>(b); 316 mat_traits<A>::template write_element<2,0>(a)+=mat_traits<B>::template read_element<2,0>(b); 317 return a; 318 } 319 320 namespace 321 sfinae 322 { 323 using ::boost::qvm::operator+=; 324 } 325 326 namespace 327 qvm_detail 328 { 329 template <int R,int C> 330 struct plus_eq_mm_defined; 331 332 template <> 333 struct 334 plus_eq_mm_defined<3,1> 335 { 336 static bool const value=true; 337 }; 338 } 339 340 template <class A,class B> 341 BOOST_QVM_INLINE_OPERATIONS 342 typename enable_if_c< 343 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 && 344 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 345 A &>::type operator +=(A & a,B const & b)346 operator+=( A & a, B const & b ) 347 { 348 mat_traits<A>::template write_element<0,0>(a)+=mat_traits<B>::template read_element<0,0>(b); 349 mat_traits<A>::template write_element<0,1>(a)+=mat_traits<B>::template read_element<0,1>(b); 350 mat_traits<A>::template write_element<0,2>(a)+=mat_traits<B>::template read_element<0,2>(b); 351 return a; 352 } 353 354 namespace 355 sfinae 356 { 357 using ::boost::qvm::operator+=; 358 } 359 360 namespace 361 qvm_detail 362 { 363 template <int R,int C> 364 struct plus_eq_mm_defined; 365 366 template <> 367 struct 368 plus_eq_mm_defined<1,3> 369 { 370 static bool const value=true; 371 }; 372 } 373 374 template <class A,class B> 375 BOOST_QVM_INLINE_OPERATIONS 376 typename enable_if_c< 377 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 378 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 379 A &>::type operator -=(A & a,B const & b)380 operator-=( A & a, B const & b ) 381 { 382 mat_traits<A>::template write_element<0,0>(a)-=mat_traits<B>::template read_element<0,0>(b); 383 mat_traits<A>::template write_element<0,1>(a)-=mat_traits<B>::template read_element<0,1>(b); 384 mat_traits<A>::template write_element<0,2>(a)-=mat_traits<B>::template read_element<0,2>(b); 385 mat_traits<A>::template write_element<1,0>(a)-=mat_traits<B>::template read_element<1,0>(b); 386 mat_traits<A>::template write_element<1,1>(a)-=mat_traits<B>::template read_element<1,1>(b); 387 mat_traits<A>::template write_element<1,2>(a)-=mat_traits<B>::template read_element<1,2>(b); 388 mat_traits<A>::template write_element<2,0>(a)-=mat_traits<B>::template read_element<2,0>(b); 389 mat_traits<A>::template write_element<2,1>(a)-=mat_traits<B>::template read_element<2,1>(b); 390 mat_traits<A>::template write_element<2,2>(a)-=mat_traits<B>::template read_element<2,2>(b); 391 return a; 392 } 393 394 namespace 395 sfinae 396 { 397 using ::boost::qvm::operator-=; 398 } 399 400 namespace 401 qvm_detail 402 { 403 template <int R,int C> 404 struct minus_eq_mm_defined; 405 406 template <> 407 struct 408 minus_eq_mm_defined<3,3> 409 { 410 static bool const value=true; 411 }; 412 } 413 414 template <class A,class B> 415 BOOST_QVM_INLINE_OPERATIONS 416 typename enable_if_c< 417 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 418 mat_traits<A>::cols==1 && mat_traits<B>::cols==1, 419 A &>::type operator -=(A & a,B const & b)420 operator-=( A & a, B const & b ) 421 { 422 mat_traits<A>::template write_element<0,0>(a)-=mat_traits<B>::template read_element<0,0>(b); 423 mat_traits<A>::template write_element<1,0>(a)-=mat_traits<B>::template read_element<1,0>(b); 424 mat_traits<A>::template write_element<2,0>(a)-=mat_traits<B>::template read_element<2,0>(b); 425 return a; 426 } 427 428 namespace 429 sfinae 430 { 431 using ::boost::qvm::operator-=; 432 } 433 434 namespace 435 qvm_detail 436 { 437 template <int R,int C> 438 struct minus_eq_mm_defined; 439 440 template <> 441 struct 442 minus_eq_mm_defined<3,1> 443 { 444 static bool const value=true; 445 }; 446 } 447 448 template <class A,class B> 449 BOOST_QVM_INLINE_OPERATIONS 450 typename enable_if_c< 451 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 && 452 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 453 A &>::type operator -=(A & a,B const & b)454 operator-=( A & a, B const & b ) 455 { 456 mat_traits<A>::template write_element<0,0>(a)-=mat_traits<B>::template read_element<0,0>(b); 457 mat_traits<A>::template write_element<0,1>(a)-=mat_traits<B>::template read_element<0,1>(b); 458 mat_traits<A>::template write_element<0,2>(a)-=mat_traits<B>::template read_element<0,2>(b); 459 return a; 460 } 461 462 namespace 463 sfinae 464 { 465 using ::boost::qvm::operator-=; 466 } 467 468 namespace 469 qvm_detail 470 { 471 template <int R,int C> 472 struct minus_eq_mm_defined; 473 474 template <> 475 struct 476 minus_eq_mm_defined<1,3> 477 { 478 static bool const value=true; 479 }; 480 } 481 482 template <class A,class B> 483 BOOST_QVM_INLINE_OPERATIONS 484 typename lazy_enable_if_c< 485 mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value, 486 deduce_mat<A> >::type operator *(A const & a,B b)487 operator*( A const & a, B b ) 488 { 489 typedef typename deduce_mat<A>::type R; 490 R r; 491 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)*b; 492 mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)*b; 493 mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)*b; 494 mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)*b; 495 mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)*b; 496 mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)*b; 497 mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)*b; 498 mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)*b; 499 mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)*b; 500 return r; 501 } 502 503 namespace 504 sfinae 505 { 506 using ::boost::qvm::operator*; 507 } 508 509 namespace 510 qvm_detail 511 { 512 template <int R,int C> 513 struct mul_ms_defined; 514 515 template <> 516 struct 517 mul_ms_defined<3,3> 518 { 519 static bool const value=true; 520 }; 521 } 522 523 template <class A,class B> 524 BOOST_QVM_INLINE_OPERATIONS 525 typename lazy_enable_if_c< 526 is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==3, 527 deduce_mat<B> >::type operator *(A a,B const & b)528 operator*( A a, B const & b ) 529 { 530 typedef typename deduce_mat<B>::type R; 531 R r; 532 mat_traits<R>::template write_element<0,0>(r)=a*mat_traits<B>::template read_element<0,0>(b); 533 mat_traits<R>::template write_element<0,1>(r)=a*mat_traits<B>::template read_element<0,1>(b); 534 mat_traits<R>::template write_element<0,2>(r)=a*mat_traits<B>::template read_element<0,2>(b); 535 mat_traits<R>::template write_element<1,0>(r)=a*mat_traits<B>::template read_element<1,0>(b); 536 mat_traits<R>::template write_element<1,1>(r)=a*mat_traits<B>::template read_element<1,1>(b); 537 mat_traits<R>::template write_element<1,2>(r)=a*mat_traits<B>::template read_element<1,2>(b); 538 mat_traits<R>::template write_element<2,0>(r)=a*mat_traits<B>::template read_element<2,0>(b); 539 mat_traits<R>::template write_element<2,1>(r)=a*mat_traits<B>::template read_element<2,1>(b); 540 mat_traits<R>::template write_element<2,2>(r)=a*mat_traits<B>::template read_element<2,2>(b); 541 return r; 542 } 543 544 namespace 545 sfinae 546 { 547 using ::boost::qvm::operator*; 548 } 549 550 namespace 551 qvm_detail 552 { 553 template <int R,int C> 554 struct mul_sm_defined; 555 556 template <> 557 struct 558 mul_sm_defined<3,3> 559 { 560 static bool const value=true; 561 }; 562 } 563 564 template <class A,class B> 565 BOOST_QVM_INLINE_OPERATIONS 566 typename lazy_enable_if_c< 567 mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value, 568 deduce_mat<A> >::type operator *(A const & a,B b)569 operator*( A const & a, B b ) 570 { 571 typedef typename deduce_mat<A>::type R; 572 R r; 573 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)*b; 574 mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)*b; 575 mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)*b; 576 return r; 577 } 578 579 namespace 580 sfinae 581 { 582 using ::boost::qvm::operator*; 583 } 584 585 namespace 586 qvm_detail 587 { 588 template <int R,int C> 589 struct mul_ms_defined; 590 591 template <> 592 struct 593 mul_ms_defined<3,1> 594 { 595 static bool const value=true; 596 }; 597 } 598 599 template <class A,class B> 600 BOOST_QVM_INLINE_OPERATIONS 601 typename lazy_enable_if_c< 602 is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==1, 603 deduce_mat<B> >::type operator *(A a,B const & b)604 operator*( A a, B const & b ) 605 { 606 typedef typename deduce_mat<B>::type R; 607 R r; 608 mat_traits<R>::template write_element<0,0>(r)=a*mat_traits<B>::template read_element<0,0>(b); 609 mat_traits<R>::template write_element<1,0>(r)=a*mat_traits<B>::template read_element<1,0>(b); 610 mat_traits<R>::template write_element<2,0>(r)=a*mat_traits<B>::template read_element<2,0>(b); 611 return r; 612 } 613 614 namespace 615 sfinae 616 { 617 using ::boost::qvm::operator*; 618 } 619 620 namespace 621 qvm_detail 622 { 623 template <int R,int C> 624 struct mul_sm_defined; 625 626 template <> 627 struct 628 mul_sm_defined<3,1> 629 { 630 static bool const value=true; 631 }; 632 } 633 634 template <class A,class B> 635 BOOST_QVM_INLINE_OPERATIONS 636 typename lazy_enable_if_c< 637 mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value, 638 deduce_mat<A> >::type operator *(A const & a,B b)639 operator*( A const & a, B b ) 640 { 641 typedef typename deduce_mat<A>::type R; 642 R r; 643 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)*b; 644 mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)*b; 645 mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)*b; 646 return r; 647 } 648 649 namespace 650 sfinae 651 { 652 using ::boost::qvm::operator*; 653 } 654 655 namespace 656 qvm_detail 657 { 658 template <int R,int C> 659 struct mul_ms_defined; 660 661 template <> 662 struct 663 mul_ms_defined<1,3> 664 { 665 static bool const value=true; 666 }; 667 } 668 669 template <class A,class B> 670 BOOST_QVM_INLINE_OPERATIONS 671 typename lazy_enable_if_c< 672 is_scalar<A>::value && mat_traits<B>::rows==1 && mat_traits<B>::cols==3, 673 deduce_mat<B> >::type operator *(A a,B const & b)674 operator*( A a, B const & b ) 675 { 676 typedef typename deduce_mat<B>::type R; 677 R r; 678 mat_traits<R>::template write_element<0,0>(r)=a*mat_traits<B>::template read_element<0,0>(b); 679 mat_traits<R>::template write_element<0,1>(r)=a*mat_traits<B>::template read_element<0,1>(b); 680 mat_traits<R>::template write_element<0,2>(r)=a*mat_traits<B>::template read_element<0,2>(b); 681 return r; 682 } 683 684 namespace 685 sfinae 686 { 687 using ::boost::qvm::operator*; 688 } 689 690 namespace 691 qvm_detail 692 { 693 template <int R,int C> 694 struct mul_sm_defined; 695 696 template <> 697 struct 698 mul_sm_defined<1,3> 699 { 700 static bool const value=true; 701 }; 702 } 703 704 template <class A,class B> 705 BOOST_QVM_INLINE_OPERATIONS 706 typename enable_if_c< 707 mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value, 708 A &>::type operator *=(A & a,B b)709 operator*=( A & a, B b ) 710 { 711 mat_traits<A>::template write_element<0,0>(a)*=b; 712 mat_traits<A>::template write_element<0,1>(a)*=b; 713 mat_traits<A>::template write_element<0,2>(a)*=b; 714 mat_traits<A>::template write_element<1,0>(a)*=b; 715 mat_traits<A>::template write_element<1,1>(a)*=b; 716 mat_traits<A>::template write_element<1,2>(a)*=b; 717 mat_traits<A>::template write_element<2,0>(a)*=b; 718 mat_traits<A>::template write_element<2,1>(a)*=b; 719 mat_traits<A>::template write_element<2,2>(a)*=b; 720 return a; 721 } 722 723 namespace 724 sfinae 725 { 726 using ::boost::qvm::operator*=; 727 } 728 729 namespace 730 qvm_detail 731 { 732 template <int R,int C> 733 struct mul_eq_ms_defined; 734 735 template <> 736 struct 737 mul_eq_ms_defined<3,3> 738 { 739 static bool const value=true; 740 }; 741 } 742 743 template <class A,class B> 744 BOOST_QVM_INLINE_OPERATIONS 745 typename enable_if_c< 746 mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value, 747 A &>::type operator *=(A & a,B b)748 operator*=( A & a, B b ) 749 { 750 mat_traits<A>::template write_element<0,0>(a)*=b; 751 mat_traits<A>::template write_element<1,0>(a)*=b; 752 mat_traits<A>::template write_element<2,0>(a)*=b; 753 return a; 754 } 755 756 namespace 757 sfinae 758 { 759 using ::boost::qvm::operator*=; 760 } 761 762 namespace 763 qvm_detail 764 { 765 template <int R,int C> 766 struct mul_eq_ms_defined; 767 768 template <> 769 struct 770 mul_eq_ms_defined<3,1> 771 { 772 static bool const value=true; 773 }; 774 } 775 776 template <class A,class B> 777 BOOST_QVM_INLINE_OPERATIONS 778 typename enable_if_c< 779 mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value, 780 A &>::type operator *=(A & a,B b)781 operator*=( A & a, B b ) 782 { 783 mat_traits<A>::template write_element<0,0>(a)*=b; 784 mat_traits<A>::template write_element<0,1>(a)*=b; 785 mat_traits<A>::template write_element<0,2>(a)*=b; 786 return a; 787 } 788 789 namespace 790 sfinae 791 { 792 using ::boost::qvm::operator*=; 793 } 794 795 namespace 796 qvm_detail 797 { 798 template <int R,int C> 799 struct mul_eq_ms_defined; 800 801 template <> 802 struct 803 mul_eq_ms_defined<1,3> 804 { 805 static bool const value=true; 806 }; 807 } 808 809 template <class A,class B> 810 BOOST_QVM_INLINE_OPERATIONS 811 typename lazy_enable_if_c< 812 mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value, 813 deduce_mat<A> >::type operator /(A const & a,B b)814 operator/( A const & a, B b ) 815 { 816 typedef typename deduce_mat<A>::type R; 817 R r; 818 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)/b; 819 mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)/b; 820 mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)/b; 821 mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)/b; 822 mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)/b; 823 mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)/b; 824 mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)/b; 825 mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)/b; 826 mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)/b; 827 return r; 828 } 829 830 namespace 831 sfinae 832 { 833 using ::boost::qvm::operator/; 834 } 835 836 namespace 837 qvm_detail 838 { 839 template <int R,int C> 840 struct div_ms_defined; 841 842 template <> 843 struct 844 div_ms_defined<3,3> 845 { 846 static bool const value=true; 847 }; 848 } 849 850 template <class A,class B> 851 BOOST_QVM_INLINE_OPERATIONS 852 typename lazy_enable_if_c< 853 is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==3, 854 deduce_mat<B> >::type operator /(A a,B const & b)855 operator/( A a, B const & b ) 856 { 857 typedef typename deduce_mat<B>::type R; 858 R r; 859 mat_traits<R>::template write_element<0,0>(r)=a/mat_traits<B>::template read_element<0,0>(b); 860 mat_traits<R>::template write_element<0,1>(r)=a/mat_traits<B>::template read_element<0,1>(b); 861 mat_traits<R>::template write_element<0,2>(r)=a/mat_traits<B>::template read_element<0,2>(b); 862 mat_traits<R>::template write_element<1,0>(r)=a/mat_traits<B>::template read_element<1,0>(b); 863 mat_traits<R>::template write_element<1,1>(r)=a/mat_traits<B>::template read_element<1,1>(b); 864 mat_traits<R>::template write_element<1,2>(r)=a/mat_traits<B>::template read_element<1,2>(b); 865 mat_traits<R>::template write_element<2,0>(r)=a/mat_traits<B>::template read_element<2,0>(b); 866 mat_traits<R>::template write_element<2,1>(r)=a/mat_traits<B>::template read_element<2,1>(b); 867 mat_traits<R>::template write_element<2,2>(r)=a/mat_traits<B>::template read_element<2,2>(b); 868 return r; 869 } 870 871 namespace 872 sfinae 873 { 874 using ::boost::qvm::operator/; 875 } 876 877 namespace 878 qvm_detail 879 { 880 template <int R,int C> 881 struct div_sm_defined; 882 883 template <> 884 struct 885 div_sm_defined<3,3> 886 { 887 static bool const value=true; 888 }; 889 } 890 891 template <class A,class B> 892 BOOST_QVM_INLINE_OPERATIONS 893 typename lazy_enable_if_c< 894 mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value, 895 deduce_mat<A> >::type operator /(A const & a,B b)896 operator/( A const & a, B b ) 897 { 898 typedef typename deduce_mat<A>::type R; 899 R r; 900 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)/b; 901 mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)/b; 902 mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)/b; 903 return r; 904 } 905 906 namespace 907 sfinae 908 { 909 using ::boost::qvm::operator/; 910 } 911 912 namespace 913 qvm_detail 914 { 915 template <int R,int C> 916 struct div_ms_defined; 917 918 template <> 919 struct 920 div_ms_defined<3,1> 921 { 922 static bool const value=true; 923 }; 924 } 925 926 template <class A,class B> 927 BOOST_QVM_INLINE_OPERATIONS 928 typename lazy_enable_if_c< 929 is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==1, 930 deduce_mat<B> >::type operator /(A a,B const & b)931 operator/( A a, B const & b ) 932 { 933 typedef typename deduce_mat<B>::type R; 934 R r; 935 mat_traits<R>::template write_element<0,0>(r)=a/mat_traits<B>::template read_element<0,0>(b); 936 mat_traits<R>::template write_element<1,0>(r)=a/mat_traits<B>::template read_element<1,0>(b); 937 mat_traits<R>::template write_element<2,0>(r)=a/mat_traits<B>::template read_element<2,0>(b); 938 return r; 939 } 940 941 namespace 942 sfinae 943 { 944 using ::boost::qvm::operator/; 945 } 946 947 namespace 948 qvm_detail 949 { 950 template <int R,int C> 951 struct div_sm_defined; 952 953 template <> 954 struct 955 div_sm_defined<3,1> 956 { 957 static bool const value=true; 958 }; 959 } 960 961 template <class A,class B> 962 BOOST_QVM_INLINE_OPERATIONS 963 typename lazy_enable_if_c< 964 mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value, 965 deduce_mat<A> >::type operator /(A const & a,B b)966 operator/( A const & a, B b ) 967 { 968 typedef typename deduce_mat<A>::type R; 969 R r; 970 mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)/b; 971 mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)/b; 972 mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)/b; 973 return r; 974 } 975 976 namespace 977 sfinae 978 { 979 using ::boost::qvm::operator/; 980 } 981 982 namespace 983 qvm_detail 984 { 985 template <int R,int C> 986 struct div_ms_defined; 987 988 template <> 989 struct 990 div_ms_defined<1,3> 991 { 992 static bool const value=true; 993 }; 994 } 995 996 template <class A,class B> 997 BOOST_QVM_INLINE_OPERATIONS 998 typename enable_if_c< 999 mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value, 1000 A &>::type operator /=(A & a,B b)1001 operator/=( A & a, B b ) 1002 { 1003 mat_traits<A>::template write_element<0,0>(a)/=b; 1004 mat_traits<A>::template write_element<0,1>(a)/=b; 1005 mat_traits<A>::template write_element<0,2>(a)/=b; 1006 mat_traits<A>::template write_element<1,0>(a)/=b; 1007 mat_traits<A>::template write_element<1,1>(a)/=b; 1008 mat_traits<A>::template write_element<1,2>(a)/=b; 1009 mat_traits<A>::template write_element<2,0>(a)/=b; 1010 mat_traits<A>::template write_element<2,1>(a)/=b; 1011 mat_traits<A>::template write_element<2,2>(a)/=b; 1012 return a; 1013 } 1014 1015 namespace 1016 sfinae 1017 { 1018 using ::boost::qvm::operator/=; 1019 } 1020 1021 namespace 1022 qvm_detail 1023 { 1024 template <int R,int C> 1025 struct div_eq_ms_defined; 1026 1027 template <> 1028 struct 1029 div_eq_ms_defined<3,3> 1030 { 1031 static bool const value=true; 1032 }; 1033 } 1034 1035 template <class A,class B> 1036 BOOST_QVM_INLINE_OPERATIONS 1037 typename enable_if_c< 1038 mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value, 1039 A &>::type operator /=(A & a,B b)1040 operator/=( A & a, B b ) 1041 { 1042 mat_traits<A>::template write_element<0,0>(a)/=b; 1043 mat_traits<A>::template write_element<1,0>(a)/=b; 1044 mat_traits<A>::template write_element<2,0>(a)/=b; 1045 return a; 1046 } 1047 1048 namespace 1049 sfinae 1050 { 1051 using ::boost::qvm::operator/=; 1052 } 1053 1054 namespace 1055 qvm_detail 1056 { 1057 template <int R,int C> 1058 struct div_eq_ms_defined; 1059 1060 template <> 1061 struct 1062 div_eq_ms_defined<3,1> 1063 { 1064 static bool const value=true; 1065 }; 1066 } 1067 1068 template <class A,class B> 1069 BOOST_QVM_INLINE_OPERATIONS 1070 typename enable_if_c< 1071 mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value, 1072 A &>::type operator /=(A & a,B b)1073 operator/=( A & a, B b ) 1074 { 1075 mat_traits<A>::template write_element<0,0>(a)/=b; 1076 mat_traits<A>::template write_element<0,1>(a)/=b; 1077 mat_traits<A>::template write_element<0,2>(a)/=b; 1078 return a; 1079 } 1080 1081 namespace 1082 sfinae 1083 { 1084 using ::boost::qvm::operator/=; 1085 } 1086 1087 namespace 1088 qvm_detail 1089 { 1090 template <int R,int C> 1091 struct div_eq_ms_defined; 1092 1093 template <> 1094 struct 1095 div_eq_ms_defined<1,3> 1096 { 1097 static bool const value=true; 1098 }; 1099 } 1100 1101 template <class R,class A> 1102 BOOST_QVM_INLINE_OPERATIONS 1103 typename enable_if_c< 1104 mat_traits<R>::rows==3 && mat_traits<A>::rows==3 && 1105 mat_traits<R>::cols==3 && mat_traits<A>::cols==3, 1106 R>::type convert_to(A const & a)1107 convert_to( A const & a ) 1108 { 1109 R r; 1110 mat_traits<R>::template write_element<0,0>(r) = mat_traits<A>::template read_element<0,0>(a); 1111 mat_traits<R>::template write_element<0,1>(r) = mat_traits<A>::template read_element<0,1>(a); 1112 mat_traits<R>::template write_element<0,2>(r) = mat_traits<A>::template read_element<0,2>(a); 1113 mat_traits<R>::template write_element<1,0>(r) = mat_traits<A>::template read_element<1,0>(a); 1114 mat_traits<R>::template write_element<1,1>(r) = mat_traits<A>::template read_element<1,1>(a); 1115 mat_traits<R>::template write_element<1,2>(r) = mat_traits<A>::template read_element<1,2>(a); 1116 mat_traits<R>::template write_element<2,0>(r) = mat_traits<A>::template read_element<2,0>(a); 1117 mat_traits<R>::template write_element<2,1>(r) = mat_traits<A>::template read_element<2,1>(a); 1118 mat_traits<R>::template write_element<2,2>(r) = mat_traits<A>::template read_element<2,2>(a); 1119 return r; 1120 } 1121 1122 template <class R,class A> 1123 BOOST_QVM_INLINE 1124 typename enable_if_c< 1125 is_mat<R>::value && is_quat<A>::value && 1126 mat_traits<R>::rows==3 && mat_traits<R>::cols==3, 1127 R>::type convert_to(A const & q)1128 convert_to( A const & q ) 1129 { 1130 typedef typename mat_traits<R>::scalar_type T; 1131 T const a=quat_traits<A>::template read_element<0>(q); 1132 T const b=quat_traits<A>::template read_element<1>(q); 1133 T const c=quat_traits<A>::template read_element<2>(q); 1134 T const d=quat_traits<A>::template read_element<3>(q); 1135 T const bb = b*b; 1136 T const cc = c*c; 1137 T const dd = d*d; 1138 T const bc = b*c; 1139 T const bd = b*d; 1140 T const cd = c*d; 1141 T const ab = a*b; 1142 T const ac = a*c; 1143 T const ad = a*d; 1144 T const one = scalar_traits<T>::value(1); 1145 T const two = one+one; 1146 R r; 1147 mat_traits<R>::template write_element<0,0>(r) = one - two*(cc+dd); 1148 mat_traits<R>::template write_element<0,1>(r) = two*(bc-ad); 1149 mat_traits<R>::template write_element<0,2>(r) = two*(bd+ac); 1150 mat_traits<R>::template write_element<1,0>(r) = two*(bc+ad); 1151 mat_traits<R>::template write_element<1,1>(r) = one - two*(bb+dd); 1152 mat_traits<R>::template write_element<1,2>(r) = two*(cd-ab); 1153 mat_traits<R>::template write_element<2,0>(r) = two*(bd-ac); 1154 mat_traits<R>::template write_element<2,1>(r) = two*(cd+ab); 1155 mat_traits<R>::template write_element<2,2>(r) = one - two*(bb+cc); 1156 return r; 1157 } 1158 1159 namespace 1160 sfinae 1161 { 1162 using ::boost::qvm::convert_to; 1163 } 1164 1165 namespace 1166 qvm_detail 1167 { 1168 template <int R,int C> 1169 struct convert_to_m_defined; 1170 1171 template <> 1172 struct 1173 convert_to_m_defined<3,3> 1174 { 1175 static bool const value=true; 1176 }; 1177 } 1178 1179 template <class R,class A> 1180 BOOST_QVM_INLINE_OPERATIONS 1181 typename enable_if_c< 1182 mat_traits<R>::rows==3 && mat_traits<A>::rows==3 && 1183 mat_traits<R>::cols==1 && mat_traits<A>::cols==1, 1184 R>::type convert_to(A const & a)1185 convert_to( A const & a ) 1186 { 1187 R r; 1188 mat_traits<R>::template write_element<0,0>(r) = mat_traits<A>::template read_element<0,0>(a); 1189 mat_traits<R>::template write_element<1,0>(r) = mat_traits<A>::template read_element<1,0>(a); 1190 mat_traits<R>::template write_element<2,0>(r) = mat_traits<A>::template read_element<2,0>(a); 1191 return r; 1192 } 1193 1194 namespace 1195 sfinae 1196 { 1197 using ::boost::qvm::convert_to; 1198 } 1199 1200 namespace 1201 qvm_detail 1202 { 1203 template <int R,int C> 1204 struct convert_to_m_defined; 1205 1206 template <> 1207 struct 1208 convert_to_m_defined<3,1> 1209 { 1210 static bool const value=true; 1211 }; 1212 } 1213 1214 template <class R,class A> 1215 BOOST_QVM_INLINE_OPERATIONS 1216 typename enable_if_c< 1217 mat_traits<R>::rows==1 && mat_traits<A>::rows==1 && 1218 mat_traits<R>::cols==3 && mat_traits<A>::cols==3, 1219 R>::type convert_to(A const & a)1220 convert_to( A const & a ) 1221 { 1222 R r; 1223 mat_traits<R>::template write_element<0,0>(r) = mat_traits<A>::template read_element<0,0>(a); 1224 mat_traits<R>::template write_element<0,1>(r) = mat_traits<A>::template read_element<0,1>(a); 1225 mat_traits<R>::template write_element<0,2>(r) = mat_traits<A>::template read_element<0,2>(a); 1226 return r; 1227 } 1228 1229 namespace 1230 sfinae 1231 { 1232 using ::boost::qvm::convert_to; 1233 } 1234 1235 namespace 1236 qvm_detail 1237 { 1238 template <int R,int C> 1239 struct convert_to_m_defined; 1240 1241 template <> 1242 struct 1243 convert_to_m_defined<1,3> 1244 { 1245 static bool const value=true; 1246 }; 1247 } 1248 1249 template <class A,class B> 1250 BOOST_QVM_INLINE_OPERATIONS 1251 typename enable_if_c< 1252 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 1253 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 1254 bool>::type operator ==(A const & a,B const & b)1255 operator==( A const & a, B const & b ) 1256 { 1257 return 1258 mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) && 1259 mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) && 1260 mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b) && 1261 mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) && 1262 mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b) && 1263 mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b) && 1264 mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b) && 1265 mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b) && 1266 mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b); 1267 } 1268 1269 namespace 1270 sfinae 1271 { 1272 using ::boost::qvm::operator==; 1273 } 1274 1275 namespace 1276 qvm_detail 1277 { 1278 template <int R,int C> 1279 struct eq_mm_defined; 1280 1281 template <> 1282 struct 1283 eq_mm_defined<3,3> 1284 { 1285 static bool const value=true; 1286 }; 1287 } 1288 1289 template <class A,class B> 1290 BOOST_QVM_INLINE_OPERATIONS 1291 typename enable_if_c< 1292 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 1293 mat_traits<A>::cols==1 && mat_traits<B>::cols==1, 1294 bool>::type operator ==(A const & a,B const & b)1295 operator==( A const & a, B const & b ) 1296 { 1297 return 1298 mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) && 1299 mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) && 1300 mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b); 1301 } 1302 1303 namespace 1304 sfinae 1305 { 1306 using ::boost::qvm::operator==; 1307 } 1308 1309 namespace 1310 qvm_detail 1311 { 1312 template <int R,int C> 1313 struct eq_mm_defined; 1314 1315 template <> 1316 struct 1317 eq_mm_defined<3,1> 1318 { 1319 static bool const value=true; 1320 }; 1321 } 1322 1323 template <class A,class B> 1324 BOOST_QVM_INLINE_OPERATIONS 1325 typename enable_if_c< 1326 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 && 1327 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 1328 bool>::type operator ==(A const & a,B const & b)1329 operator==( A const & a, B const & b ) 1330 { 1331 return 1332 mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) && 1333 mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) && 1334 mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b); 1335 } 1336 1337 namespace 1338 sfinae 1339 { 1340 using ::boost::qvm::operator==; 1341 } 1342 1343 namespace 1344 qvm_detail 1345 { 1346 template <int R,int C> 1347 struct eq_mm_defined; 1348 1349 template <> 1350 struct 1351 eq_mm_defined<1,3> 1352 { 1353 static bool const value=true; 1354 }; 1355 } 1356 1357 template <class A,class B> 1358 BOOST_QVM_INLINE_OPERATIONS 1359 typename enable_if_c< 1360 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 1361 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 1362 bool>::type operator !=(A const & a,B const & b)1363 operator!=( A const & a, B const & b ) 1364 { 1365 return 1366 !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) || 1367 !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) || 1368 !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b)) || 1369 !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) || 1370 !(mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b)) || 1371 !(mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b)) || 1372 !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b)) || 1373 !(mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b)) || 1374 !(mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b)); 1375 } 1376 1377 namespace 1378 sfinae 1379 { 1380 using ::boost::qvm::operator!=; 1381 } 1382 1383 namespace 1384 qvm_detail 1385 { 1386 template <int R,int C> 1387 struct neq_mm_defined; 1388 1389 template <> 1390 struct 1391 neq_mm_defined<3,3> 1392 { 1393 static bool const value=true; 1394 }; 1395 } 1396 1397 template <class A,class B> 1398 BOOST_QVM_INLINE_OPERATIONS 1399 typename enable_if_c< 1400 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 1401 mat_traits<A>::cols==1 && mat_traits<B>::cols==1, 1402 bool>::type operator !=(A const & a,B const & b)1403 operator!=( A const & a, B const & b ) 1404 { 1405 return 1406 !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) || 1407 !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) || 1408 !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b)); 1409 } 1410 1411 namespace 1412 sfinae 1413 { 1414 using ::boost::qvm::operator!=; 1415 } 1416 1417 namespace 1418 qvm_detail 1419 { 1420 template <int R,int C> 1421 struct neq_mm_defined; 1422 1423 template <> 1424 struct 1425 neq_mm_defined<3,1> 1426 { 1427 static bool const value=true; 1428 }; 1429 } 1430 1431 template <class A,class B> 1432 BOOST_QVM_INLINE_OPERATIONS 1433 typename enable_if_c< 1434 mat_traits<A>::rows==1 && mat_traits<B>::rows==1 && 1435 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 1436 bool>::type operator !=(A const & a,B const & b)1437 operator!=( A const & a, B const & b ) 1438 { 1439 return 1440 !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) || 1441 !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) || 1442 !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b)); 1443 } 1444 1445 namespace 1446 sfinae 1447 { 1448 using ::boost::qvm::operator!=; 1449 } 1450 1451 namespace 1452 qvm_detail 1453 { 1454 template <int R,int C> 1455 struct neq_mm_defined; 1456 1457 template <> 1458 struct 1459 neq_mm_defined<1,3> 1460 { 1461 static bool const value=true; 1462 }; 1463 } 1464 1465 template <class A> 1466 BOOST_QVM_INLINE_OPERATIONS 1467 typename lazy_enable_if_c< 1468 mat_traits<A>::rows==3 && mat_traits<A>::cols==3, 1469 deduce_mat<A> >::type operator -(A const & a)1470 operator-( A const & a ) 1471 { 1472 typedef typename deduce_mat<A>::type R; 1473 R r; 1474 mat_traits<R>::template write_element<0,0>(r)=-mat_traits<A>::template read_element<0,0>(a); 1475 mat_traits<R>::template write_element<0,1>(r)=-mat_traits<A>::template read_element<0,1>(a); 1476 mat_traits<R>::template write_element<0,2>(r)=-mat_traits<A>::template read_element<0,2>(a); 1477 mat_traits<R>::template write_element<1,0>(r)=-mat_traits<A>::template read_element<1,0>(a); 1478 mat_traits<R>::template write_element<1,1>(r)=-mat_traits<A>::template read_element<1,1>(a); 1479 mat_traits<R>::template write_element<1,2>(r)=-mat_traits<A>::template read_element<1,2>(a); 1480 mat_traits<R>::template write_element<2,0>(r)=-mat_traits<A>::template read_element<2,0>(a); 1481 mat_traits<R>::template write_element<2,1>(r)=-mat_traits<A>::template read_element<2,1>(a); 1482 mat_traits<R>::template write_element<2,2>(r)=-mat_traits<A>::template read_element<2,2>(a); 1483 return r; 1484 } 1485 1486 namespace 1487 sfinae 1488 { 1489 using ::boost::qvm::operator-; 1490 } 1491 1492 namespace 1493 qvm_detail 1494 { 1495 template <int R,int C> 1496 struct minus_m_defined; 1497 1498 template <> 1499 struct 1500 minus_m_defined<3,3> 1501 { 1502 static bool const value=true; 1503 }; 1504 } 1505 1506 template <class A> 1507 BOOST_QVM_INLINE_OPERATIONS 1508 typename lazy_enable_if_c< 1509 mat_traits<A>::rows==3 && mat_traits<A>::cols==1, 1510 deduce_mat<A> >::type operator -(A const & a)1511 operator-( A const & a ) 1512 { 1513 typedef typename deduce_mat<A>::type R; 1514 R r; 1515 mat_traits<R>::template write_element<0,0>(r)=-mat_traits<A>::template read_element<0,0>(a); 1516 mat_traits<R>::template write_element<1,0>(r)=-mat_traits<A>::template read_element<1,0>(a); 1517 mat_traits<R>::template write_element<2,0>(r)=-mat_traits<A>::template read_element<2,0>(a); 1518 return r; 1519 } 1520 1521 namespace 1522 sfinae 1523 { 1524 using ::boost::qvm::operator-; 1525 } 1526 1527 namespace 1528 qvm_detail 1529 { 1530 template <int R,int C> 1531 struct minus_m_defined; 1532 1533 template <> 1534 struct 1535 minus_m_defined<3,1> 1536 { 1537 static bool const value=true; 1538 }; 1539 } 1540 1541 template <class A> 1542 BOOST_QVM_INLINE_OPERATIONS 1543 typename lazy_enable_if_c< 1544 mat_traits<A>::rows==1 && mat_traits<A>::cols==3, 1545 deduce_mat<A> >::type operator -(A const & a)1546 operator-( A const & a ) 1547 { 1548 typedef typename deduce_mat<A>::type R; 1549 R r; 1550 mat_traits<R>::template write_element<0,0>(r)=-mat_traits<A>::template read_element<0,0>(a); 1551 mat_traits<R>::template write_element<0,1>(r)=-mat_traits<A>::template read_element<0,1>(a); 1552 mat_traits<R>::template write_element<0,2>(r)=-mat_traits<A>::template read_element<0,2>(a); 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 C> 1566 struct minus_m_defined; 1567 1568 template <> 1569 struct 1570 minus_m_defined<1,3> 1571 { 1572 static bool const value=true; 1573 }; 1574 } 1575 1576 template <class A> 1577 BOOST_QVM_INLINE_OPERATIONS 1578 typename enable_if_c< 1579 mat_traits<A>::rows==3 && mat_traits<A>::cols==3, 1580 typename mat_traits<A>::scalar_type>::type determinant(A const & a)1581 determinant( A const & a ) 1582 { 1583 typedef typename mat_traits<A>::scalar_type T; 1584 T const a00=mat_traits<A>::template read_element<0,0>(a); 1585 T const a01=mat_traits<A>::template read_element<0,1>(a); 1586 T const a02=mat_traits<A>::template read_element<0,2>(a); 1587 T const a10=mat_traits<A>::template read_element<1,0>(a); 1588 T const a11=mat_traits<A>::template read_element<1,1>(a); 1589 T const a12=mat_traits<A>::template read_element<1,2>(a); 1590 T const a20=mat_traits<A>::template read_element<2,0>(a); 1591 T const a21=mat_traits<A>::template read_element<2,1>(a); 1592 T const a22=mat_traits<A>::template read_element<2,2>(a); 1593 T det=(a00*(a11*a22-a12*a21)-a01*(a10*a22-a12*a20)+a02*(a10*a21-a11*a20)); 1594 return det; 1595 } 1596 1597 namespace 1598 sfinae 1599 { 1600 using ::boost::qvm::determinant; 1601 } 1602 1603 namespace 1604 qvm_detail 1605 { 1606 template <int D> 1607 struct determinant_defined; 1608 1609 template <> 1610 struct 1611 determinant_defined<3> 1612 { 1613 static bool const value=true; 1614 }; 1615 } 1616 1617 template <class A,class B> 1618 BOOST_QVM_INLINE_OPERATIONS 1619 typename lazy_enable_if_c< 1620 mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value, 1621 deduce_mat<A> >::type inverse(A const & a,B det)1622 inverse( A const & a, B det ) 1623 { 1624 typedef typename mat_traits<A>::scalar_type T; 1625 BOOST_QVM_ASSERT(det!=scalar_traits<B>::value(0)); 1626 T const a00=mat_traits<A>::template read_element<0,0>(a); 1627 T const a01=mat_traits<A>::template read_element<0,1>(a); 1628 T const a02=mat_traits<A>::template read_element<0,2>(a); 1629 T const a10=mat_traits<A>::template read_element<1,0>(a); 1630 T const a11=mat_traits<A>::template read_element<1,1>(a); 1631 T const a12=mat_traits<A>::template read_element<1,2>(a); 1632 T const a20=mat_traits<A>::template read_element<2,0>(a); 1633 T const a21=mat_traits<A>::template read_element<2,1>(a); 1634 T const a22=mat_traits<A>::template read_element<2,2>(a); 1635 T const f=scalar_traits<T>::value(1)/det; 1636 typedef typename deduce_mat<A>::type R; 1637 R r; 1638 mat_traits<R>::template write_element<0,0>(r)= f*(a11*a22-a12*a21); 1639 mat_traits<R>::template write_element<0,1>(r)=-f*(a01*a22-a02*a21); 1640 mat_traits<R>::template write_element<0,2>(r)= f*(a01*a12-a02*a11); 1641 mat_traits<R>::template write_element<1,0>(r)=-f*(a10*a22-a12*a20); 1642 mat_traits<R>::template write_element<1,1>(r)= f*(a00*a22-a02*a20); 1643 mat_traits<R>::template write_element<1,2>(r)=-f*(a00*a12-a02*a10); 1644 mat_traits<R>::template write_element<2,0>(r)= f*(a10*a21-a11*a20); 1645 mat_traits<R>::template write_element<2,1>(r)=-f*(a00*a21-a01*a20); 1646 mat_traits<R>::template write_element<2,2>(r)= f*(a00*a11-a01*a10); 1647 return r; 1648 } 1649 1650 template <class A> 1651 BOOST_QVM_INLINE_OPERATIONS 1652 typename lazy_enable_if_c< 1653 mat_traits<A>::rows==3 && mat_traits<A>::cols==3, 1654 deduce_mat<A> >::type inverse(A const & a)1655 inverse( A const & a ) 1656 { 1657 typedef typename mat_traits<A>::scalar_type T; 1658 T det=determinant(a); 1659 if( det==scalar_traits<T>::value(0) ) 1660 BOOST_QVM_THROW_EXCEPTION(zero_determinant_error()); 1661 return inverse(a,det); 1662 } 1663 1664 namespace 1665 sfinae 1666 { 1667 using ::boost::qvm::inverse; 1668 } 1669 1670 namespace 1671 qvm_detail 1672 { 1673 template <int D> 1674 struct inverse_m_defined; 1675 1676 template <> 1677 struct 1678 inverse_m_defined<3> 1679 { 1680 static bool const value=true; 1681 }; 1682 } 1683 1684 template <class A,class B> 1685 BOOST_QVM_INLINE_OPERATIONS 1686 typename lazy_enable_if_c< 1687 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 1688 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 1689 deduce_mat2<A,B,3,3> >::type operator *(A const & a,B const & b)1690 operator*( A const & a, B const & b ) 1691 { 1692 typedef typename mat_traits<A>::scalar_type Ta; 1693 typedef typename mat_traits<B>::scalar_type Tb; 1694 Ta const a00 = mat_traits<A>::template read_element<0,0>(a); 1695 Ta const a01 = mat_traits<A>::template read_element<0,1>(a); 1696 Ta const a02 = mat_traits<A>::template read_element<0,2>(a); 1697 Ta const a10 = mat_traits<A>::template read_element<1,0>(a); 1698 Ta const a11 = mat_traits<A>::template read_element<1,1>(a); 1699 Ta const a12 = mat_traits<A>::template read_element<1,2>(a); 1700 Ta const a20 = mat_traits<A>::template read_element<2,0>(a); 1701 Ta const a21 = mat_traits<A>::template read_element<2,1>(a); 1702 Ta const a22 = mat_traits<A>::template read_element<2,2>(a); 1703 Tb const b00 = mat_traits<B>::template read_element<0,0>(b); 1704 Tb const b01 = mat_traits<B>::template read_element<0,1>(b); 1705 Tb const b02 = mat_traits<B>::template read_element<0,2>(b); 1706 Tb const b10 = mat_traits<B>::template read_element<1,0>(b); 1707 Tb const b11 = mat_traits<B>::template read_element<1,1>(b); 1708 Tb const b12 = mat_traits<B>::template read_element<1,2>(b); 1709 Tb const b20 = mat_traits<B>::template read_element<2,0>(b); 1710 Tb const b21 = mat_traits<B>::template read_element<2,1>(b); 1711 Tb const b22 = mat_traits<B>::template read_element<2,2>(b); 1712 typedef typename deduce_mat2<A,B,3,3>::type R; 1713 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3); 1714 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3); 1715 R r; 1716 mat_traits<R>::template write_element<0,0>(r)=a00*b00+a01*b10+a02*b20; 1717 mat_traits<R>::template write_element<0,1>(r)=a00*b01+a01*b11+a02*b21; 1718 mat_traits<R>::template write_element<0,2>(r)=a00*b02+a01*b12+a02*b22; 1719 mat_traits<R>::template write_element<1,0>(r)=a10*b00+a11*b10+a12*b20; 1720 mat_traits<R>::template write_element<1,1>(r)=a10*b01+a11*b11+a12*b21; 1721 mat_traits<R>::template write_element<1,2>(r)=a10*b02+a11*b12+a12*b22; 1722 mat_traits<R>::template write_element<2,0>(r)=a20*b00+a21*b10+a22*b20; 1723 mat_traits<R>::template write_element<2,1>(r)=a20*b01+a21*b11+a22*b21; 1724 mat_traits<R>::template write_element<2,2>(r)=a20*b02+a21*b12+a22*b22; 1725 return r; 1726 } 1727 1728 namespace 1729 sfinae 1730 { 1731 using ::boost::qvm::operator*; 1732 } 1733 1734 namespace 1735 qvm_detail 1736 { 1737 template <int R,int /*CR*/,int C> 1738 struct mul_mm_defined; 1739 1740 template <> 1741 struct 1742 mul_mm_defined<3,3,3> 1743 { 1744 static bool const value=true; 1745 }; 1746 } 1747 1748 template <class A,class B> 1749 BOOST_QVM_INLINE_OPERATIONS 1750 typename enable_if_c< 1751 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 1752 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 1753 A &>::type operator *=(A & a,B const & b)1754 operator*=( A & a, B const & b ) 1755 { 1756 typedef typename mat_traits<A>::scalar_type Ta; 1757 typedef typename mat_traits<B>::scalar_type Tb; 1758 Ta const a00 = mat_traits<A>::template read_element<0,0>(a); 1759 Ta const a01 = mat_traits<A>::template read_element<0,1>(a); 1760 Ta const a02 = mat_traits<A>::template read_element<0,2>(a); 1761 Ta const a10 = mat_traits<A>::template read_element<1,0>(a); 1762 Ta const a11 = mat_traits<A>::template read_element<1,1>(a); 1763 Ta const a12 = mat_traits<A>::template read_element<1,2>(a); 1764 Ta const a20 = mat_traits<A>::template read_element<2,0>(a); 1765 Ta const a21 = mat_traits<A>::template read_element<2,1>(a); 1766 Ta const a22 = mat_traits<A>::template read_element<2,2>(a); 1767 Tb const b00 = mat_traits<B>::template read_element<0,0>(b); 1768 Tb const b01 = mat_traits<B>::template read_element<0,1>(b); 1769 Tb const b02 = mat_traits<B>::template read_element<0,2>(b); 1770 Tb const b10 = mat_traits<B>::template read_element<1,0>(b); 1771 Tb const b11 = mat_traits<B>::template read_element<1,1>(b); 1772 Tb const b12 = mat_traits<B>::template read_element<1,2>(b); 1773 Tb const b20 = mat_traits<B>::template read_element<2,0>(b); 1774 Tb const b21 = mat_traits<B>::template read_element<2,1>(b); 1775 Tb const b22 = mat_traits<B>::template read_element<2,2>(b); 1776 mat_traits<A>::template write_element<0,0>(a)=a00*b00+a01*b10+a02*b20; 1777 mat_traits<A>::template write_element<0,1>(a)=a00*b01+a01*b11+a02*b21; 1778 mat_traits<A>::template write_element<0,2>(a)=a00*b02+a01*b12+a02*b22; 1779 mat_traits<A>::template write_element<1,0>(a)=a10*b00+a11*b10+a12*b20; 1780 mat_traits<A>::template write_element<1,1>(a)=a10*b01+a11*b11+a12*b21; 1781 mat_traits<A>::template write_element<1,2>(a)=a10*b02+a11*b12+a12*b22; 1782 mat_traits<A>::template write_element<2,0>(a)=a20*b00+a21*b10+a22*b20; 1783 mat_traits<A>::template write_element<2,1>(a)=a20*b01+a21*b11+a22*b21; 1784 mat_traits<A>::template write_element<2,2>(a)=a20*b02+a21*b12+a22*b22; 1785 return a; 1786 } 1787 1788 namespace 1789 sfinae 1790 { 1791 using ::boost::qvm::operator*=; 1792 } 1793 1794 namespace 1795 qvm_detail 1796 { 1797 template <int D> 1798 struct mul_eq_mm_defined; 1799 1800 template <> 1801 struct 1802 mul_eq_mm_defined<3> 1803 { 1804 static bool const value=true; 1805 }; 1806 } 1807 1808 template <class A,class B> 1809 BOOST_QVM_INLINE_OPERATIONS 1810 typename lazy_enable_if_c< 1811 mat_traits<A>::rows==3 && mat_traits<B>::rows==3 && 1812 mat_traits<A>::cols==3 && mat_traits<B>::cols==1, 1813 deduce_mat2<A,B,3,1> >::type operator *(A const & a,B const & b)1814 operator*( A const & a, B const & b ) 1815 { 1816 typedef typename mat_traits<A>::scalar_type Ta; 1817 typedef typename mat_traits<B>::scalar_type Tb; 1818 Ta const a00 = mat_traits<A>::template read_element<0,0>(a); 1819 Ta const a01 = mat_traits<A>::template read_element<0,1>(a); 1820 Ta const a02 = mat_traits<A>::template read_element<0,2>(a); 1821 Ta const a10 = mat_traits<A>::template read_element<1,0>(a); 1822 Ta const a11 = mat_traits<A>::template read_element<1,1>(a); 1823 Ta const a12 = mat_traits<A>::template read_element<1,2>(a); 1824 Ta const a20 = mat_traits<A>::template read_element<2,0>(a); 1825 Ta const a21 = mat_traits<A>::template read_element<2,1>(a); 1826 Ta const a22 = mat_traits<A>::template read_element<2,2>(a); 1827 Tb const b00 = mat_traits<B>::template read_element<0,0>(b); 1828 Tb const b10 = mat_traits<B>::template read_element<1,0>(b); 1829 Tb const b20 = mat_traits<B>::template read_element<2,0>(b); 1830 typedef typename deduce_mat2<A,B,3,1>::type R; 1831 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3); 1832 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1); 1833 R r; 1834 mat_traits<R>::template write_element<0,0>(r)=a00*b00+a01*b10+a02*b20; 1835 mat_traits<R>::template write_element<1,0>(r)=a10*b00+a11*b10+a12*b20; 1836 mat_traits<R>::template write_element<2,0>(r)=a20*b00+a21*b10+a22*b20; 1837 return r; 1838 } 1839 1840 namespace 1841 sfinae 1842 { 1843 using ::boost::qvm::operator*; 1844 } 1845 1846 namespace 1847 qvm_detail 1848 { 1849 template <int R,int /*CR*/,int C> 1850 struct mul_mm_defined; 1851 1852 template <> 1853 struct 1854 mul_mm_defined<3,3,1> 1855 { 1856 static bool const value=true; 1857 }; 1858 } 1859 1860 template <class A,class B> 1861 BOOST_QVM_INLINE_OPERATIONS 1862 typename lazy_enable_if_c< 1863 mat_traits<A>::rows==1 && mat_traits<B>::rows==3 && 1864 mat_traits<A>::cols==3 && mat_traits<B>::cols==3, 1865 deduce_mat2<A,B,1,3> >::type operator *(A const & a,B const & b)1866 operator*( A const & a, B const & b ) 1867 { 1868 typedef typename mat_traits<A>::scalar_type Ta; 1869 typedef typename mat_traits<B>::scalar_type Tb; 1870 Ta const a00 = mat_traits<A>::template read_element<0,0>(a); 1871 Ta const a01 = mat_traits<A>::template read_element<0,1>(a); 1872 Ta const a02 = mat_traits<A>::template read_element<0,2>(a); 1873 Tb const b00 = mat_traits<B>::template read_element<0,0>(b); 1874 Tb const b01 = mat_traits<B>::template read_element<0,1>(b); 1875 Tb const b02 = mat_traits<B>::template read_element<0,2>(b); 1876 Tb const b10 = mat_traits<B>::template read_element<1,0>(b); 1877 Tb const b11 = mat_traits<B>::template read_element<1,1>(b); 1878 Tb const b12 = mat_traits<B>::template read_element<1,2>(b); 1879 Tb const b20 = mat_traits<B>::template read_element<2,0>(b); 1880 Tb const b21 = mat_traits<B>::template read_element<2,1>(b); 1881 Tb const b22 = mat_traits<B>::template read_element<2,2>(b); 1882 typedef typename deduce_mat2<A,B,1,3>::type R; 1883 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1); 1884 BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3); 1885 R r; 1886 mat_traits<R>::template write_element<0,0>(r)=a00*b00+a01*b10+a02*b20; 1887 mat_traits<R>::template write_element<0,1>(r)=a00*b01+a01*b11+a02*b21; 1888 mat_traits<R>::template write_element<0,2>(r)=a00*b02+a01*b12+a02*b22; 1889 return r; 1890 } 1891 1892 namespace 1893 sfinae 1894 { 1895 using ::boost::qvm::operator*; 1896 } 1897 1898 namespace 1899 qvm_detail 1900 { 1901 template <int R,int /*CR*/,int C> 1902 struct mul_mm_defined; 1903 1904 template <> 1905 struct 1906 mul_mm_defined<1,3,3> 1907 { 1908 static bool const value=true; 1909 }; 1910 } 1911 1912 } 1913 } 1914 1915 #endif 1916