File indexing completed on 2025-01-18 09:51:04
0001 #ifndef BOOST_QVM_MAP_MAT_MAT_HPP_INCLUDED
0002 #define BOOST_QVM_MAP_MAT_MAT_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/qvm/config.hpp>
0010 #include <boost/qvm/deduce_mat.hpp>
0011 #include <boost/qvm/assert.hpp>
0012 #include <boost/qvm/enable_if.hpp>
0013 #include <boost/qvm/detail/transp_impl.hpp>
0014
0015 namespace boost { namespace qvm {
0016
0017 namespace
0018 qvm_detail
0019 {
0020 template <int Row,class OriginalMatrix>
0021 class
0022 del_row_
0023 {
0024 del_row_( del_row_ const & );
0025 del_row_ & operator=( del_row_ const & );
0026 ~del_row_();
0027
0028 public:
0029
0030 template <class T>
0031 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0032 del_row_ &
0033 operator=( T const & x )
0034 {
0035 assign(*this,x);
0036 return *this;
0037 }
0038
0039 template <class R
0040 #if __cplusplus >= 201103L
0041 , class = typename enable_if<is_mat<R> >::type
0042 #endif
0043 >
0044 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0045 operator R() const
0046 {
0047 R r;
0048 assign(r,*this);
0049 return r;
0050 }
0051 };
0052
0053 template <int I,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
0054 struct del_row_write_traits;
0055
0056 template <int I,class OriginalMatrix>
0057 struct
0058 del_row_write_traits<I,OriginalMatrix,true>
0059 {
0060 typedef del_row_<I,OriginalMatrix> this_matrix;
0061 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0062 static int const rows=mat_traits<OriginalMatrix>::rows-1;
0063 static int const cols=mat_traits<OriginalMatrix>::cols;
0064
0065 template <int Row,int Col>
0066 static
0067 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0068 scalar_type &
0069 write_element( this_matrix & x )
0070 {
0071 BOOST_QVM_STATIC_ASSERT(Row>=0);
0072 BOOST_QVM_STATIC_ASSERT(Row<rows);
0073 BOOST_QVM_STATIC_ASSERT(Col>=0);
0074 BOOST_QVM_STATIC_ASSERT(Col<cols);
0075 return mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix &>(x));
0076 }
0077
0078 static
0079 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0080 scalar_type &
0081 write_element_idx( int row, int col, this_matrix & x )
0082 {
0083 BOOST_QVM_ASSERT(row>=0);
0084 BOOST_QVM_ASSERT(row<rows);
0085 BOOST_QVM_ASSERT(col>=0);
0086 BOOST_QVM_ASSERT(col<cols);
0087 return mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix &>(x));
0088 }
0089 };
0090
0091 template <int I,class OriginalMatrix>
0092 struct
0093 del_row_write_traits<I,OriginalMatrix,false>
0094 {
0095 typedef del_row_<I,OriginalMatrix> this_matrix;
0096 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0097 static int const rows=mat_traits<OriginalMatrix>::rows-1;
0098 static int const cols=mat_traits<OriginalMatrix>::cols;
0099
0100 template <int Row,int Col>
0101 static
0102 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0103 void
0104 write_element( this_matrix & x, scalar_type s )
0105 {
0106 BOOST_QVM_STATIC_ASSERT(Row>=0);
0107 BOOST_QVM_STATIC_ASSERT(Row<rows);
0108 BOOST_QVM_STATIC_ASSERT(Col>=0);
0109 BOOST_QVM_STATIC_ASSERT(Col<cols);
0110 mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix &>(x), s);
0111 }
0112
0113 static
0114 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0115 void
0116 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0117 {
0118 BOOST_QVM_ASSERT(row>=0);
0119 BOOST_QVM_ASSERT(row<rows);
0120 BOOST_QVM_ASSERT(col>=0);
0121 BOOST_QVM_ASSERT(col<cols);
0122 mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix &>(x), s);
0123 }
0124 };
0125 }
0126
0127 template <int I,class OriginalMatrix>
0128 struct
0129 mat_traits<qvm_detail::del_row_<I,OriginalMatrix> >:
0130 qvm_detail::del_row_write_traits<I,OriginalMatrix>
0131 {
0132 typedef qvm_detail::del_row_<I,OriginalMatrix> this_matrix;
0133 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0134 static int const rows=mat_traits<OriginalMatrix>::rows-1;
0135 static int const cols=mat_traits<OriginalMatrix>::cols;
0136
0137 template <int Row,int Col>
0138 static
0139 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0140 scalar_type
0141 read_element( this_matrix const & x )
0142 {
0143 BOOST_QVM_STATIC_ASSERT(Row>=0);
0144 BOOST_QVM_STATIC_ASSERT(Row<rows);
0145 BOOST_QVM_STATIC_ASSERT(Col>=0);
0146 BOOST_QVM_STATIC_ASSERT(Col<cols);
0147 return mat_traits<OriginalMatrix>::template read_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix const &>(x));
0148 }
0149
0150 static
0151 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0152 scalar_type
0153 read_element_idx( int row, int col, this_matrix const & x )
0154 {
0155 BOOST_QVM_ASSERT(row>=0);
0156 BOOST_QVM_ASSERT(row<rows);
0157 BOOST_QVM_ASSERT(col>=0);
0158 BOOST_QVM_ASSERT(col<cols);
0159 return mat_traits<OriginalMatrix>::read_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix const &>(x));
0160 }
0161 };
0162
0163 template <int J,class OriginalMatrix,int R,int C>
0164 struct
0165 deduce_mat<qvm_detail::del_row_<J,OriginalMatrix>,R,C>
0166 {
0167 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0168 };
0169
0170 template <int J,class OriginalMatrix,int R,int C>
0171 struct
0172 deduce_mat2<qvm_detail::del_row_<J,OriginalMatrix>,qvm_detail::del_row_<J,OriginalMatrix>,R,C>
0173 {
0174 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0175 };
0176
0177 template <int Row,class A>
0178 typename enable_if_c<
0179 is_mat<A>::value,
0180 qvm_detail::del_row_<Row,A> const &>::type
0181 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0182 del_row( A const & a )
0183 {
0184 return reinterpret_cast<typename qvm_detail::del_row_<Row,A> const &>(a);
0185 }
0186
0187 template <int Row,class A>
0188 typename enable_if_c<
0189 is_mat<A>::value,
0190 qvm_detail::del_row_<Row,A> &>::type
0191 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0192 del_row( A & a )
0193 {
0194 return reinterpret_cast<typename qvm_detail::del_row_<Row,A> &>(a);
0195 }
0196
0197
0198
0199 namespace
0200 qvm_detail
0201 {
0202 template <int Col,class OriginalMatrix>
0203 class
0204 del_col_
0205 {
0206 del_col_( del_col_ const & );
0207 del_col_ & operator=( del_col_ const & );
0208 ~del_col_();
0209
0210 public:
0211
0212 template <class T>
0213 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0214 del_col_ &
0215 operator=( T const & x )
0216 {
0217 assign(*this,x);
0218 return *this;
0219 }
0220
0221 template <class R
0222 #if __cplusplus >= 201103L
0223 , class = typename enable_if<is_mat<R> >::type
0224 #endif
0225 >
0226 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0227 operator R() const
0228 {
0229 R r;
0230 assign(r,*this);
0231 return r;
0232 }
0233 };
0234
0235 template <int J,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
0236 struct del_col_write_traits;
0237
0238 template <int J,class OriginalMatrix>
0239 struct
0240 del_col_write_traits<J,OriginalMatrix,true>
0241 {
0242 typedef del_col_<J,OriginalMatrix> this_matrix;
0243 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0244 static int const rows=mat_traits<OriginalMatrix>::rows;
0245 static int const cols=mat_traits<OriginalMatrix>::cols-1;
0246
0247 template <int Row,int Col>
0248 static
0249 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0250 scalar_type &
0251 write_element( this_matrix & x )
0252 {
0253 BOOST_QVM_STATIC_ASSERT(Row>=0);
0254 BOOST_QVM_STATIC_ASSERT(Row<rows);
0255 BOOST_QVM_STATIC_ASSERT(Col>=0);
0256 BOOST_QVM_STATIC_ASSERT(Col<cols);
0257 return mat_traits<OriginalMatrix>::template write_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x));
0258 }
0259
0260 static
0261 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0262 scalar_type &
0263 write_element_idx( int row, int col, this_matrix & x )
0264 {
0265 BOOST_QVM_ASSERT(row>=0);
0266 BOOST_QVM_ASSERT(row<rows);
0267 BOOST_QVM_ASSERT(col>=0);
0268 BOOST_QVM_ASSERT(col<cols);
0269 return mat_traits<OriginalMatrix>::write_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix &>(x));
0270 }
0271 };
0272
0273 template <int J,class OriginalMatrix>
0274 struct
0275 del_col_write_traits<J,OriginalMatrix,false>
0276 {
0277 typedef del_col_<J,OriginalMatrix> this_matrix;
0278 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0279 static int const rows=mat_traits<OriginalMatrix>::rows;
0280 static int const cols=mat_traits<OriginalMatrix>::cols-1;
0281
0282 template <int Row,int Col>
0283 static
0284 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0285 void
0286 write_element( this_matrix & x, scalar_type s )
0287 {
0288 BOOST_QVM_STATIC_ASSERT(Row>=0);
0289 BOOST_QVM_STATIC_ASSERT(Row<rows);
0290 BOOST_QVM_STATIC_ASSERT(Col>=0);
0291 BOOST_QVM_STATIC_ASSERT(Col<cols);
0292 mat_traits<OriginalMatrix>::template write_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x), s);
0293 }
0294
0295 static
0296 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0297 void
0298 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0299 {
0300 BOOST_QVM_ASSERT(row>=0);
0301 BOOST_QVM_ASSERT(row<rows);
0302 BOOST_QVM_ASSERT(col>=0);
0303 BOOST_QVM_ASSERT(col<cols);
0304 mat_traits<OriginalMatrix>::write_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix &>(x), s);
0305 }
0306 };
0307 }
0308
0309 template <int J,class OriginalMatrix>
0310 struct
0311 mat_traits<qvm_detail::del_col_<J,OriginalMatrix> >:
0312 qvm_detail::del_col_write_traits<J,OriginalMatrix>
0313 {
0314 typedef qvm_detail::del_col_<J,OriginalMatrix> this_matrix;
0315 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0316 static int const rows=mat_traits<OriginalMatrix>::rows;
0317 static int const cols=mat_traits<OriginalMatrix>::cols-1;
0318
0319 template <int Row,int Col>
0320 static
0321 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0322 scalar_type
0323 read_element( this_matrix const & x )
0324 {
0325 BOOST_QVM_STATIC_ASSERT(Row>=0);
0326 BOOST_QVM_STATIC_ASSERT(Row<rows);
0327 BOOST_QVM_STATIC_ASSERT(Col>=0);
0328 BOOST_QVM_STATIC_ASSERT(Col<cols);
0329 return mat_traits<OriginalMatrix>::template read_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix const &>(x));
0330 }
0331
0332 static
0333 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0334 scalar_type
0335 read_element_idx( int row, int col, this_matrix const & x )
0336 {
0337 BOOST_QVM_ASSERT(row>=0);
0338 BOOST_QVM_ASSERT(row<rows);
0339 BOOST_QVM_ASSERT(col>=0);
0340 BOOST_QVM_ASSERT(col<cols);
0341 return mat_traits<OriginalMatrix>::read_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix const &>(x));
0342 }
0343 };
0344
0345 template <int J,class OriginalMatrix,int R,int C>
0346 struct
0347 deduce_mat<qvm_detail::del_col_<J,OriginalMatrix>,R,C>
0348 {
0349 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0350 };
0351
0352 template <int J,class OriginalMatrix,int R,int C>
0353 struct
0354 deduce_mat2<qvm_detail::del_col_<J,OriginalMatrix>,qvm_detail::del_col_<J,OriginalMatrix>,R,C>
0355 {
0356 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0357 };
0358
0359 template <int Col,class A>
0360 typename enable_if_c<
0361 is_mat<A>::value,
0362 qvm_detail::del_col_<Col,A> const &>::type
0363 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0364 del_col( A const & a )
0365 {
0366 return reinterpret_cast<typename qvm_detail::del_col_<Col,A> const &>(a);
0367 }
0368
0369 template <int Col,class A>
0370 typename enable_if_c<
0371 is_mat<A>::value,
0372 qvm_detail::del_col_<Col,A> &>::type
0373 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0374 del_col( A & a )
0375 {
0376 return reinterpret_cast<typename qvm_detail::del_col_<Col,A> &>(a);
0377 }
0378
0379
0380
0381 namespace
0382 qvm_detail
0383 {
0384 template <int Row,int Col,class OriginalMatrix>
0385 class
0386 del_row_col_
0387 {
0388 del_row_col_( del_row_col_ const & );
0389 ~del_row_col_();
0390
0391 public:
0392
0393 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0394 del_row_col_ &
0395 operator=( del_row_col_ const & x )
0396 {
0397 assign(*this,x);
0398 return *this;
0399 }
0400
0401 template <class T>
0402 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0403 del_row_col_ &
0404 operator=( T const & x )
0405 {
0406 assign(*this,x);
0407 return *this;
0408 }
0409
0410 template <class R
0411 #if __cplusplus >= 201103L
0412 , class = typename enable_if<is_mat<R> >::type
0413 #endif
0414 >
0415 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0416 operator R() const
0417 {
0418 R r;
0419 assign(r,*this);
0420 return r;
0421 }
0422 };
0423
0424 template <int I,int J,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
0425 struct del_row_col_write_traits;
0426
0427 template <int I,int J,class OriginalMatrix>
0428 struct
0429 del_row_col_write_traits<I,J,OriginalMatrix,true>
0430 {
0431 typedef del_row_col_<I,J,OriginalMatrix> this_matrix;
0432 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0433 static int const rows=mat_traits<OriginalMatrix>::rows-1;
0434 static int const cols=mat_traits<OriginalMatrix>::cols-1;
0435
0436 template <int Row,int Col>
0437 static
0438 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0439 scalar_type &
0440 write_element( this_matrix & x )
0441 {
0442 BOOST_QVM_STATIC_ASSERT(Row>=0);
0443 BOOST_QVM_STATIC_ASSERT(Row<rows);
0444 BOOST_QVM_STATIC_ASSERT(Col>=0);
0445 BOOST_QVM_STATIC_ASSERT(Col<cols);
0446 return mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x));
0447 }
0448
0449 static
0450 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0451 scalar_type &
0452 write_element_idx( int row, int col, this_matrix & x )
0453 {
0454 BOOST_QVM_ASSERT(row>=0);
0455 BOOST_QVM_ASSERT(row<rows);
0456 BOOST_QVM_ASSERT(col>=0);
0457 BOOST_QVM_ASSERT(col<cols);
0458 return mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix &>(x));
0459 }
0460 };
0461
0462 template <int I,int J,class OriginalMatrix>
0463 struct
0464 del_row_col_write_traits<I,J,OriginalMatrix,false>
0465 {
0466 typedef del_row_col_<I,J,OriginalMatrix> this_matrix;
0467 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0468 static int const rows=mat_traits<OriginalMatrix>::rows-1;
0469 static int const cols=mat_traits<OriginalMatrix>::cols-1;
0470
0471 template <int Row,int Col>
0472 static
0473 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0474 void
0475 write_element( this_matrix & x, scalar_type s )
0476 {
0477 BOOST_QVM_STATIC_ASSERT(Row>=0);
0478 BOOST_QVM_STATIC_ASSERT(Row<rows);
0479 BOOST_QVM_STATIC_ASSERT(Col>=0);
0480 BOOST_QVM_STATIC_ASSERT(Col<cols);
0481 mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x), s);
0482 }
0483
0484 static
0485 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0486 void
0487 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0488 {
0489 BOOST_QVM_ASSERT(row>=0);
0490 BOOST_QVM_ASSERT(row<rows);
0491 BOOST_QVM_ASSERT(col>=0);
0492 BOOST_QVM_ASSERT(col<cols);
0493 mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix &>(x), s);
0494 }
0495 };
0496 }
0497
0498 template <int I,int J,class OriginalMatrix>
0499 struct
0500 mat_traits<qvm_detail::del_row_col_<I,J,OriginalMatrix> >:
0501 qvm_detail::del_row_col_write_traits<I,J,OriginalMatrix>
0502 {
0503 typedef qvm_detail::del_row_col_<I,J,OriginalMatrix> this_matrix;
0504 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0505 static int const rows=mat_traits<OriginalMatrix>::rows-1;
0506 static int const cols=mat_traits<OriginalMatrix>::cols-1;
0507
0508 template <int Row,int Col>
0509 static
0510 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0511 scalar_type
0512 read_element( this_matrix const & x )
0513 {
0514 BOOST_QVM_STATIC_ASSERT(Row>=0);
0515 BOOST_QVM_STATIC_ASSERT(Row<rows);
0516 BOOST_QVM_STATIC_ASSERT(Col>=0);
0517 BOOST_QVM_STATIC_ASSERT(Col<cols);
0518 return mat_traits<OriginalMatrix>::template read_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix const &>(x));
0519 }
0520
0521 static
0522 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0523 scalar_type
0524 read_element_idx( int row, int col, this_matrix const & x )
0525 {
0526 BOOST_QVM_ASSERT(row>=0);
0527 BOOST_QVM_ASSERT(row<rows);
0528 BOOST_QVM_ASSERT(col>=0);
0529 BOOST_QVM_ASSERT(col<cols);
0530 return mat_traits<OriginalMatrix>::read_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix const &>(x));
0531 }
0532 };
0533
0534 template <int I,int J,class OriginalMatrix,int R,int C>
0535 struct
0536 deduce_mat<qvm_detail::del_row_col_<I,J,OriginalMatrix>,R,C>
0537 {
0538 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0539 };
0540
0541 template <int I,int J,class OriginalMatrix,int R,int C>
0542 struct
0543 deduce_mat2<qvm_detail::del_row_col_<I,J,OriginalMatrix>,qvm_detail::del_row_col_<I,J,OriginalMatrix>,R,C>
0544 {
0545 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0546 };
0547
0548 template <int Row,int Col,class A>
0549 typename enable_if_c<
0550 is_mat<A>::value,
0551 qvm_detail::del_row_col_<Row,Col,A> const &>::type
0552 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0553 del_row_col( A const & a )
0554 {
0555 return reinterpret_cast<typename qvm_detail::del_row_col_<Row,Col,A> const &>(a);
0556 }
0557
0558 template <int Row,int Col,class A>
0559 typename enable_if_c<
0560 is_mat<A>::value,
0561 qvm_detail::del_row_col_<Row,Col,A> &>::type
0562 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0563 del_row_col( A & a )
0564 {
0565 return reinterpret_cast<typename qvm_detail::del_row_col_<Row,Col,A> &>(a);
0566 }
0567
0568
0569
0570 namespace
0571 qvm_detail
0572 {
0573 template <int Row,class OriginalMatrix>
0574 class
0575 neg_row_
0576 {
0577 neg_row_( neg_row_ const & );
0578 neg_row_ & operator=( neg_row_ const & );
0579 ~neg_row_();
0580
0581 public:
0582
0583 template <class T>
0584 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0585 neg_row_ &
0586 operator=( T const & x )
0587 {
0588 assign(*this,x);
0589 return *this;
0590 }
0591
0592 template <class R
0593 #if __cplusplus >= 201103L
0594 , class = typename enable_if<is_mat<R> >::type
0595 #endif
0596 >
0597 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0598 operator R() const
0599 {
0600 R r;
0601 assign(r,*this);
0602 return r;
0603 }
0604 };
0605 }
0606
0607 template <int I,class OriginalMatrix>
0608 struct
0609 mat_traits<qvm_detail::neg_row_<I,OriginalMatrix> >
0610 {
0611 typedef qvm_detail::neg_row_<I,OriginalMatrix> this_matrix;
0612 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0613 static int const rows=mat_traits<OriginalMatrix>::rows;
0614 static int const cols=mat_traits<OriginalMatrix>::cols;
0615
0616 template <int Row,int Col>
0617 static
0618 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0619 scalar_type
0620 read_element( this_matrix const & x )
0621 {
0622 BOOST_QVM_STATIC_ASSERT(Row>=0);
0623 BOOST_QVM_STATIC_ASSERT(Row<rows);
0624 BOOST_QVM_STATIC_ASSERT(Col>=0);
0625 BOOST_QVM_STATIC_ASSERT(Col<cols);
0626 return Row==I ?
0627 -mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)) :
0628 mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x));
0629 }
0630
0631 static
0632 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0633 scalar_type
0634 read_element_idx( int row, int col, this_matrix const & x )
0635 {
0636 BOOST_QVM_ASSERT(row>=0);
0637 BOOST_QVM_ASSERT(row<rows);
0638 BOOST_QVM_ASSERT(col>=0);
0639 BOOST_QVM_ASSERT(col<cols);
0640 return row==I?
0641 -mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)) :
0642 mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x));
0643 }
0644 };
0645
0646 template <int J,class OriginalMatrix,int R,int C>
0647 struct
0648 deduce_mat<qvm_detail::neg_row_<J,OriginalMatrix>,R,C>
0649 {
0650 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0651 };
0652
0653 template <int J,class OriginalMatrix,int R,int C>
0654 struct
0655 deduce_mat2<qvm_detail::neg_row_<J,OriginalMatrix>,qvm_detail::neg_row_<J,OriginalMatrix>,R,C>
0656 {
0657 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0658 };
0659
0660 template <int Row,class A>
0661 typename enable_if_c<
0662 is_mat<A>::value,
0663 qvm_detail::neg_row_<Row,A> const &>::type
0664 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0665 neg_row( A const & a )
0666 {
0667 return reinterpret_cast<typename qvm_detail::neg_row_<Row,A> const &>(a);
0668 }
0669
0670
0671
0672 namespace
0673 qvm_detail
0674 {
0675 template <int Col,class OriginalMatrix>
0676 class
0677 neg_col_
0678 {
0679 neg_col_( neg_col_ const & );
0680 neg_col_ & operator=( neg_col_ const & );
0681 ~neg_col_();
0682
0683 public:
0684
0685 template <class T>
0686 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0687 neg_col_ &
0688 operator=( T const & x )
0689 {
0690 assign(*this,x);
0691 return *this;
0692 }
0693
0694 template <class R
0695 #if __cplusplus >= 201103L
0696 , class = typename enable_if<is_mat<R> >::type
0697 #endif
0698 >
0699 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0700 operator R() const
0701 {
0702 R r;
0703 assign(r,*this);
0704 return r;
0705 }
0706 };
0707 }
0708
0709 template <int J,class OriginalMatrix>
0710 struct
0711 mat_traits<qvm_detail::neg_col_<J,OriginalMatrix> >
0712 {
0713 typedef qvm_detail::neg_col_<J,OriginalMatrix> this_matrix;
0714 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0715 static int const rows=mat_traits<OriginalMatrix>::rows;
0716 static int const cols=mat_traits<OriginalMatrix>::cols;
0717
0718 template <int Row,int Col>
0719 static
0720 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0721 scalar_type
0722 read_element( this_matrix const & x )
0723 {
0724 BOOST_QVM_STATIC_ASSERT(Row>=0);
0725 BOOST_QVM_STATIC_ASSERT(Row<rows);
0726 BOOST_QVM_STATIC_ASSERT(Col>=0);
0727 BOOST_QVM_STATIC_ASSERT(Col<cols);
0728 return Col==J?
0729 -mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)) :
0730 mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x));
0731 }
0732
0733 static
0734 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0735 scalar_type
0736 read_element_idx( int row, int col, this_matrix const & x )
0737 {
0738 BOOST_QVM_ASSERT(row>=0);
0739 BOOST_QVM_ASSERT(row<rows);
0740 BOOST_QVM_ASSERT(col>=0);
0741 BOOST_QVM_ASSERT(col<cols);
0742 return col==J?
0743 -mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)) :
0744 mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x));
0745 }
0746 };
0747
0748 template <int J,class OriginalMatrix,int R,int C>
0749 struct
0750 deduce_mat<qvm_detail::neg_col_<J,OriginalMatrix>,R,C>
0751 {
0752 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0753 };
0754
0755 template <int J,class OriginalMatrix,int R,int C>
0756 struct
0757 deduce_mat2<qvm_detail::neg_col_<J,OriginalMatrix>,qvm_detail::neg_col_<J,OriginalMatrix>,R,C>
0758 {
0759 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0760 };
0761
0762 template <int Col,class A>
0763 typename enable_if_c<
0764 is_mat<A>::value,
0765 qvm_detail::neg_col_<Col,A> const &>::type
0766 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0767 neg_col( A const & a )
0768 {
0769 return reinterpret_cast<typename qvm_detail::neg_col_<Col,A> const &>(a);
0770 }
0771
0772
0773
0774 template <class A>
0775 typename enable_if_c<
0776 is_mat<A>::value,
0777 qvm_detail::transposed_<A> const &>::type
0778 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0779 transposed( A const & a )
0780 {
0781 return reinterpret_cast<typename qvm_detail::transposed_<A> const &>(a);
0782 }
0783
0784 template <class A>
0785 typename enable_if_c<
0786 is_mat<A>::value,
0787 qvm_detail::transposed_<A> &>::type
0788 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0789 transposed( A & a )
0790 {
0791 return reinterpret_cast<typename qvm_detail::transposed_<A> &>(a);
0792 }
0793
0794
0795
0796 namespace
0797 qvm_detail
0798 {
0799 template <int Row1,int Row2,class OriginalMatrix>
0800 class
0801 swap_rows_
0802 {
0803 swap_rows_( swap_rows_ const & );
0804 swap_rows_ & operator=( swap_rows_ const & );
0805 ~swap_rows_();
0806
0807 public:
0808
0809 template <class T>
0810 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0811 swap_rows_ &
0812 operator=( T const & x )
0813 {
0814 assign(*this,x);
0815 return *this;
0816 }
0817
0818 template <class R
0819 #if __cplusplus >= 201103L
0820 , class = typename enable_if<is_mat<R> >::type
0821 #endif
0822 >
0823 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0824 operator R() const
0825 {
0826 R r;
0827 assign(r,*this);
0828 return r;
0829 }
0830 };
0831
0832 template <int R1,int R2,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
0833 struct swap_rows_write_traits;
0834
0835 template <int R1,int R2,class OriginalMatrix>
0836 struct
0837 swap_rows_write_traits<R1,R2,OriginalMatrix,true>
0838 {
0839 typedef swap_rows_<R1,R2,OriginalMatrix> this_matrix;
0840 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0841 static int const rows=mat_traits<OriginalMatrix>::rows;
0842 static int const cols=mat_traits<OriginalMatrix>::cols;
0843
0844 template <int Row,int Col>
0845 static
0846 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0847 scalar_type &
0848 write_element( this_matrix & x )
0849 {
0850 BOOST_QVM_STATIC_ASSERT(Row>=0);
0851 BOOST_QVM_STATIC_ASSERT(Row<rows);
0852 BOOST_QVM_STATIC_ASSERT(Col>=0);
0853 BOOST_QVM_STATIC_ASSERT(Col<cols);
0854 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));
0855 }
0856
0857 static
0858 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0859 scalar_type &
0860 write_element_idx( int row, int col, this_matrix & x )
0861 {
0862 BOOST_QVM_ASSERT(row>=0);
0863 BOOST_QVM_ASSERT(row<rows);
0864 BOOST_QVM_ASSERT(col>=0);
0865 BOOST_QVM_ASSERT(col<cols);
0866 return mat_traits<OriginalMatrix>::write_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix &>(x));
0867 }
0868 };
0869
0870 template <int R1,int R2,class OriginalMatrix>
0871 struct
0872 swap_rows_write_traits<R1,R2,OriginalMatrix,false>
0873 {
0874 typedef swap_rows_<R1,R2,OriginalMatrix> this_matrix;
0875 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0876 static int const rows=mat_traits<OriginalMatrix>::rows;
0877 static int const cols=mat_traits<OriginalMatrix>::cols;
0878
0879 template <int Row,int Col>
0880 static
0881 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0882 void
0883 write_element( this_matrix & x, scalar_type s )
0884 {
0885 BOOST_QVM_STATIC_ASSERT(Row>=0);
0886 BOOST_QVM_STATIC_ASSERT(Row<rows);
0887 BOOST_QVM_STATIC_ASSERT(Col>=0);
0888 BOOST_QVM_STATIC_ASSERT(Col<cols);
0889 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), s);
0890 }
0891
0892 static
0893 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0894 void
0895 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0896 {
0897 BOOST_QVM_ASSERT(row>=0);
0898 BOOST_QVM_ASSERT(row<rows);
0899 BOOST_QVM_ASSERT(col>=0);
0900 BOOST_QVM_ASSERT(col<cols);
0901 mat_traits<OriginalMatrix>::write_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix &>(x), s);
0902 }
0903 };
0904 }
0905
0906 template <int R1,int R2,class OriginalMatrix>
0907 struct
0908 mat_traits<qvm_detail::swap_rows_<R1,R2,OriginalMatrix> >:
0909 qvm_detail::swap_rows_write_traits<R1,R2,OriginalMatrix>
0910 {
0911 typedef qvm_detail::swap_rows_<R1,R2,OriginalMatrix> this_matrix;
0912 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0913 static int const rows=mat_traits<OriginalMatrix>::rows;
0914 static int const cols=mat_traits<OriginalMatrix>::cols;
0915
0916 template <int Row,int Col>
0917 static
0918 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0919 scalar_type
0920 read_element( this_matrix const & x )
0921 {
0922 BOOST_QVM_STATIC_ASSERT(Row>=0);
0923 BOOST_QVM_STATIC_ASSERT(Row<rows);
0924 BOOST_QVM_STATIC_ASSERT(Col>=0);
0925 BOOST_QVM_STATIC_ASSERT(Col<cols);
0926 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));
0927 }
0928
0929 static
0930 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0931 scalar_type
0932 read_element_idx( int row, int col, this_matrix const & x )
0933 {
0934 BOOST_QVM_ASSERT(row>=0);
0935 BOOST_QVM_ASSERT(row<rows);
0936 BOOST_QVM_ASSERT(col>=0);
0937 BOOST_QVM_ASSERT(col<cols);
0938 return mat_traits<OriginalMatrix>::read_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix const &>(x));
0939 }
0940 };
0941
0942 template <int R1,int R2,class OriginalMatrix,int R,int C>
0943 struct
0944 deduce_mat<qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,R,C>
0945 {
0946 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0947 };
0948
0949 template <int R1,int R2,class OriginalMatrix,int R,int C>
0950 struct
0951 deduce_mat2<qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,R,C>
0952 {
0953 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0954 };
0955
0956 template <int R1,int R2,class A>
0957 typename enable_if_c<
0958 is_mat<A>::value,
0959 qvm_detail::swap_rows_<R1,R2,A> const &>::type
0960 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0961 swap_rows( A const & a )
0962 {
0963 return reinterpret_cast<typename qvm_detail::swap_rows_<R1,R2,A> const &>(a);
0964 }
0965
0966 template <int R1,int R2,class A>
0967 typename enable_if_c<
0968 is_mat<A>::value,
0969 qvm_detail::swap_rows_<R1,R2,A> &>::type
0970 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0971 swap_rows( A & a )
0972 {
0973 return reinterpret_cast<typename qvm_detail::swap_rows_<R1,R2,A> &>(a);
0974 }
0975
0976
0977
0978 namespace
0979 qvm_detail
0980 {
0981 template <int Row1,int Row2,class OriginalMatrix>
0982 class
0983 swap_cols_
0984 {
0985 swap_cols_( swap_cols_ const & );
0986 swap_cols_ & operator=( swap_cols_ const & );
0987 ~swap_cols_();
0988
0989 public:
0990
0991 template <class T>
0992 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0993 swap_cols_ &
0994 operator=( T const & x )
0995 {
0996 assign(*this,x);
0997 return *this;
0998 }
0999
1000 template <class R
1001 #if __cplusplus >= 201103L
1002 , class = typename enable_if<is_mat<R> >::type
1003 #endif
1004 >
1005 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1006 operator R() const
1007 {
1008 R r;
1009 assign(r,*this);
1010 return r;
1011 }
1012 };
1013
1014 template <int C1,int C2,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
1015 struct swap_cols_write_traits;
1016
1017 template <int C1,int C2,class OriginalMatrix>
1018 struct
1019 swap_cols_write_traits<C1,C2,OriginalMatrix,true>
1020 {
1021 typedef swap_cols_<C1,C2,OriginalMatrix> this_matrix;
1022 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
1023 static int const rows=mat_traits<OriginalMatrix>::rows;
1024 static int const cols=mat_traits<OriginalMatrix>::cols;
1025
1026 template <int Row,int Col>
1027 static
1028 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1029 scalar_type &
1030 write_element( this_matrix & x )
1031 {
1032 BOOST_QVM_STATIC_ASSERT(Row>=0);
1033 BOOST_QVM_STATIC_ASSERT(Row<rows);
1034 BOOST_QVM_STATIC_ASSERT(Col>=0);
1035 BOOST_QVM_STATIC_ASSERT(Col<cols);
1036 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));
1037 }
1038
1039 static
1040 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1041 scalar_type &
1042 write_element_idx( int row, int col, this_matrix & x )
1043 {
1044 BOOST_QVM_ASSERT(row>=0);
1045 BOOST_QVM_ASSERT(row<rows);
1046 BOOST_QVM_ASSERT(col>=0);
1047 BOOST_QVM_ASSERT(col<cols);
1048 return mat_traits<OriginalMatrix>::write_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix &>(x));
1049 }
1050 };
1051
1052 template <int C1,int C2,class OriginalMatrix>
1053 struct
1054 swap_cols_write_traits<C1,C2,OriginalMatrix,false>
1055 {
1056 typedef swap_cols_<C1,C2,OriginalMatrix> this_matrix;
1057 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
1058 static int const rows=mat_traits<OriginalMatrix>::rows;
1059 static int const cols=mat_traits<OriginalMatrix>::cols;
1060
1061 template <int Row,int Col>
1062 static
1063 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1064 void
1065 write_element( this_matrix & x, scalar_type s )
1066 {
1067 BOOST_QVM_STATIC_ASSERT(Row>=0);
1068 BOOST_QVM_STATIC_ASSERT(Row<rows);
1069 BOOST_QVM_STATIC_ASSERT(Col>=0);
1070 BOOST_QVM_STATIC_ASSERT(Col<cols);
1071 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), s);
1072 }
1073
1074 static
1075 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1076 void
1077 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
1078 {
1079 BOOST_QVM_ASSERT(row>=0);
1080 BOOST_QVM_ASSERT(row<rows);
1081 BOOST_QVM_ASSERT(col>=0);
1082 BOOST_QVM_ASSERT(col<cols);
1083 mat_traits<OriginalMatrix>::write_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix &>(x), s);
1084 }
1085 };
1086 }
1087
1088 template <int C1,int C2,class OriginalMatrix>
1089 struct
1090 mat_traits<qvm_detail::swap_cols_<C1,C2,OriginalMatrix> >:
1091 qvm_detail::swap_cols_write_traits<C1,C2,OriginalMatrix>
1092 {
1093 typedef qvm_detail::swap_cols_<C1,C2,OriginalMatrix> this_matrix;
1094 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
1095 static int const rows=mat_traits<OriginalMatrix>::rows;
1096 static int const cols=mat_traits<OriginalMatrix>::cols;
1097
1098 template <int Row,int Col>
1099 static
1100 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1101 scalar_type
1102 read_element( this_matrix const & x )
1103 {
1104 BOOST_QVM_STATIC_ASSERT(Row>=0);
1105 BOOST_QVM_STATIC_ASSERT(Row<rows);
1106 BOOST_QVM_STATIC_ASSERT(Col>=0);
1107 BOOST_QVM_STATIC_ASSERT(Col<cols);
1108 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));
1109 }
1110
1111 static
1112 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1113 scalar_type
1114 read_element_idx( int row, int col, this_matrix const & x )
1115 {
1116 BOOST_QVM_ASSERT(row>=0);
1117 BOOST_QVM_ASSERT(row<rows);
1118 BOOST_QVM_ASSERT(col>=0);
1119 BOOST_QVM_ASSERT(col<cols);
1120 return mat_traits<OriginalMatrix>::read_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix const &>(x));
1121 }
1122 };
1123
1124 template <int C1,int C2,class OriginalMatrix,int R,int C>
1125 struct
1126 deduce_mat<qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,R,C>
1127 {
1128 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
1129 };
1130
1131 template <int C1,int C2,class OriginalMatrix,int R,int C>
1132 struct
1133 deduce_mat2<qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,R,C>
1134 {
1135 typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
1136 };
1137
1138 template <int C1,int C2,class A>
1139 typename enable_if_c<
1140 is_mat<A>::value,
1141 qvm_detail::swap_cols_<C1,C2,A> const &>::type
1142 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1143 swap_cols( A const & a )
1144 {
1145 return reinterpret_cast<typename qvm_detail::swap_cols_<C1,C2,A> const &>(a);
1146 }
1147
1148 template <int C1,int C2,class A>
1149 typename enable_if_c<
1150 is_mat<A>::value,
1151 qvm_detail::swap_cols_<C1,C2,A> &>::type
1152 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1153 swap_cols( A & a )
1154 {
1155 return reinterpret_cast<typename qvm_detail::swap_cols_<C1,C2,A> &>(a);
1156 }
1157
1158 } }
1159
1160 #endif