1 //Copyright (c) 2008-2016 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_3EDF999CA1C011DEBA5C8DA956D89593 7 #define BOOST_QVM_3EDF999CA1C011DEBA5C8DA956D89593 8 9 #include <boost/qvm/inline.hpp> 10 #include <boost/qvm/deduce_mat.hpp> 11 #include <boost/qvm/vec_traits.hpp> 12 #include <boost/qvm/assert.hpp> 13 #include <boost/qvm/enable_if.hpp> 14 15 namespace 16 boost 17 { 18 namespace 19 qvm 20 { 21 //////////////////////////////////////////////// 22 23 namespace 24 qvm_detail 25 { 26 template <class OriginalVector> 27 class 28 col_mat_ 29 { 30 col_mat_( col_mat_ const & ); 31 col_mat_ & operator=( col_mat_ const & ); 32 ~col_mat_(); 33 34 public: 35 36 template <class T> 37 BOOST_QVM_INLINE_TRIVIAL 38 col_mat_ & operator =(T const & x)39 operator=( T const & x ) 40 { 41 assign(*this,x); 42 return *this; 43 } 44 45 template <class R> 46 BOOST_QVM_INLINE_TRIVIAL operator R() const47 operator R() const 48 { 49 R r; 50 assign(r,*this); 51 return r; 52 } 53 }; 54 } 55 56 template <class OriginalVector> 57 struct 58 mat_traits< qvm_detail::col_mat_<OriginalVector> > 59 { 60 typedef qvm_detail::col_mat_<OriginalVector> this_matrix; 61 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type; 62 static int const rows=vec_traits<OriginalVector>::dim; 63 static int const cols=1; 64 65 template <int Row,int Col> 66 static 67 BOOST_QVM_INLINE_CRITICAL 68 scalar_type read_elementboost::qvm::mat_traits69 read_element( this_matrix const & x ) 70 { 71 BOOST_QVM_STATIC_ASSERT(Col==0); 72 BOOST_QVM_STATIC_ASSERT(Row>=0); 73 BOOST_QVM_STATIC_ASSERT(Row<rows); 74 return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x)); 75 } 76 77 template <int Row,int Col> 78 static 79 BOOST_QVM_INLINE_CRITICAL 80 scalar_type & write_elementboost::qvm::mat_traits81 write_element( this_matrix & x ) 82 { 83 BOOST_QVM_STATIC_ASSERT(Col==0); 84 BOOST_QVM_STATIC_ASSERT(Row>=0); 85 BOOST_QVM_STATIC_ASSERT(Row<rows); 86 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x)); 87 } 88 89 static 90 BOOST_QVM_INLINE_CRITICAL 91 scalar_type read_element_idxboost::qvm::mat_traits92 read_element_idx( int row, int col, this_matrix const & x ) 93 { 94 BOOST_QVM_ASSERT(col==0); 95 BOOST_QVM_ASSERT(row>=0); 96 BOOST_QVM_ASSERT(row<rows); 97 return vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)); 98 } 99 100 static 101 BOOST_QVM_INLINE_CRITICAL 102 scalar_type & write_element_idxboost::qvm::mat_traits103 write_element_idx( int row, int col, this_matrix & x ) 104 { 105 BOOST_QVM_ASSERT(col==0); 106 BOOST_QVM_ASSERT(row>=0); 107 BOOST_QVM_ASSERT(row<rows); 108 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x)); 109 } 110 }; 111 112 template <class OriginalVector,int R,int C> 113 struct 114 deduce_mat<qvm_detail::col_mat_<OriginalVector>,R,C> 115 { 116 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type; 117 }; 118 119 template <class OriginalVector,int R,int C> 120 struct 121 deduce_mat2<qvm_detail::col_mat_<OriginalVector>,qvm_detail::col_mat_<OriginalVector>,R,C> 122 { 123 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type; 124 }; 125 126 template <class A> 127 typename boost::enable_if_c< 128 is_vec<A>::value, 129 qvm_detail::col_mat_<A> const &>::type 130 BOOST_QVM_INLINE_TRIVIAL col_mat(A const & a)131 col_mat( A const & a ) 132 { 133 return reinterpret_cast<typename qvm_detail::col_mat_<A> const &>(a); 134 } 135 136 template <class A> 137 typename boost::enable_if_c< 138 is_vec<A>::value, 139 qvm_detail::col_mat_<A> &>::type 140 BOOST_QVM_INLINE_TRIVIAL col_mat(A & a)141 col_mat( A & a ) 142 { 143 return reinterpret_cast<typename qvm_detail::col_mat_<A> &>(a); 144 } 145 146 //////////////////////////////////////////////// 147 148 namespace 149 qvm_detail 150 { 151 template <class OriginalVector> 152 class 153 row_mat_ 154 { 155 row_mat_( row_mat_ const & ); 156 row_mat_ & operator=( row_mat_ const & ); 157 ~row_mat_(); 158 159 public: 160 161 template <class T> 162 BOOST_QVM_INLINE_TRIVIAL 163 row_mat_ & operator =(T const & x)164 operator=( T const & x ) 165 { 166 assign(*this,x); 167 return *this; 168 } 169 170 template <class R> 171 BOOST_QVM_INLINE_TRIVIAL operator R() const172 operator R() const 173 { 174 R r; 175 assign(r,*this); 176 return r; 177 } 178 }; 179 } 180 181 template <class OriginalVector> 182 struct 183 mat_traits< qvm_detail::row_mat_<OriginalVector> > 184 { 185 typedef qvm_detail::row_mat_<OriginalVector> this_matrix; 186 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type; 187 static int const rows=1; 188 static int const cols=vec_traits<OriginalVector>::dim; 189 190 template <int Row,int Col> 191 static 192 BOOST_QVM_INLINE_CRITICAL 193 scalar_type read_elementboost::qvm::mat_traits194 read_element( this_matrix const & x ) 195 { 196 BOOST_QVM_STATIC_ASSERT(Row==0); 197 BOOST_QVM_STATIC_ASSERT(Col>=0); 198 BOOST_QVM_STATIC_ASSERT(Col<cols); 199 return vec_traits<OriginalVector>::template read_element<Col>(reinterpret_cast<OriginalVector const &>(x)); 200 } 201 202 template <int Row,int Col> 203 static 204 BOOST_QVM_INLINE_CRITICAL 205 scalar_type & write_elementboost::qvm::mat_traits206 write_element( this_matrix & x ) 207 { 208 BOOST_QVM_STATIC_ASSERT(Row==0); 209 BOOST_QVM_STATIC_ASSERT(Col>=0); 210 BOOST_QVM_STATIC_ASSERT(Col<cols); 211 return vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x)); 212 } 213 214 static 215 BOOST_QVM_INLINE_CRITICAL 216 scalar_type read_element_idxboost::qvm::mat_traits217 read_element_idx( int row, int col, this_matrix const & x ) 218 { 219 BOOST_QVM_ASSERT(row==0); 220 BOOST_QVM_ASSERT(col>=0); 221 BOOST_QVM_ASSERT(col<cols); 222 return vec_traits<OriginalVector>::read_element_idx(col,reinterpret_cast<OriginalVector const &>(x)); 223 } 224 225 static 226 BOOST_QVM_INLINE_CRITICAL 227 scalar_type & write_element_idxboost::qvm::mat_traits228 write_element_idx( int row, int col, this_matrix & x ) 229 { 230 BOOST_QVM_ASSERT(row==0); 231 BOOST_QVM_ASSERT(col>=0); 232 BOOST_QVM_ASSERT(col<cols); 233 return vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x)); 234 } 235 }; 236 237 template <class OriginalVector,int R,int C> 238 struct 239 deduce_mat<qvm_detail::row_mat_<OriginalVector>,R,C> 240 { 241 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type; 242 }; 243 244 template <class OriginalVector,int R,int C> 245 struct 246 deduce_mat2<qvm_detail::row_mat_<OriginalVector>,qvm_detail::row_mat_<OriginalVector>,R,C> 247 { 248 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type; 249 }; 250 251 template <class A> 252 typename boost::enable_if_c< 253 is_vec<A>::value, 254 qvm_detail::row_mat_<A> const &>::type 255 BOOST_QVM_INLINE_TRIVIAL row_mat(A const & a)256 row_mat( A const & a ) 257 { 258 return reinterpret_cast<typename qvm_detail::row_mat_<A> const &>(a); 259 } 260 261 template <class A> 262 typename boost::enable_if_c< 263 is_vec<A>::value, 264 qvm_detail::row_mat_<A> &>::type 265 BOOST_QVM_INLINE_TRIVIAL row_mat(A & a)266 row_mat( A & a ) 267 { 268 return reinterpret_cast<typename qvm_detail::row_mat_<A> &>(a); 269 } 270 271 //////////////////////////////////////////////// 272 273 namespace 274 qvm_detail 275 { 276 template <class OriginalVector> 277 class 278 translation_mat_ 279 { 280 translation_mat_( translation_mat_ const & ); 281 translation_mat_ & operator=( translation_mat_ const & ); 282 ~translation_mat_(); 283 284 public: 285 286 template <class T> 287 BOOST_QVM_INLINE_TRIVIAL 288 translation_mat_ & operator =(T const & x)289 operator=( T const & x ) 290 { 291 assign(*this,x); 292 return *this; 293 } 294 295 template <class R> 296 BOOST_QVM_INLINE_TRIVIAL operator R() const297 operator R() const 298 { 299 R r; 300 assign(r,*this); 301 return r; 302 } 303 }; 304 305 template <class M,int Row,int Col,bool TransCol=(Col==mat_traits<M>::cols-1)> 306 struct read_translation_matat; 307 308 template <class OriginalVector,int Row,int Col,bool TransCol> 309 struct 310 read_translation_matat<translation_mat_<OriginalVector>,Row,Col,TransCol> 311 { 312 static 313 BOOST_QVM_INLINE_CRITICAL 314 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type fboost::qvm::qvm_detail::read_translation_matat315 f( translation_mat_<OriginalVector> const & ) 316 { 317 return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(0); 318 } 319 }; 320 321 template <class OriginalVector,int D> 322 struct 323 read_translation_matat<translation_mat_<OriginalVector>,D,D,false> 324 { 325 static 326 BOOST_QVM_INLINE_CRITICAL 327 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type fboost::qvm::qvm_detail::read_translation_matat328 f( translation_mat_<OriginalVector> const & ) 329 { 330 return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1); 331 } 332 }; 333 334 template <class OriginalVector,int D> 335 struct 336 read_translation_matat<translation_mat_<OriginalVector>,D,D,true> 337 { 338 static 339 BOOST_QVM_INLINE_CRITICAL 340 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type fboost::qvm::qvm_detail::read_translation_matat341 f( translation_mat_<OriginalVector> const & ) 342 { 343 return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1); 344 } 345 }; 346 347 template <class OriginalVector,int Row,int Col> 348 struct 349 read_translation_matat<translation_mat_<OriginalVector>,Row,Col,true> 350 { 351 static 352 BOOST_QVM_INLINE_CRITICAL 353 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type fboost::qvm::qvm_detail::read_translation_matat354 f( translation_mat_<OriginalVector> const & x ) 355 { 356 return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x)); 357 } 358 }; 359 } 360 361 template <class OriginalVector> 362 struct 363 mat_traits< qvm_detail::translation_mat_<OriginalVector> > 364 { 365 typedef qvm_detail::translation_mat_<OriginalVector> this_matrix; 366 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type; 367 static int const rows=vec_traits<OriginalVector>::dim+1; 368 static int const cols=vec_traits<OriginalVector>::dim+1; 369 370 template <int Row,int Col> 371 static 372 BOOST_QVM_INLINE_CRITICAL 373 scalar_type read_elementboost::qvm::mat_traits374 read_element( this_matrix const & x ) 375 { 376 BOOST_QVM_STATIC_ASSERT(Row>=0); 377 BOOST_QVM_STATIC_ASSERT(Row<rows); 378 BOOST_QVM_STATIC_ASSERT(Col>=0); 379 BOOST_QVM_STATIC_ASSERT(Col<cols); 380 return qvm_detail::read_translation_matat<qvm_detail::translation_mat_<OriginalVector>,Row,Col>::f(x); 381 } 382 383 template <int Row,int Col> 384 static 385 BOOST_QVM_INLINE_CRITICAL 386 scalar_type & write_elementboost::qvm::mat_traits387 write_element( this_matrix & x ) 388 { 389 BOOST_QVM_STATIC_ASSERT(Row>=0); 390 BOOST_QVM_STATIC_ASSERT(Row<rows); 391 BOOST_QVM_STATIC_ASSERT(Col==cols-1); 392 BOOST_QVM_STATIC_ASSERT(Col!=Row); 393 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x)); 394 } 395 396 static 397 BOOST_QVM_INLINE_CRITICAL 398 scalar_type read_element_idxboost::qvm::mat_traits399 read_element_idx( int row, int col, this_matrix const & x ) 400 { 401 BOOST_QVM_ASSERT(row>=0); 402 BOOST_QVM_ASSERT(row<rows); 403 BOOST_QVM_ASSERT(col>=0); 404 BOOST_QVM_ASSERT(col<cols); 405 return 406 row==col? 407 scalar_traits<scalar_type>::value(1): 408 (col==cols-1? 409 vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)): 410 scalar_traits<scalar_type>::value(0)); 411 } 412 413 static 414 BOOST_QVM_INLINE_CRITICAL 415 scalar_type & write_element_idxboost::qvm::mat_traits416 write_element_idx( int row, int col, this_matrix const & x ) 417 { 418 BOOST_QVM_ASSERT(row>=0); 419 BOOST_QVM_ASSERT(row<rows); 420 BOOST_QVM_ASSERT(col==cols-1); 421 BOOST_QVM_ASSERT(col!=row); 422 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x)); 423 } 424 }; 425 426 template <class OriginalVector,int R,int C> 427 struct 428 deduce_mat<qvm_detail::translation_mat_<OriginalVector>,R,C> 429 { 430 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type; 431 }; 432 433 template <class OriginalVector,int R,int C> 434 struct 435 deduce_mat2<qvm_detail::translation_mat_<OriginalVector>,qvm_detail::translation_mat_<OriginalVector>,R,C> 436 { 437 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type; 438 }; 439 440 template <class A> 441 typename boost::enable_if_c< 442 is_vec<A>::value, 443 qvm_detail::translation_mat_<A> const &>::type 444 BOOST_QVM_INLINE_TRIVIAL translation_mat(A const & a)445 translation_mat( A const & a ) 446 { 447 return reinterpret_cast<typename qvm_detail::translation_mat_<A> const &>(a); 448 } 449 450 template <class A> 451 typename boost::enable_if_c< 452 is_vec<A>::value, 453 qvm_detail::translation_mat_<A> &>::type 454 BOOST_QVM_INLINE_TRIVIAL translation_mat(A & a)455 translation_mat( A & a ) 456 { 457 return reinterpret_cast<typename qvm_detail::translation_mat_<A> &>(a); 458 } 459 460 //////////////////////////////////////////////// 461 462 namespace 463 qvm_detail 464 { 465 template <class OriginalVector> 466 class 467 diag_mat_ 468 { 469 diag_mat_( diag_mat_ const & ); 470 diag_mat_ & operator=( diag_mat_ const & ); 471 ~diag_mat_(); 472 473 public: 474 475 template <class T> 476 BOOST_QVM_INLINE_TRIVIAL 477 diag_mat_ & operator =(T const & x)478 operator=( T const & x ) 479 { 480 assign(*this,x); 481 return *this; 482 } 483 484 template <class R> 485 BOOST_QVM_INLINE_TRIVIAL operator R() const486 operator R() const 487 { 488 R r; 489 assign(r,*this); 490 return r; 491 } 492 }; 493 } 494 495 template <class OriginalVector> 496 struct 497 mat_traits< qvm_detail::diag_mat_<OriginalVector> > 498 { 499 typedef qvm_detail::diag_mat_<OriginalVector> this_matrix; 500 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type; 501 static int const rows=vec_traits<OriginalVector>::dim; 502 static int const cols=vec_traits<OriginalVector>::dim; 503 504 template <int Row,int Col> 505 static 506 BOOST_QVM_INLINE_CRITICAL 507 scalar_type read_elementboost::qvm::mat_traits508 read_element( this_matrix const & x ) 509 { 510 BOOST_QVM_STATIC_ASSERT(Row>=0); 511 BOOST_QVM_STATIC_ASSERT(Row<rows); 512 BOOST_QVM_STATIC_ASSERT(Col>=0); 513 BOOST_QVM_STATIC_ASSERT(Col<cols); 514 return Row==Col?vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0); 515 } 516 517 template <int Row,int Col> 518 static 519 BOOST_QVM_INLINE_CRITICAL 520 scalar_type & write_elementboost::qvm::mat_traits521 write_element( this_matrix & x ) 522 { 523 BOOST_QVM_STATIC_ASSERT(Row>=0); 524 BOOST_QVM_STATIC_ASSERT(Row<rows); 525 BOOST_QVM_STATIC_ASSERT(Row==Col); 526 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x)); 527 } 528 529 static 530 BOOST_QVM_INLINE_CRITICAL 531 scalar_type read_element_idxboost::qvm::mat_traits532 read_element_idx( int row, int col, this_matrix const & x ) 533 { 534 BOOST_QVM_ASSERT(row>=0); 535 BOOST_QVM_ASSERT(row<rows); 536 BOOST_QVM_ASSERT(col>=0); 537 BOOST_QVM_ASSERT(col<cols); 538 return row==col?vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0); 539 } 540 541 static 542 BOOST_QVM_INLINE_CRITICAL 543 scalar_type & write_element_idxboost::qvm::mat_traits544 write_element_idx( int row, int col, this_matrix & x ) 545 { 546 BOOST_QVM_ASSERT(row>=0); 547 BOOST_QVM_ASSERT(row<rows); 548 BOOST_QVM_ASSERT(row==col); 549 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x)); 550 } 551 }; 552 553 template <class OriginalVector,int R,int C> 554 struct 555 deduce_mat<qvm_detail::diag_mat_<OriginalVector>,R,C> 556 { 557 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type; 558 }; 559 560 template <class OriginalVector,int R,int C> 561 struct 562 deduce_mat2<qvm_detail::diag_mat_<OriginalVector>,qvm_detail::diag_mat_<OriginalVector>,R,C> 563 { 564 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type; 565 }; 566 567 template <class A> 568 typename boost::enable_if_c< 569 is_vec<A>::value, 570 qvm_detail::diag_mat_<A> const &>::type 571 BOOST_QVM_INLINE_TRIVIAL diag_mat(A const & a)572 diag_mat( A const & a ) 573 { 574 return reinterpret_cast<typename qvm_detail::diag_mat_<A> const &>(a); 575 } 576 577 template <class A> 578 typename boost::enable_if_c< 579 is_vec<A>::value, 580 qvm_detail::diag_mat_<A> &>::type 581 BOOST_QVM_INLINE_TRIVIAL diag_mat(A & a)582 diag_mat( A & a ) 583 { 584 return reinterpret_cast<typename qvm_detail::diag_mat_<A> &>(a); 585 } 586 587 //////////////////////////////////////////////// 588 } 589 } 590 591 #endif 592