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_20D98340A3EB11DEB2180CD156D89593 7 #define BOOST_QVM_20D98340A3EB11DEB2180CD156D89593 8 9 #include <boost/qvm/inline.hpp> 10 #include <boost/qvm/deduce_mat.hpp> 11 #include <boost/qvm/assert.hpp> 12 #include <boost/qvm/enable_if.hpp> 13 #include <boost/qvm/detail/transp_impl.hpp> 14 15 namespace 16 boost 17 { 18 namespace 19 qvm 20 { 21 //////////////////////////////////////////////// 22 23 namespace 24 qvm_detail 25 { 26 template <int Row,class OriginalMatrix> 27 class 28 del_row_ 29 { 30 del_row_( del_row_ const & ); 31 del_row_ & operator=( del_row_ const & ); 32 ~del_row_(); 33 34 public: 35 36 template <class T> 37 BOOST_QVM_INLINE_TRIVIAL 38 del_row_ & 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 <int I,class OriginalMatrix> 57 struct 58 mat_traits< qvm_detail::del_row_<I,OriginalMatrix> > 59 { 60 typedef qvm_detail::del_row_<I,OriginalMatrix> this_matrix; 61 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 62 static int const rows=mat_traits<OriginalMatrix>::rows-1; 63 static int const cols=mat_traits<OriginalMatrix>::cols; 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(Row>=0); 72 BOOST_QVM_STATIC_ASSERT(Row<rows); 73 BOOST_QVM_STATIC_ASSERT(Col>=0); 74 BOOST_QVM_STATIC_ASSERT(Col<cols); 75 return mat_traits<OriginalMatrix>::template read_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix const &>(x)); 76 } 77 78 template <int Row,int Col> 79 static 80 BOOST_QVM_INLINE_CRITICAL 81 scalar_type & write_elementboost::qvm::mat_traits82 write_element( this_matrix & x ) 83 { 84 BOOST_QVM_STATIC_ASSERT(Row>=0); 85 BOOST_QVM_STATIC_ASSERT(Row<rows); 86 BOOST_QVM_STATIC_ASSERT(Col>=0); 87 BOOST_QVM_STATIC_ASSERT(Col<cols); 88 return mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix &>(x)); 89 } 90 91 static 92 BOOST_QVM_INLINE_CRITICAL 93 scalar_type read_element_idxboost::qvm::mat_traits94 read_element_idx( int row, int col, this_matrix const & x ) 95 { 96 BOOST_QVM_ASSERT(row>=0); 97 BOOST_QVM_ASSERT(row<rows); 98 BOOST_QVM_ASSERT(col>=0); 99 BOOST_QVM_ASSERT(col<cols); 100 return mat_traits<OriginalMatrix>::read_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix const &>(x)); 101 } 102 103 static 104 BOOST_QVM_INLINE_CRITICAL 105 scalar_type & write_element_idxboost::qvm::mat_traits106 write_element_idx( int row, int col, this_matrix & x ) 107 { 108 BOOST_QVM_ASSERT(row>=0); 109 BOOST_QVM_ASSERT(row<rows); 110 BOOST_QVM_ASSERT(col>=0); 111 BOOST_QVM_ASSERT(col<cols); 112 return mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix &>(x)); 113 } 114 }; 115 116 template <int J,class OriginalMatrix,int R,int C> 117 struct 118 deduce_mat<qvm_detail::del_row_<J,OriginalMatrix>,R,C> 119 { 120 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 121 }; 122 123 template <int J,class OriginalMatrix,int R,int C> 124 struct 125 deduce_mat2<qvm_detail::del_row_<J,OriginalMatrix>,qvm_detail::del_row_<J,OriginalMatrix>,R,C> 126 { 127 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 128 }; 129 130 template <int Row,class A> 131 typename boost::enable_if_c< 132 is_mat<A>::value, 133 qvm_detail::del_row_<Row,A> const &>::type 134 BOOST_QVM_INLINE_TRIVIAL del_row(A const & a)135 del_row( A const & a ) 136 { 137 return reinterpret_cast<typename qvm_detail::del_row_<Row,A> const &>(a); 138 } 139 140 template <int Row,class A> 141 typename boost::enable_if_c< 142 is_mat<A>::value, 143 qvm_detail::del_row_<Row,A> &>::type 144 BOOST_QVM_INLINE_TRIVIAL del_row(A & a)145 del_row( A & a ) 146 { 147 return reinterpret_cast<typename qvm_detail::del_row_<Row,A> &>(a); 148 } 149 150 //////////////////////////////////////////////// 151 152 namespace 153 qvm_detail 154 { 155 template <int Col,class OriginalMatrix> 156 class 157 del_col_ 158 { 159 del_col_( del_col_ const & ); 160 del_col_ & operator=( del_col_ const & ); 161 ~del_col_(); 162 163 public: 164 165 template <class T> 166 BOOST_QVM_INLINE_TRIVIAL 167 del_col_ & operator =(T const & x)168 operator=( T const & x ) 169 { 170 assign(*this,x); 171 return *this; 172 } 173 174 template <class R> 175 BOOST_QVM_INLINE_TRIVIAL operator R() const176 operator R() const 177 { 178 R r; 179 assign(r,*this); 180 return r; 181 } 182 }; 183 } 184 185 template <int J,class OriginalMatrix> 186 struct 187 mat_traits< qvm_detail::del_col_<J,OriginalMatrix> > 188 { 189 typedef qvm_detail::del_col_<J,OriginalMatrix> this_matrix; 190 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 191 static int const rows=mat_traits<OriginalMatrix>::rows; 192 static int const cols=mat_traits<OriginalMatrix>::cols-1; 193 194 template <int Row,int Col> 195 static 196 BOOST_QVM_INLINE_CRITICAL 197 scalar_type read_elementboost::qvm::mat_traits198 read_element( this_matrix const & x ) 199 { 200 BOOST_QVM_STATIC_ASSERT(Row>=0); 201 BOOST_QVM_STATIC_ASSERT(Row<rows); 202 BOOST_QVM_STATIC_ASSERT(Col>=0); 203 BOOST_QVM_STATIC_ASSERT(Col<cols); 204 return mat_traits<OriginalMatrix>::template read_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix const &>(x)); 205 } 206 207 template <int Row,int Col> 208 static 209 BOOST_QVM_INLINE_CRITICAL 210 scalar_type & write_elementboost::qvm::mat_traits211 write_element( this_matrix & x ) 212 { 213 BOOST_QVM_STATIC_ASSERT(Row>=0); 214 BOOST_QVM_STATIC_ASSERT(Row<rows); 215 BOOST_QVM_STATIC_ASSERT(Col>=0); 216 BOOST_QVM_STATIC_ASSERT(Col<cols); 217 return mat_traits<OriginalMatrix>::template write_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x)); 218 } 219 220 static 221 BOOST_QVM_INLINE_CRITICAL 222 scalar_type read_element_idxboost::qvm::mat_traits223 read_element_idx( int row, int col, this_matrix const & x ) 224 { 225 BOOST_QVM_ASSERT(row>=0); 226 BOOST_QVM_ASSERT(row<rows); 227 BOOST_QVM_ASSERT(col>=0); 228 BOOST_QVM_ASSERT(col<cols); 229 return mat_traits<OriginalMatrix>::read_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix const &>(x)); 230 } 231 232 static 233 BOOST_QVM_INLINE_CRITICAL 234 scalar_type & write_element_idxboost::qvm::mat_traits235 write_element_idx( int row, int col, this_matrix & x ) 236 { 237 BOOST_QVM_ASSERT(row>=0); 238 BOOST_QVM_ASSERT(row<rows); 239 BOOST_QVM_ASSERT(col>=0); 240 BOOST_QVM_ASSERT(col<cols); 241 return mat_traits<OriginalMatrix>::write_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix &>(x)); 242 } 243 }; 244 245 template <int J,class OriginalMatrix,int R,int C> 246 struct 247 deduce_mat<qvm_detail::del_col_<J,OriginalMatrix>,R,C> 248 { 249 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 250 }; 251 252 template <int J,class OriginalMatrix,int R,int C> 253 struct 254 deduce_mat2<qvm_detail::del_col_<J,OriginalMatrix>,qvm_detail::del_col_<J,OriginalMatrix>,R,C> 255 { 256 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 257 }; 258 259 template <int Col,class A> 260 typename boost::enable_if_c< 261 is_mat<A>::value, 262 qvm_detail::del_col_<Col,A> const &>::type 263 BOOST_QVM_INLINE_TRIVIAL del_col(A const & a)264 del_col( A const & a ) 265 { 266 return reinterpret_cast<typename qvm_detail::del_col_<Col,A> const &>(a); 267 } 268 269 template <int Col,class A> 270 typename boost::enable_if_c< 271 is_mat<A>::value, 272 qvm_detail::del_col_<Col,A> &>::type 273 BOOST_QVM_INLINE_TRIVIAL del_col(A & a)274 del_col( A & a ) 275 { 276 return reinterpret_cast<typename qvm_detail::del_col_<Col,A> &>(a); 277 } 278 279 //////////////////////////////////////////////// 280 281 namespace 282 qvm_detail 283 { 284 template <int Row,int Col,class OriginalMatrix> 285 class 286 del_row_col_ 287 { 288 del_row_col_( del_row_col_ const & ); 289 ~del_row_col_(); 290 291 public: 292 293 BOOST_QVM_INLINE_TRIVIAL 294 del_row_col_ & operator =(del_row_col_ const & x)295 operator=( del_row_col_ const & x ) 296 { 297 assign(*this,x); 298 return *this; 299 } 300 301 template <class T> 302 BOOST_QVM_INLINE_TRIVIAL 303 del_row_col_ & operator =(T const & x)304 operator=( T const & x ) 305 { 306 assign(*this,x); 307 return *this; 308 } 309 310 template <class R> 311 BOOST_QVM_INLINE_TRIVIAL operator R() const312 operator R() const 313 { 314 R r; 315 assign(r,*this); 316 return r; 317 } 318 }; 319 } 320 321 template <int I,int J,class OriginalMatrix> 322 struct 323 mat_traits< qvm_detail::del_row_col_<I,J,OriginalMatrix> > 324 { 325 typedef qvm_detail::del_row_col_<I,J,OriginalMatrix> this_matrix; 326 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 327 static int const rows=mat_traits<OriginalMatrix>::rows-1; 328 static int const cols=mat_traits<OriginalMatrix>::cols-1; 329 330 template <int Row,int Col> 331 static 332 BOOST_QVM_INLINE_CRITICAL 333 scalar_type read_elementboost::qvm::mat_traits334 read_element( this_matrix const & x ) 335 { 336 BOOST_QVM_STATIC_ASSERT(Row>=0); 337 BOOST_QVM_STATIC_ASSERT(Row<rows); 338 BOOST_QVM_STATIC_ASSERT(Col>=0); 339 BOOST_QVM_STATIC_ASSERT(Col<cols); 340 return mat_traits<OriginalMatrix>::template read_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix const &>(x)); 341 } 342 343 template <int Row,int Col> 344 static 345 BOOST_QVM_INLINE_CRITICAL 346 scalar_type & write_elementboost::qvm::mat_traits347 write_element( this_matrix & x ) 348 { 349 BOOST_QVM_STATIC_ASSERT(Row>=0); 350 BOOST_QVM_STATIC_ASSERT(Row<rows); 351 BOOST_QVM_STATIC_ASSERT(Col>=0); 352 BOOST_QVM_STATIC_ASSERT(Col<cols); 353 return mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x)); 354 } 355 356 static 357 BOOST_QVM_INLINE_CRITICAL 358 scalar_type read_element_idxboost::qvm::mat_traits359 read_element_idx( int row, int col, this_matrix const & x ) 360 { 361 BOOST_QVM_ASSERT(row>=0); 362 BOOST_QVM_ASSERT(row<rows); 363 BOOST_QVM_ASSERT(col>=0); 364 BOOST_QVM_ASSERT(col<cols); 365 return mat_traits<OriginalMatrix>::read_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix const &>(x)); 366 } 367 368 static 369 BOOST_QVM_INLINE_CRITICAL 370 scalar_type & write_element_idxboost::qvm::mat_traits371 write_element_idx( int row, int col, this_matrix & x ) 372 { 373 BOOST_QVM_ASSERT(row>=0); 374 BOOST_QVM_ASSERT(row<rows); 375 BOOST_QVM_ASSERT(col>=0); 376 BOOST_QVM_ASSERT(col<cols); 377 return mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix &>(x)); 378 } 379 }; 380 381 template <int I,int J,class OriginalMatrix,int R,int C> 382 struct 383 deduce_mat<qvm_detail::del_row_col_<I,J,OriginalMatrix>,R,C> 384 { 385 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 386 }; 387 388 template <int I,int J,class OriginalMatrix,int R,int C> 389 struct 390 deduce_mat2<qvm_detail::del_row_col_<I,J,OriginalMatrix>,qvm_detail::del_row_col_<I,J,OriginalMatrix>,R,C> 391 { 392 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 393 }; 394 395 template <int Row,int Col,class A> 396 typename boost::enable_if_c< 397 is_mat<A>::value, 398 qvm_detail::del_row_col_<Row,Col,A> const &>::type 399 BOOST_QVM_INLINE_TRIVIAL del_row_col(A const & a)400 del_row_col( A const & a ) 401 { 402 return reinterpret_cast<typename qvm_detail::del_row_col_<Row,Col,A> const &>(a); 403 } 404 405 template <int Row,int Col,class A> 406 typename boost::enable_if_c< 407 is_mat<A>::value, 408 qvm_detail::del_row_col_<Row,Col,A> &>::type 409 BOOST_QVM_INLINE_TRIVIAL del_row_col(A & a)410 del_row_col( A & a ) 411 { 412 return reinterpret_cast<typename qvm_detail::del_row_col_<Row,Col,A> &>(a); 413 } 414 415 //////////////////////////////////////////////// 416 417 namespace 418 qvm_detail 419 { 420 template <int Row,class OriginalMatrix> 421 class 422 neg_row_ 423 { 424 neg_row_( neg_row_ const & ); 425 neg_row_ & operator=( neg_row_ const & ); 426 ~neg_row_(); 427 428 public: 429 430 template <class T> 431 BOOST_QVM_INLINE_TRIVIAL 432 neg_row_ & operator =(T const & x)433 operator=( T const & x ) 434 { 435 assign(*this,x); 436 return *this; 437 } 438 439 template <class R> 440 BOOST_QVM_INLINE_TRIVIAL operator R() const441 operator R() const 442 { 443 R r; 444 assign(r,*this); 445 return r; 446 } 447 }; 448 } 449 450 template <int I,class OriginalMatrix> 451 struct 452 mat_traits< qvm_detail::neg_row_<I,OriginalMatrix> > 453 { 454 typedef qvm_detail::neg_row_<I,OriginalMatrix> this_matrix; 455 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 456 static int const rows=mat_traits<OriginalMatrix>::rows; 457 static int const cols=mat_traits<OriginalMatrix>::cols; 458 459 template <int Row,int Col> 460 static 461 BOOST_QVM_INLINE_CRITICAL 462 scalar_type read_elementboost::qvm::mat_traits463 read_element( this_matrix const & x ) 464 { 465 BOOST_QVM_STATIC_ASSERT(Row>=0); 466 BOOST_QVM_STATIC_ASSERT(Row<rows); 467 BOOST_QVM_STATIC_ASSERT(Col>=0); 468 BOOST_QVM_STATIC_ASSERT(Col<cols); 469 return Row==I ? 470 -mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)) : 471 mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)); 472 } 473 474 static 475 BOOST_QVM_INLINE_CRITICAL 476 scalar_type read_element_idxboost::qvm::mat_traits477 read_element_idx( int row, int col, this_matrix const & x ) 478 { 479 BOOST_QVM_ASSERT(row>=0); 480 BOOST_QVM_ASSERT(row<rows); 481 BOOST_QVM_ASSERT(col>=0); 482 BOOST_QVM_ASSERT(col<cols); 483 return row==I? 484 -mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)) : 485 mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)); 486 } 487 }; 488 489 template <int J,class OriginalMatrix,int R,int C> 490 struct 491 deduce_mat<qvm_detail::neg_row_<J,OriginalMatrix>,R,C> 492 { 493 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 494 }; 495 496 template <int J,class OriginalMatrix,int R,int C> 497 struct 498 deduce_mat2<qvm_detail::neg_row_<J,OriginalMatrix>,qvm_detail::neg_row_<J,OriginalMatrix>,R,C> 499 { 500 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 501 }; 502 503 template <int Row,class A> 504 typename boost::enable_if_c< 505 is_mat<A>::value, 506 qvm_detail::neg_row_<Row,A> const &>::type 507 BOOST_QVM_INLINE_TRIVIAL neg_row(A const & a)508 neg_row( A const & a ) 509 { 510 return reinterpret_cast<typename qvm_detail::neg_row_<Row,A> const &>(a); 511 } 512 513 //////////////////////////////////////////////// 514 515 namespace 516 qvm_detail 517 { 518 template <int Col,class OriginalMatrix> 519 class 520 neg_col_ 521 { 522 neg_col_( neg_col_ const & ); 523 neg_col_ & operator=( neg_col_ const & ); 524 ~neg_col_(); 525 526 public: 527 528 template <class T> 529 BOOST_QVM_INLINE_TRIVIAL 530 neg_col_ & operator =(T const & x)531 operator=( T const & x ) 532 { 533 assign(*this,x); 534 return *this; 535 } 536 537 template <class R> 538 BOOST_QVM_INLINE_TRIVIAL operator R() const539 operator R() const 540 { 541 R r; 542 assign(r,*this); 543 return r; 544 } 545 }; 546 } 547 548 template <int J,class OriginalMatrix> 549 struct 550 mat_traits< qvm_detail::neg_col_<J,OriginalMatrix> > 551 { 552 typedef qvm_detail::neg_col_<J,OriginalMatrix> this_matrix; 553 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 554 static int const rows=mat_traits<OriginalMatrix>::rows; 555 static int const cols=mat_traits<OriginalMatrix>::cols; 556 557 template <int Row,int Col> 558 static 559 BOOST_QVM_INLINE_CRITICAL 560 scalar_type read_elementboost::qvm::mat_traits561 read_element( this_matrix const & x ) 562 { 563 BOOST_QVM_STATIC_ASSERT(Row>=0); 564 BOOST_QVM_STATIC_ASSERT(Row<rows); 565 BOOST_QVM_STATIC_ASSERT(Col>=0); 566 BOOST_QVM_STATIC_ASSERT(Col<cols); 567 return Col==J? 568 -mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)) : 569 mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)); 570 } 571 572 static 573 BOOST_QVM_INLINE_CRITICAL 574 scalar_type read_element_idxboost::qvm::mat_traits575 read_element_idx( int row, int col, this_matrix const & x ) 576 { 577 BOOST_QVM_ASSERT(row>=0); 578 BOOST_QVM_ASSERT(row<rows); 579 BOOST_QVM_ASSERT(col>=0); 580 BOOST_QVM_ASSERT(col<cols); 581 return col==J? 582 -mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)) : 583 mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)); 584 } 585 }; 586 587 template <int J,class OriginalMatrix,int R,int C> 588 struct 589 deduce_mat<qvm_detail::neg_col_<J,OriginalMatrix>,R,C> 590 { 591 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 592 }; 593 594 template <int J,class OriginalMatrix,int R,int C> 595 struct 596 deduce_mat2<qvm_detail::neg_col_<J,OriginalMatrix>,qvm_detail::neg_col_<J,OriginalMatrix>,R,C> 597 { 598 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 599 }; 600 601 template <int Col,class A> 602 typename boost::enable_if_c< 603 is_mat<A>::value, 604 qvm_detail::neg_col_<Col,A> const &>::type 605 BOOST_QVM_INLINE_TRIVIAL neg_col(A const & a)606 neg_col( A const & a ) 607 { 608 return reinterpret_cast<typename qvm_detail::neg_col_<Col,A> const &>(a); 609 } 610 611 //////////////////////////////////////////////// 612 613 template <class A> 614 typename boost::enable_if_c< 615 is_mat<A>::value, 616 qvm_detail::transposed_<A> const &>::type 617 BOOST_QVM_INLINE_TRIVIAL transposed(A const & a)618 transposed( A const & a ) 619 { 620 return reinterpret_cast<typename qvm_detail::transposed_<A> const &>(a); 621 } 622 623 template <class A> 624 typename boost::enable_if_c< 625 is_mat<A>::value, 626 qvm_detail::transposed_<A> &>::type 627 BOOST_QVM_INLINE_TRIVIAL transposed(A & a)628 transposed( A & a ) 629 { 630 return reinterpret_cast<typename qvm_detail::transposed_<A> &>(a); 631 } 632 633 //////////////////////////////////////////////// 634 635 namespace 636 qvm_detail 637 { 638 template <int Row1,int Row2,class OriginalMatrix> 639 class 640 swap_rows_ 641 { 642 swap_rows_( swap_rows_ const & ); 643 swap_rows_ & operator=( swap_rows_ const & ); 644 ~swap_rows_(); 645 646 public: 647 648 template <class T> 649 BOOST_QVM_INLINE_TRIVIAL 650 swap_rows_ & operator =(T const & x)651 operator=( T const & x ) 652 { 653 assign(*this,x); 654 return *this; 655 } 656 657 template <class R> 658 BOOST_QVM_INLINE_TRIVIAL operator R() const659 operator R() const 660 { 661 R r; 662 assign(r,*this); 663 return r; 664 } 665 }; 666 } 667 668 template <int R1,int R2,class OriginalMatrix> 669 struct 670 mat_traits< qvm_detail::swap_rows_<R1,R2,OriginalMatrix> > 671 { 672 typedef qvm_detail::swap_rows_<R1,R2,OriginalMatrix> this_matrix; 673 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 674 static int const rows=mat_traits<OriginalMatrix>::rows; 675 static int const cols=mat_traits<OriginalMatrix>::cols; 676 677 template <int Row,int Col> 678 static 679 BOOST_QVM_INLINE_CRITICAL 680 scalar_type read_elementboost::qvm::mat_traits681 read_element( this_matrix const & x ) 682 { 683 BOOST_QVM_STATIC_ASSERT(Row>=0); 684 BOOST_QVM_STATIC_ASSERT(Row<rows); 685 BOOST_QVM_STATIC_ASSERT(Col>=0); 686 BOOST_QVM_STATIC_ASSERT(Col<cols); 687 return mat_traits<OriginalMatrix>::template read_element<(Row==R1 && R1!=R2)*R2+(Row==R2 && R1!=R2)*R1+((Row!=R1 && Row!=R2) || R1==R2)*Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)); 688 } 689 690 template <int Row,int Col> 691 static 692 BOOST_QVM_INLINE_CRITICAL 693 scalar_type & write_elementboost::qvm::mat_traits694 write_element( this_matrix & x ) 695 { 696 BOOST_QVM_STATIC_ASSERT(Row>=0); 697 BOOST_QVM_STATIC_ASSERT(Row<rows); 698 BOOST_QVM_STATIC_ASSERT(Col>=0); 699 BOOST_QVM_STATIC_ASSERT(Col<cols); 700 return mat_traits<OriginalMatrix>::template write_element<(Row==R1 && R1!=R2)*R2+(Row==R2 && R1!=R2)*R1+((Row!=R1 && Row!=R2) || R1==R2)*Row,Col>(reinterpret_cast<OriginalMatrix &>(x)); 701 } 702 703 static 704 BOOST_QVM_INLINE_CRITICAL 705 scalar_type read_element_idxboost::qvm::mat_traits706 read_element_idx( int row, int col, this_matrix const & x ) 707 { 708 BOOST_QVM_ASSERT(row>=0); 709 BOOST_QVM_ASSERT(row<rows); 710 BOOST_QVM_ASSERT(col>=0); 711 BOOST_QVM_ASSERT(col<cols); 712 return mat_traits<OriginalMatrix>::read_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix const &>(x)); 713 } 714 715 static 716 BOOST_QVM_INLINE_CRITICAL 717 scalar_type & write_element_idxboost::qvm::mat_traits718 write_element_idx( int row, int col, this_matrix & x ) 719 { 720 BOOST_QVM_ASSERT(row>=0); 721 BOOST_QVM_ASSERT(row<rows); 722 BOOST_QVM_ASSERT(col>=0); 723 BOOST_QVM_ASSERT(col<cols); 724 return mat_traits<OriginalMatrix>::write_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix &>(x)); 725 } 726 }; 727 728 template <int R1,int R2,class OriginalMatrix,int R,int C> 729 struct 730 deduce_mat<qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,R,C> 731 { 732 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 733 }; 734 735 template <int R1,int R2,class OriginalMatrix,int R,int C> 736 struct 737 deduce_mat2<qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,R,C> 738 { 739 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 740 }; 741 742 template <int R1,int R2,class A> 743 typename boost::enable_if_c< 744 is_mat<A>::value, 745 qvm_detail::swap_rows_<R1,R2,A> const &>::type 746 BOOST_QVM_INLINE_TRIVIAL swap_rows(A const & a)747 swap_rows( A const & a ) 748 { 749 return reinterpret_cast<typename qvm_detail::swap_rows_<R1,R2,A> const &>(a); 750 } 751 752 template <int R1,int R2,class A> 753 typename boost::enable_if_c< 754 is_mat<A>::value, 755 qvm_detail::swap_rows_<R1,R2,A> &>::type 756 BOOST_QVM_INLINE_TRIVIAL swap_rows(A & a)757 swap_rows( A & a ) 758 { 759 return reinterpret_cast<typename qvm_detail::swap_rows_<R1,R2,A> &>(a); 760 } 761 762 //////////////////////////////////////////////// 763 764 namespace 765 qvm_detail 766 { 767 template <int Row1,int Row2,class OriginalMatrix> 768 class 769 swap_cols_ 770 { 771 swap_cols_( swap_cols_ const & ); 772 swap_cols_ & operator=( swap_cols_ const & ); 773 ~swap_cols_(); 774 775 public: 776 777 template <class T> 778 BOOST_QVM_INLINE_TRIVIAL 779 swap_cols_ & operator =(T const & x)780 operator=( T const & x ) 781 { 782 assign(*this,x); 783 return *this; 784 } 785 786 template <class R> 787 BOOST_QVM_INLINE_TRIVIAL operator R() const788 operator R() const 789 { 790 R r; 791 assign(r,*this); 792 return r; 793 } 794 }; 795 } 796 797 template <int C1,int C2,class OriginalMatrix> 798 struct 799 mat_traits< qvm_detail::swap_cols_<C1,C2,OriginalMatrix> > 800 { 801 typedef qvm_detail::swap_cols_<C1,C2,OriginalMatrix> this_matrix; 802 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 803 static int const rows=mat_traits<OriginalMatrix>::rows; 804 static int const cols=mat_traits<OriginalMatrix>::cols; 805 806 template <int Row,int Col> 807 static 808 BOOST_QVM_INLINE_CRITICAL 809 scalar_type read_elementboost::qvm::mat_traits810 read_element( this_matrix const & x ) 811 { 812 BOOST_QVM_STATIC_ASSERT(Row>=0); 813 BOOST_QVM_STATIC_ASSERT(Row<rows); 814 BOOST_QVM_STATIC_ASSERT(Col>=0); 815 BOOST_QVM_STATIC_ASSERT(Col<cols); 816 return mat_traits<OriginalMatrix>::template read_element<Row,(Col==C1 && C1!=C2)*C2+(Col==C2 && C1!=C2)*C1+((Col!=C1 && Col!=C2) || C1==C2)*Col>(reinterpret_cast<OriginalMatrix const &>(x)); 817 } 818 819 template <int Row,int Col> 820 static 821 BOOST_QVM_INLINE_CRITICAL 822 scalar_type & write_elementboost::qvm::mat_traits823 write_element( this_matrix & x ) 824 { 825 BOOST_QVM_STATIC_ASSERT(Row>=0); 826 BOOST_QVM_STATIC_ASSERT(Row<rows); 827 BOOST_QVM_STATIC_ASSERT(Col>=0); 828 BOOST_QVM_STATIC_ASSERT(Col<cols); 829 return mat_traits<OriginalMatrix>::template write_element<Row,(Col==C1 && C1!=C2)*C2+(Col==C2 && C1!=C2)*C1+((Col!=C1 && Col!=C2) || C1==C2)*Col>(reinterpret_cast<OriginalMatrix &>(x)); 830 } 831 832 static 833 BOOST_QVM_INLINE_CRITICAL 834 scalar_type read_element_idxboost::qvm::mat_traits835 read_element_idx( int row, int col, this_matrix const & x ) 836 { 837 BOOST_QVM_ASSERT(row>=0); 838 BOOST_QVM_ASSERT(row<rows); 839 BOOST_QVM_ASSERT(col>=0); 840 BOOST_QVM_ASSERT(col<cols); 841 return mat_traits<OriginalMatrix>::read_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix const &>(x)); 842 } 843 844 static 845 BOOST_QVM_INLINE_CRITICAL 846 scalar_type & write_element_idxboost::qvm::mat_traits847 write_element_idx( int row, int col, this_matrix & x ) 848 { 849 BOOST_QVM_ASSERT(row>=0); 850 BOOST_QVM_ASSERT(row<rows); 851 BOOST_QVM_ASSERT(col>=0); 852 BOOST_QVM_ASSERT(col<cols); 853 return mat_traits<OriginalMatrix>::write_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix &>(x)); 854 } 855 }; 856 857 template <int C1,int C2,class OriginalMatrix,int R,int C> 858 struct 859 deduce_mat<qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,R,C> 860 { 861 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 862 }; 863 864 template <int C1,int C2,class OriginalMatrix,int R,int C> 865 struct 866 deduce_mat2<qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,R,C> 867 { 868 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type; 869 }; 870 871 template <int C1,int C2,class A> 872 typename boost::enable_if_c< 873 is_mat<A>::value, 874 qvm_detail::swap_cols_<C1,C2,A> const &>::type 875 BOOST_QVM_INLINE_TRIVIAL swap_cols(A const & a)876 swap_cols( A const & a ) 877 { 878 return reinterpret_cast<typename qvm_detail::swap_cols_<C1,C2,A> const &>(a); 879 } 880 881 template <int C1,int C2,class A> 882 typename boost::enable_if_c< 883 is_mat<A>::value, 884 qvm_detail::swap_cols_<C1,C2,A> &>::type 885 BOOST_QVM_INLINE_TRIVIAL swap_cols(A & a)886 swap_cols( A & a ) 887 { 888 return reinterpret_cast<typename qvm_detail::swap_cols_<C1,C2,A> &>(a); 889 } 890 891 //////////////////////////////////////////////// 892 } 893 } 894 895 #endif 896