File indexing completed on 2025-01-18 09:51:04
0001 #ifndef BOOST_QVM_MAP_VEC_MAT_HPP_INCLUDED
0002 #define BOOST_QVM_MAP_VEC_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/vec_traits.hpp>
0012 #include <boost/qvm/assert.hpp>
0013 #include <boost/qvm/enable_if.hpp>
0014
0015 namespace boost { namespace qvm {
0016
0017 namespace
0018 qvm_detail
0019 {
0020 template <class OriginalVector>
0021 class
0022 col_mat_
0023 {
0024 col_mat_( col_mat_ const & );
0025 col_mat_ & operator=( col_mat_ const & );
0026 ~col_mat_();
0027
0028 public:
0029
0030 template <class T>
0031 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0032 col_mat_ &
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 <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
0054 struct col_mat_write_traits;
0055
0056 template <class OriginalVector>
0057 struct
0058 col_mat_write_traits<OriginalVector,true>
0059 {
0060 typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
0061 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0062 static int const rows=vec_traits<OriginalVector>::dim;
0063 static int const cols=1;
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(Col==0);
0072 BOOST_QVM_STATIC_ASSERT(Row>=0);
0073 BOOST_QVM_STATIC_ASSERT(Row<rows);
0074 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
0075 }
0076
0077 static
0078 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0079 scalar_type &
0080 write_element_idx( int row, int col, this_matrix & x )
0081 {
0082 BOOST_QVM_ASSERT(col==0);
0083 BOOST_QVM_ASSERT(row>=0);
0084 BOOST_QVM_ASSERT(row<rows);
0085 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
0086 }
0087 };
0088
0089 template <class OriginalVector>
0090 struct
0091 col_mat_write_traits<OriginalVector,false>
0092 {
0093 typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
0094 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0095 static int const rows=vec_traits<OriginalVector>::dim;
0096 static int const cols=1;
0097
0098 template <int Row,int Col>
0099 static
0100 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0101 void
0102 write_element( this_matrix & x, scalar_type s )
0103 {
0104 BOOST_QVM_STATIC_ASSERT(Col==0);
0105 BOOST_QVM_STATIC_ASSERT(Row>=0);
0106 BOOST_QVM_STATIC_ASSERT(Row<rows);
0107 vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
0108 }
0109
0110 static
0111 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0112 void
0113 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0114 {
0115 BOOST_QVM_ASSERT(col==0);
0116 BOOST_QVM_ASSERT(row>=0);
0117 BOOST_QVM_ASSERT(row<rows);
0118 vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
0119 }
0120 };
0121 }
0122
0123 template <class OriginalVector>
0124 struct
0125 mat_traits< qvm_detail::col_mat_<OriginalVector> >:
0126 qvm_detail::col_mat_write_traits<OriginalVector>
0127 {
0128 typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
0129 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0130 static int const rows=vec_traits<OriginalVector>::dim;
0131 static int const cols=1;
0132
0133 template <int Row,int Col>
0134 static
0135 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0136 scalar_type
0137 read_element( this_matrix const & x )
0138 {
0139 BOOST_QVM_STATIC_ASSERT(Col==0);
0140 BOOST_QVM_STATIC_ASSERT(Row>=0);
0141 BOOST_QVM_STATIC_ASSERT(Row<rows);
0142 return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
0143 }
0144
0145 static
0146 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0147 scalar_type
0148 read_element_idx( int row, int col, this_matrix const & x )
0149 {
0150 BOOST_QVM_ASSERT(col==0);
0151 BOOST_QVM_ASSERT(row>=0);
0152 BOOST_QVM_ASSERT(row<rows);
0153 return vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x));
0154 }
0155 };
0156
0157 template <class OriginalVector,int R,int C>
0158 struct
0159 deduce_mat<qvm_detail::col_mat_<OriginalVector>,R,C>
0160 {
0161 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0162 };
0163
0164 template <class OriginalVector,int R,int C>
0165 struct
0166 deduce_mat2<qvm_detail::col_mat_<OriginalVector>,qvm_detail::col_mat_<OriginalVector>,R,C>
0167 {
0168 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0169 };
0170
0171 template <class A>
0172 typename enable_if_c<
0173 is_vec<A>::value,
0174 qvm_detail::col_mat_<A> const &>::type
0175 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0176 col_mat( A const & a )
0177 {
0178 return reinterpret_cast<typename qvm_detail::col_mat_<A> const &>(a);
0179 }
0180
0181 template <class A>
0182 typename enable_if_c<
0183 is_vec<A>::value,
0184 qvm_detail::col_mat_<A> &>::type
0185 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0186 col_mat( A & a )
0187 {
0188 return reinterpret_cast<typename qvm_detail::col_mat_<A> &>(a);
0189 }
0190
0191
0192
0193 namespace
0194 qvm_detail
0195 {
0196 template <class OriginalVector>
0197 class
0198 row_mat_
0199 {
0200 row_mat_( row_mat_ const & );
0201 row_mat_ & operator=( row_mat_ const & );
0202 ~row_mat_();
0203
0204 public:
0205
0206 template <class T>
0207 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0208 row_mat_ &
0209 operator=( T const & x )
0210 {
0211 assign(*this,x);
0212 return *this;
0213 }
0214
0215 template <class R
0216 #if __cplusplus >= 201103L
0217 , class = typename enable_if<is_mat<R> >::type
0218 #endif
0219 >
0220 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0221 operator R() const
0222 {
0223 R r;
0224 assign(r,*this);
0225 return r;
0226 }
0227 };
0228
0229 template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
0230 struct row_mat_write_traits;
0231
0232 template <class OriginalVector>
0233 struct
0234 row_mat_write_traits<OriginalVector,true>
0235 {
0236 typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
0237 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0238 static int const rows=1;
0239 static int const cols=vec_traits<OriginalVector>::dim;
0240
0241 template <int Row,int Col>
0242 static
0243 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0244 scalar_type &
0245 write_element( this_matrix & x )
0246 {
0247 BOOST_QVM_STATIC_ASSERT(Row==0);
0248 BOOST_QVM_STATIC_ASSERT(Col>=0);
0249 BOOST_QVM_STATIC_ASSERT(Col<cols);
0250 return vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x));
0251 }
0252
0253 static
0254 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0255 scalar_type &
0256 write_element_idx( int row, int col, this_matrix & x )
0257 {
0258 BOOST_QVM_ASSERT(row==0);
0259 BOOST_QVM_ASSERT(col>=0);
0260 BOOST_QVM_ASSERT(col<cols);
0261 return vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x));
0262 }
0263 };
0264
0265 template <class OriginalVector>
0266 struct
0267 row_mat_write_traits<OriginalVector,false>
0268 {
0269 typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
0270 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0271 static int const rows=1;
0272 static int const cols=vec_traits<OriginalVector>::dim;
0273
0274 template <int Row,int Col>
0275 static
0276 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0277 void
0278 write_element( this_matrix & x, scalar_type s )
0279 {
0280 BOOST_QVM_STATIC_ASSERT(Row==0);
0281 BOOST_QVM_STATIC_ASSERT(Col>=0);
0282 BOOST_QVM_STATIC_ASSERT(Col<cols);
0283 vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x), s);
0284 }
0285
0286 static
0287 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0288 void
0289 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0290 {
0291 BOOST_QVM_ASSERT(row==0);
0292 BOOST_QVM_ASSERT(col>=0);
0293 BOOST_QVM_ASSERT(col<cols);
0294 vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x), s);
0295 }
0296 };
0297 }
0298
0299 template <class OriginalVector>
0300 struct
0301 mat_traits< qvm_detail::row_mat_<OriginalVector> >:
0302 qvm_detail::row_mat_write_traits<OriginalVector>
0303 {
0304 typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
0305 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0306 static int const rows=1;
0307 static int const cols=vec_traits<OriginalVector>::dim;
0308
0309 template <int Row,int Col>
0310 static
0311 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0312 scalar_type
0313 read_element( this_matrix const & x )
0314 {
0315 BOOST_QVM_STATIC_ASSERT(Row==0);
0316 BOOST_QVM_STATIC_ASSERT(Col>=0);
0317 BOOST_QVM_STATIC_ASSERT(Col<cols);
0318 return vec_traits<OriginalVector>::template read_element<Col>(reinterpret_cast<OriginalVector const &>(x));
0319 }
0320
0321 static
0322 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0323 scalar_type
0324 read_element_idx( int row, int col, this_matrix const & x )
0325 {
0326 BOOST_QVM_ASSERT(row==0);
0327 BOOST_QVM_ASSERT(col>=0);
0328 BOOST_QVM_ASSERT(col<cols);
0329 return vec_traits<OriginalVector>::read_element_idx(col,reinterpret_cast<OriginalVector const &>(x));
0330 }
0331 };
0332
0333 template <class OriginalVector,int R,int C>
0334 struct
0335 deduce_mat<qvm_detail::row_mat_<OriginalVector>,R,C>
0336 {
0337 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0338 };
0339
0340 template <class OriginalVector,int R,int C>
0341 struct
0342 deduce_mat2<qvm_detail::row_mat_<OriginalVector>,qvm_detail::row_mat_<OriginalVector>,R,C>
0343 {
0344 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0345 };
0346
0347 template <class A>
0348 typename enable_if_c<
0349 is_vec<A>::value,
0350 qvm_detail::row_mat_<A> const &>::type
0351 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0352 row_mat( A const & a )
0353 {
0354 return reinterpret_cast<typename qvm_detail::row_mat_<A> const &>(a);
0355 }
0356
0357 template <class A>
0358 typename enable_if_c<
0359 is_vec<A>::value,
0360 qvm_detail::row_mat_<A> &>::type
0361 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0362 row_mat( A & a )
0363 {
0364 return reinterpret_cast<typename qvm_detail::row_mat_<A> &>(a);
0365 }
0366
0367
0368
0369 namespace
0370 qvm_detail
0371 {
0372 template <class OriginalVector>
0373 class
0374 translation_mat_
0375 {
0376 translation_mat_( translation_mat_ const & );
0377 translation_mat_ & operator=( translation_mat_ const & );
0378 ~translation_mat_();
0379
0380 public:
0381
0382 template <class T>
0383 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0384 translation_mat_ &
0385 operator=( T const & x )
0386 {
0387 assign(*this,x);
0388 return *this;
0389 }
0390
0391 template <class R
0392 #if __cplusplus >= 201103L
0393 , class = typename enable_if<is_mat<R> >::type
0394 #endif
0395 >
0396 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0397 operator R() const
0398 {
0399 R r;
0400 assign(r,*this);
0401 return r;
0402 }
0403 };
0404
0405 template <class M,int Row,int Col,bool TransCol=(Col==mat_traits<M>::cols-1)>
0406 struct read_translation_matat;
0407
0408 template <class OriginalVector,int Row,int Col,bool TransCol>
0409 struct
0410 read_translation_matat<translation_mat_<OriginalVector>,Row,Col,TransCol>
0411 {
0412 static
0413 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0414 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
0415 f( translation_mat_<OriginalVector> const & )
0416 {
0417 return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(0);
0418 }
0419 };
0420
0421 template <class OriginalVector,int D>
0422 struct
0423 read_translation_matat<translation_mat_<OriginalVector>,D,D,false>
0424 {
0425 static
0426 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0427 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
0428 f( translation_mat_<OriginalVector> const & )
0429 {
0430 return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
0431 }
0432 };
0433
0434 template <class OriginalVector,int D>
0435 struct
0436 read_translation_matat<translation_mat_<OriginalVector>,D,D,true>
0437 {
0438 static
0439 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0440 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
0441 f( translation_mat_<OriginalVector> const & )
0442 {
0443 return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
0444 }
0445 };
0446
0447 template <class OriginalVector,int Row,int Col>
0448 struct
0449 read_translation_matat<translation_mat_<OriginalVector>,Row,Col,true>
0450 {
0451 static
0452 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0453 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
0454 f( translation_mat_<OriginalVector> const & x )
0455 {
0456 return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
0457 }
0458 };
0459
0460 template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
0461 struct translation_mat_write_traits;
0462
0463 template <class OriginalVector>
0464 struct
0465 translation_mat_write_traits<OriginalVector,true>
0466 {
0467 typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
0468 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0469 static int const rows=vec_traits<OriginalVector>::dim+1;
0470 static int const cols=vec_traits<OriginalVector>::dim+1;
0471
0472 template <int Row,int Col>
0473 static
0474 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0475 scalar_type &
0476 write_element( this_matrix & x )
0477 {
0478 BOOST_QVM_STATIC_ASSERT(Row>=0);
0479 BOOST_QVM_STATIC_ASSERT(Row<rows-1);
0480 BOOST_QVM_STATIC_ASSERT(Col==cols-1 || Col==0);
0481
0482
0483
0484 BOOST_QVM_ASSERT(Col==cols-1);
0485 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
0486 }
0487
0488 static
0489 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0490 scalar_type &
0491 write_element_idx( int row, int col, this_matrix const & x )
0492 {
0493 BOOST_QVM_ASSERT(row>=0);
0494 BOOST_QVM_ASSERT(row<rows-1);
0495 BOOST_QVM_ASSERT(col==cols-1);
0496 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
0497 }
0498 };
0499
0500 template <class OriginalVector>
0501 struct
0502 translation_mat_write_traits<OriginalVector,false>
0503 {
0504 typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
0505 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0506 static int const rows=vec_traits<OriginalVector>::dim+1;
0507 static int const cols=vec_traits<OriginalVector>::dim+1;
0508
0509 template <int Row,int Col>
0510 static
0511 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0512 void
0513 write_element( this_matrix & x, scalar_type s )
0514 {
0515 BOOST_QVM_STATIC_ASSERT(Row>=0);
0516 BOOST_QVM_STATIC_ASSERT(Row<rows-1);
0517 BOOST_QVM_STATIC_ASSERT(Col==cols-1 || Col==0);
0518
0519
0520
0521 BOOST_QVM_ASSERT(Col==cols-1);
0522 vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
0523 }
0524
0525 static
0526 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0527 void
0528 write_element_idx( int row, int col, this_matrix const & x, scalar_type s )
0529 {
0530 BOOST_QVM_ASSERT(row>=0);
0531 BOOST_QVM_ASSERT(row<rows);
0532 BOOST_QVM_ASSERT(col==cols-1);
0533 BOOST_QVM_ASSERT(col!=row);
0534 vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
0535 }
0536 };
0537 }
0538
0539 template <class OriginalVector>
0540 struct
0541 mat_traits< qvm_detail::translation_mat_<OriginalVector> >:
0542 qvm_detail::translation_mat_write_traits<OriginalVector>
0543 {
0544 typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
0545 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0546 static int const rows=vec_traits<OriginalVector>::dim+1;
0547 static int const cols=vec_traits<OriginalVector>::dim+1;
0548
0549 template <int Row,int Col>
0550 static
0551 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0552 scalar_type
0553 read_element( this_matrix const & x )
0554 {
0555 BOOST_QVM_STATIC_ASSERT(Row>=0);
0556 BOOST_QVM_STATIC_ASSERT(Row<rows);
0557 BOOST_QVM_STATIC_ASSERT(Col>=0);
0558 BOOST_QVM_STATIC_ASSERT(Col<cols);
0559 return qvm_detail::read_translation_matat<qvm_detail::translation_mat_<OriginalVector>,Row,Col>::f(x);
0560 }
0561
0562 static
0563 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0564 scalar_type
0565 read_element_idx( int row, int col, this_matrix const & x )
0566 {
0567 BOOST_QVM_ASSERT(row>=0);
0568 BOOST_QVM_ASSERT(row<rows);
0569 BOOST_QVM_ASSERT(col>=0);
0570 BOOST_QVM_ASSERT(col<cols);
0571 return
0572 row==col?
0573 scalar_traits<scalar_type>::value(1):
0574 (col==cols-1?
0575 vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):
0576 scalar_traits<scalar_type>::value(0));
0577 }
0578 };
0579
0580 template <class OriginalVector,int R,int C>
0581 struct
0582 deduce_mat<qvm_detail::translation_mat_<OriginalVector>,R,C>
0583 {
0584 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0585 };
0586
0587 template <class OriginalVector,int R,int C>
0588 struct
0589 deduce_mat2<qvm_detail::translation_mat_<OriginalVector>,qvm_detail::translation_mat_<OriginalVector>,R,C>
0590 {
0591 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0592 };
0593
0594 template <class A>
0595 typename enable_if_c<
0596 is_vec<A>::value,
0597 qvm_detail::translation_mat_<A> const &>::type
0598 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0599 translation_mat( A const & a )
0600 {
0601 return reinterpret_cast<typename qvm_detail::translation_mat_<A> const &>(a);
0602 }
0603
0604 template <class A>
0605 typename enable_if_c<
0606 is_vec<A>::value,
0607 qvm_detail::translation_mat_<A> &>::type
0608 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0609 translation_mat( A & a )
0610 {
0611 return reinterpret_cast<typename qvm_detail::translation_mat_<A> &>(a);
0612 }
0613
0614
0615
0616 namespace
0617 qvm_detail
0618 {
0619 template <class OriginalVector>
0620 class
0621 diag_mat_
0622 {
0623 diag_mat_( diag_mat_ const & );
0624 diag_mat_ & operator=( diag_mat_ const & );
0625 ~diag_mat_();
0626
0627 public:
0628
0629 template <class T>
0630 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0631 diag_mat_ &
0632 operator=( T const & x )
0633 {
0634 assign(*this,x);
0635 return *this;
0636 }
0637
0638 template <class R
0639 #if __cplusplus >= 201103L
0640 , class = typename enable_if<is_mat<R> >::type
0641 #endif
0642 >
0643 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0644 operator R() const
0645 {
0646 R r;
0647 assign(r,*this);
0648 return r;
0649 }
0650 };
0651
0652 template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
0653 struct diag_mat_write_traits;
0654
0655 template <class OriginalVector>
0656 struct
0657 diag_mat_write_traits<OriginalVector,true>
0658 {
0659 typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
0660 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0661 static int const rows=vec_traits<OriginalVector>::dim;
0662 static int const cols=vec_traits<OriginalVector>::dim;
0663
0664 template <int Row,int Col>
0665 static
0666 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0667 scalar_type &
0668 write_element( this_matrix & x )
0669 {
0670 BOOST_QVM_STATIC_ASSERT(Row>=0);
0671 BOOST_QVM_STATIC_ASSERT(Row<rows);
0672 BOOST_QVM_STATIC_ASSERT(Row==Col);
0673 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
0674 }
0675
0676 static
0677 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0678 scalar_type &
0679 write_element_idx( int row, int col, this_matrix & x )
0680 {
0681 BOOST_QVM_ASSERT(row>=0);
0682 BOOST_QVM_ASSERT(row<rows);
0683 BOOST_QVM_ASSERT(row==col);
0684 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
0685 }
0686 };
0687
0688 template <class OriginalVector>
0689 struct
0690 diag_mat_write_traits<OriginalVector,false>
0691 {
0692 typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
0693 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0694 static int const rows=vec_traits<OriginalVector>::dim;
0695 static int const cols=vec_traits<OriginalVector>::dim;
0696
0697 template <int Row,int Col>
0698 static
0699 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0700 void
0701 write_element( this_matrix & x, scalar_type s )
0702 {
0703 BOOST_QVM_STATIC_ASSERT(Row>=0);
0704 BOOST_QVM_STATIC_ASSERT(Row<rows);
0705 BOOST_QVM_STATIC_ASSERT(Row==Col);
0706 vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
0707 }
0708
0709 static
0710 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0711 void
0712 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0713 {
0714 BOOST_QVM_ASSERT(row>=0);
0715 BOOST_QVM_ASSERT(row<rows);
0716 BOOST_QVM_ASSERT(row==col);
0717 vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
0718 }
0719 };
0720 }
0721
0722 template <class OriginalVector>
0723 struct
0724 mat_traits< qvm_detail::diag_mat_<OriginalVector> >:
0725 qvm_detail::diag_mat_write_traits<OriginalVector>
0726 {
0727 typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
0728 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0729 static int const rows=vec_traits<OriginalVector>::dim;
0730 static int const cols=vec_traits<OriginalVector>::dim;
0731
0732 template <int Row,int Col>
0733 static
0734 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0735 scalar_type
0736 read_element( this_matrix const & x )
0737 {
0738 BOOST_QVM_STATIC_ASSERT(Row>=0);
0739 BOOST_QVM_STATIC_ASSERT(Row<rows);
0740 BOOST_QVM_STATIC_ASSERT(Col>=0);
0741 BOOST_QVM_STATIC_ASSERT(Col<cols);
0742 return Row==Col?vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
0743 }
0744
0745 static
0746 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0747 scalar_type
0748 read_element_idx( int row, int col, this_matrix const & x )
0749 {
0750 BOOST_QVM_ASSERT(row>=0);
0751 BOOST_QVM_ASSERT(row<rows);
0752 BOOST_QVM_ASSERT(col>=0);
0753 BOOST_QVM_ASSERT(col<cols);
0754 return row==col?vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
0755 }
0756 };
0757
0758 template <class OriginalVector,int R,int C>
0759 struct
0760 deduce_mat<qvm_detail::diag_mat_<OriginalVector>,R,C>
0761 {
0762 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0763 };
0764
0765 template <class OriginalVector,int R,int C>
0766 struct
0767 deduce_mat2<qvm_detail::diag_mat_<OriginalVector>,qvm_detail::diag_mat_<OriginalVector>,R,C>
0768 {
0769 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0770 };
0771
0772 template <class A>
0773 typename enable_if_c<
0774 is_vec<A>::value,
0775 qvm_detail::diag_mat_<A> const &>::type
0776 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0777 diag_mat( A const & a )
0778 {
0779 return reinterpret_cast<typename qvm_detail::diag_mat_<A> const &>(a);
0780 }
0781
0782 template <class A>
0783 typename enable_if_c<
0784 is_vec<A>::value,
0785 qvm_detail::diag_mat_<A> &>::type
0786 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0787 diag_mat( A & a )
0788 {
0789 return reinterpret_cast<typename qvm_detail::diag_mat_<A> &>(a);
0790 }
0791
0792 } }
0793
0794 #endif