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_5265FC7CA1C011DE9EBDFFA956D89593 7 #define BOOST_QVM_5265FC7CA1C011DE9EBDFFA956D89593 8 9 #include <boost/qvm/inline.hpp> 10 #include <boost/qvm/mat_traits.hpp> 11 #include <boost/qvm/deduce_vec.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 <int Col,class OriginalMatrix> 27 class 28 col_ 29 { 30 col_( col_ const & ); 31 col_ & operator=( col_ const & ); 32 ~col_(); 33 34 public: 35 36 template <class T> 37 BOOST_QVM_INLINE_TRIVIAL 38 col_ & 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 Col,class OriginalMatrix> 57 struct 58 vec_traits< qvm_detail::col_<Col,OriginalMatrix> > 59 { 60 typedef qvm_detail::col_<Col,OriginalMatrix> this_vector; 61 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 62 static int const dim=mat_traits<OriginalMatrix>::rows; 63 BOOST_QVM_STATIC_ASSERT(Col>=0); 64 BOOST_QVM_STATIC_ASSERT(Col<mat_traits<OriginalMatrix>::cols); 65 66 template <int I> 67 static 68 BOOST_QVM_INLINE_CRITICAL 69 scalar_type read_elementboost::qvm::vec_traits70 read_element( this_vector const & x ) 71 { 72 BOOST_QVM_STATIC_ASSERT(I>=0); 73 BOOST_QVM_STATIC_ASSERT(I<dim); 74 return mat_traits<OriginalMatrix>::template read_element<I,Col>(reinterpret_cast<OriginalMatrix const &>(x)); 75 } 76 77 template <int I> 78 static 79 BOOST_QVM_INLINE_CRITICAL 80 scalar_type & write_elementboost::qvm::vec_traits81 write_element( this_vector & x ) 82 { 83 BOOST_QVM_STATIC_ASSERT(I>=0); 84 BOOST_QVM_STATIC_ASSERT(I<dim); 85 return mat_traits<OriginalMatrix>::template write_element<I,Col>(reinterpret_cast<OriginalMatrix &>(x)); 86 } 87 88 static 89 BOOST_QVM_INLINE_CRITICAL 90 scalar_type read_element_idxboost::qvm::vec_traits91 read_element_idx( int i, this_vector const & x ) 92 { 93 BOOST_QVM_ASSERT(i>=0); 94 BOOST_QVM_ASSERT(i<dim); 95 return mat_traits<OriginalMatrix>::read_element_idx(i,Col,reinterpret_cast<OriginalMatrix const &>(x)); 96 } 97 98 static 99 BOOST_QVM_INLINE_CRITICAL 100 scalar_type & write_element_idxboost::qvm::vec_traits101 write_element_idx( int i, this_vector & x ) 102 { 103 BOOST_QVM_ASSERT(i>=0); 104 BOOST_QVM_ASSERT(i<dim); 105 return mat_traits<OriginalMatrix>::write_element_idx(i,Col,reinterpret_cast<OriginalMatrix &>(x)); 106 } 107 }; 108 109 template <int Col,class OriginalMatrix,int D> 110 struct 111 deduce_vec<qvm_detail::col_<Col,OriginalMatrix>,D> 112 { 113 typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type; 114 }; 115 116 template <int Col,class OriginalMatrix,int D> 117 struct 118 deduce_vec2<qvm_detail::col_<Col,OriginalMatrix>,qvm_detail::col_<Col,OriginalMatrix>,D> 119 { 120 typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type; 121 }; 122 123 template <int Col,class A> 124 typename boost::enable_if_c< 125 is_mat<A>::value, 126 qvm_detail::col_<Col,A> const &>::type 127 BOOST_QVM_INLINE_TRIVIAL col(A const & a)128 col( A const & a ) 129 { 130 return reinterpret_cast<typename qvm_detail::col_<Col,A> const &>(a); 131 } 132 133 template <int Col,class A> 134 typename boost::enable_if_c< 135 is_mat<A>::value, 136 qvm_detail::col_<Col,A> &>::type 137 BOOST_QVM_INLINE_TRIVIAL col(A & a)138 col( A & a ) 139 { 140 return reinterpret_cast<typename qvm_detail::col_<Col,A> &>(a); 141 } 142 143 //////////////////////////////////////////////// 144 145 namespace 146 qvm_detail 147 { 148 template <int Row,class OriginalMatrix> 149 class 150 row_ 151 { 152 row_( row_ const & ); 153 row_ & operator=( row_ const & ); 154 ~row_(); 155 156 public: 157 158 template <class T> 159 BOOST_QVM_INLINE_TRIVIAL 160 row_ & operator =(T const & x)161 operator=( T const & x ) 162 { 163 assign(*this,x); 164 return *this; 165 } 166 167 template <class R> 168 BOOST_QVM_INLINE_TRIVIAL operator R() const169 operator R() const 170 { 171 R r; 172 assign(r,*this); 173 return r; 174 } 175 }; 176 } 177 178 template <int Row,class OriginalMatrix> 179 struct 180 vec_traits< qvm_detail::row_<Row,OriginalMatrix> > 181 { 182 typedef qvm_detail::row_<Row,OriginalMatrix> this_vector; 183 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 184 static int const dim=mat_traits<OriginalMatrix>::cols; 185 BOOST_QVM_STATIC_ASSERT(Row>=0); 186 BOOST_QVM_STATIC_ASSERT(Row<mat_traits<OriginalMatrix>::rows); 187 188 template <int I> 189 static 190 BOOST_QVM_INLINE_CRITICAL 191 scalar_type read_elementboost::qvm::vec_traits192 read_element( this_vector const & x ) 193 { 194 BOOST_QVM_STATIC_ASSERT(I>=0); 195 BOOST_QVM_STATIC_ASSERT(I<dim); 196 return mat_traits<OriginalMatrix>::template read_element<Row,I>(reinterpret_cast<OriginalMatrix const &>(x)); 197 } 198 199 template <int I> 200 static 201 BOOST_QVM_INLINE_CRITICAL 202 scalar_type & write_elementboost::qvm::vec_traits203 write_element( this_vector & x ) 204 { 205 BOOST_QVM_STATIC_ASSERT(I>=0); 206 BOOST_QVM_STATIC_ASSERT(I<dim); 207 return mat_traits<OriginalMatrix>::template write_element<Row,I>(reinterpret_cast<OriginalMatrix &>(x)); 208 } 209 210 static 211 BOOST_QVM_INLINE_CRITICAL 212 scalar_type read_element_idxboost::qvm::vec_traits213 read_element_idx( int i, this_vector const & x ) 214 { 215 BOOST_QVM_ASSERT(i>=0); 216 BOOST_QVM_ASSERT(i<dim); 217 return mat_traits<OriginalMatrix>::read_element_idx(Row,i,reinterpret_cast<OriginalMatrix const &>(x)); 218 } 219 220 static 221 BOOST_QVM_INLINE_CRITICAL 222 scalar_type & write_element_idxboost::qvm::vec_traits223 write_element_idx( int i, this_vector & x ) 224 { 225 BOOST_QVM_ASSERT(i>=0); 226 BOOST_QVM_ASSERT(i<dim); 227 return mat_traits<OriginalMatrix>::write_element_idx(Row,i,reinterpret_cast<OriginalMatrix &>(x)); 228 } 229 }; 230 231 template <int Row,class OriginalMatrix,int D> 232 struct 233 deduce_vec<qvm_detail::row_<Row,OriginalMatrix>,D> 234 { 235 typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type; 236 }; 237 238 template <int Row,class OriginalMatrix,int D> 239 struct 240 deduce_vec2<qvm_detail::row_<Row,OriginalMatrix>,qvm_detail::row_<Row,OriginalMatrix>,D> 241 { 242 typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type; 243 }; 244 245 template <int Row,class A> 246 typename boost::enable_if_c< 247 is_mat<A>::value, 248 qvm_detail::row_<Row,A> const &>::type 249 BOOST_QVM_INLINE_TRIVIAL row(A const & a)250 row( A const & a ) 251 { 252 return reinterpret_cast<typename qvm_detail::row_<Row,A> const &>(a); 253 } 254 255 template <int Row,class A> 256 typename boost::enable_if_c< 257 is_mat<A>::value, 258 qvm_detail::row_<Row,A> &>::type 259 BOOST_QVM_INLINE_TRIVIAL row(A & a)260 row( A & a ) 261 { 262 return reinterpret_cast<typename qvm_detail::row_<Row,A> &>(a); 263 } 264 265 //////////////////////////////////////////////// 266 267 namespace 268 qvm_detail 269 { 270 template <class OriginalMatrix> 271 class 272 diag_ 273 { 274 diag_( diag_ const & ); 275 diag_ & operator=( diag_ const & ); 276 ~diag_(); 277 278 public: 279 280 template <class T> 281 BOOST_QVM_INLINE_TRIVIAL 282 diag_ & operator =(T const & x)283 operator=( T const & x ) 284 { 285 assign(*this,x); 286 return *this; 287 } 288 289 template <class R> 290 BOOST_QVM_INLINE_TRIVIAL operator R() const291 operator R() const 292 { 293 R r; 294 assign(r,*this); 295 return r; 296 } 297 }; 298 299 template <int X,int Y,bool Which> 300 struct diag_bool_dispatch; 301 302 template <int X,int Y> 303 struct 304 diag_bool_dispatch<X,Y,true> 305 { 306 static int const value=X; 307 }; 308 309 template <int X,int Y> 310 struct 311 diag_bool_dispatch<X,Y,false> 312 { 313 static int const value=Y; 314 }; 315 } 316 317 template <class OriginalMatrix> 318 struct 319 vec_traits< qvm_detail::diag_<OriginalMatrix> > 320 { 321 typedef qvm_detail::diag_<OriginalMatrix> this_vector; 322 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 323 static int const dim=qvm_detail::diag_bool_dispatch< 324 mat_traits<OriginalMatrix>::rows, 325 mat_traits<OriginalMatrix>::cols, 326 mat_traits<OriginalMatrix>::rows<=mat_traits<OriginalMatrix>::cols>::value; 327 328 template <int I> 329 static 330 BOOST_QVM_INLINE_CRITICAL 331 scalar_type read_elementboost::qvm::vec_traits332 read_element( this_vector const & x ) 333 { 334 BOOST_QVM_STATIC_ASSERT(I>=0); 335 BOOST_QVM_STATIC_ASSERT(I<dim); 336 return mat_traits<OriginalMatrix>::template read_element<I,I>(reinterpret_cast<OriginalMatrix const &>(x)); 337 } 338 339 template <int I> 340 static 341 BOOST_QVM_INLINE_CRITICAL 342 scalar_type & write_elementboost::qvm::vec_traits343 write_element( this_vector & x ) 344 { 345 BOOST_QVM_STATIC_ASSERT(I>=0); 346 BOOST_QVM_STATIC_ASSERT(I<dim); 347 return mat_traits<OriginalMatrix>::template write_element<I,I>(reinterpret_cast<OriginalMatrix &>(x)); 348 } 349 350 static 351 BOOST_QVM_INLINE_CRITICAL 352 scalar_type read_element_idxboost::qvm::vec_traits353 read_element_idx( int i, this_vector const & x ) 354 { 355 BOOST_QVM_ASSERT(i>=0); 356 BOOST_QVM_ASSERT(i<dim); 357 return mat_traits<OriginalMatrix>::read_element_idx(i,i,reinterpret_cast<OriginalMatrix const &>(x)); 358 } 359 360 static 361 BOOST_QVM_INLINE_CRITICAL 362 scalar_type & write_element_idxboost::qvm::vec_traits363 write_element_idx( int i, this_vector & x ) 364 { 365 BOOST_QVM_ASSERT(i>=0); 366 BOOST_QVM_ASSERT(i<dim); 367 return mat_traits<OriginalMatrix>::write_element_idx(i,i,reinterpret_cast<OriginalMatrix &>(x)); 368 } 369 }; 370 371 template <class OriginalMatrix,int D> 372 struct 373 deduce_vec<qvm_detail::diag_<OriginalMatrix>,D> 374 { 375 typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type; 376 }; 377 378 template <class OriginalMatrix,int D> 379 struct 380 deduce_vec2<qvm_detail::diag_<OriginalMatrix>,qvm_detail::diag_<OriginalMatrix>,D> 381 { 382 typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type; 383 }; 384 385 template <class A> 386 typename boost::enable_if_c< 387 is_mat<A>::value, 388 qvm_detail::diag_<A> const &>::type 389 BOOST_QVM_INLINE_TRIVIAL diag(A const & a)390 diag( A const & a ) 391 { 392 return reinterpret_cast<typename qvm_detail::diag_<A> const &>(a); 393 } 394 395 template <class A> 396 typename boost::enable_if_c< 397 is_mat<A>::value, 398 qvm_detail::diag_<A> &>::type 399 BOOST_QVM_INLINE_TRIVIAL diag(A & a)400 diag( A & a ) 401 { 402 return reinterpret_cast<typename qvm_detail::diag_<A> &>(a); 403 } 404 405 //////////////////////////////////////////////// 406 407 namespace 408 qvm_detail 409 { 410 template <class OriginalMatrix> 411 class 412 translation_ 413 { 414 translation_( translation_ const & ); 415 ~translation_(); 416 417 public: 418 419 translation_ & operator =(translation_ const & x)420 operator=( translation_ const & x ) 421 { 422 assign(*this,x); 423 return *this; 424 } 425 426 template <class T> 427 BOOST_QVM_INLINE_TRIVIAL 428 translation_ & operator =(T const & x)429 operator=( T const & x ) 430 { 431 assign(*this,x); 432 return *this; 433 } 434 435 template <class R> 436 BOOST_QVM_INLINE_TRIVIAL operator R() const437 operator R() const 438 { 439 R r; 440 assign(r,*this); 441 return r; 442 } 443 }; 444 } 445 446 template <class OriginalMatrix> 447 struct 448 vec_traits< qvm_detail::translation_<OriginalMatrix> > 449 { 450 typedef qvm_detail::translation_<OriginalMatrix> this_vector; 451 typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type; 452 static int const dim=mat_traits<OriginalMatrix>::rows-1; 453 BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::rows==mat_traits<OriginalMatrix>::cols); 454 BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::rows>=3); 455 456 template <int I> 457 static 458 BOOST_QVM_INLINE_CRITICAL 459 scalar_type read_elementboost::qvm::vec_traits460 read_element( this_vector const & x ) 461 { 462 BOOST_QVM_STATIC_ASSERT(I>=0); 463 BOOST_QVM_STATIC_ASSERT(I<dim); 464 return mat_traits<OriginalMatrix>::template read_element<I,dim>(reinterpret_cast<OriginalMatrix const &>(x)); 465 } 466 467 template <int I> 468 static 469 BOOST_QVM_INLINE_CRITICAL 470 scalar_type & write_elementboost::qvm::vec_traits471 write_element( this_vector & x ) 472 { 473 BOOST_QVM_STATIC_ASSERT(I>=0); 474 BOOST_QVM_STATIC_ASSERT(I<dim); 475 return mat_traits<OriginalMatrix>::template write_element<I,dim>(reinterpret_cast<OriginalMatrix &>(x)); 476 } 477 478 static 479 BOOST_QVM_INLINE_CRITICAL 480 scalar_type read_element_idxboost::qvm::vec_traits481 read_element_idx( int i, this_vector const & x ) 482 { 483 BOOST_QVM_ASSERT(i>=0); 484 BOOST_QVM_ASSERT(i<dim); 485 return mat_traits<OriginalMatrix>::read_element_idx(i,dim,reinterpret_cast<OriginalMatrix const &>(x)); 486 } 487 488 static 489 BOOST_QVM_INLINE_CRITICAL 490 scalar_type & write_element_idxboost::qvm::vec_traits491 write_element_idx( int i, this_vector & x ) 492 { 493 BOOST_QVM_ASSERT(i>=0); 494 BOOST_QVM_ASSERT(i<dim); 495 return mat_traits<OriginalMatrix>::write_element_idx(i,dim,reinterpret_cast<OriginalMatrix &>(x)); 496 } 497 }; 498 499 template <class OriginalMatrix,int D> 500 struct 501 deduce_vec<qvm_detail::translation_<OriginalMatrix>,D> 502 { 503 typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type; 504 }; 505 506 template <class OriginalMatrix,int D> 507 struct 508 deduce_vec2<qvm_detail::translation_<OriginalMatrix>,qvm_detail::translation_<OriginalMatrix>,D> 509 { 510 typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type; 511 }; 512 513 template <class A> 514 typename boost::enable_if_c< 515 is_mat<A>::value && mat_traits<A>::rows==mat_traits<A>::cols && mat_traits<A>::rows>=3, 516 qvm_detail::translation_<A> const &>::type 517 BOOST_QVM_INLINE_TRIVIAL 518 translation( A const & a ) 519 { 520 return reinterpret_cast<typename qvm_detail::translation_<A> const &>(a); 521 } 522 523 template <class A> 524 typename boost::enable_if_c< 525 is_mat<A>::value && mat_traits<A>::rows==mat_traits<A>::cols && mat_traits<A>::rows>=3, 526 qvm_detail::translation_<A> &>::type 527 BOOST_QVM_INLINE_TRIVIAL 528 translation( A & a ) 529 { 530 return reinterpret_cast<typename qvm_detail::translation_<A> &>(a); 531 } 532 533 //////////////////////////////////////////////// 534 } 535 } 536 537 #endif 538