map_mat_vec.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. #ifndef BOOST_QVM_MAP_MAT_VEC_HPP_INCLUDED
  2. #define BOOST_QVM_MAP_MAT_VEC_HPP_INCLUDED
  3. // Copyright 2008-2022 Emil Dotchevski and Reverge Studios, Inc.
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/qvm/config.hpp>
  7. #include <boost/qvm/mat_traits.hpp>
  8. #include <boost/qvm/deduce_vec.hpp>
  9. #include <boost/qvm/assert.hpp>
  10. #include <boost/qvm/enable_if.hpp>
  11. namespace boost { namespace qvm {
  12. namespace
  13. qvm_detail
  14. {
  15. template <int Col,class OriginalMatrix>
  16. class
  17. col_
  18. {
  19. col_( col_ const & );
  20. col_ & operator=( col_ const & );
  21. ~col_();
  22. public:
  23. template <class T>
  24. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  25. col_ &
  26. operator=( T const & x )
  27. {
  28. assign(*this,x);
  29. return *this;
  30. }
  31. template <class R
  32. #if __cplusplus >= 201103L
  33. , class = typename enable_if<is_vec<R> >::type
  34. #endif
  35. >
  36. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  37. operator R() const
  38. {
  39. R r;
  40. assign(r,*this);
  41. return r;
  42. }
  43. };
  44. template <int Col,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
  45. struct col_write_traits;
  46. template <int Col,class OriginalMatrix>
  47. struct
  48. col_write_traits<Col,OriginalMatrix,true>
  49. {
  50. typedef qvm_detail::col_<Col,OriginalMatrix> this_vector;
  51. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  52. static int const dim=mat_traits<OriginalMatrix>::rows;
  53. BOOST_QVM_STATIC_ASSERT(Col>=0);
  54. BOOST_QVM_STATIC_ASSERT(Col<mat_traits<OriginalMatrix>::cols);
  55. template <int I>
  56. static
  57. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  58. scalar_type &
  59. write_element( this_vector & x )
  60. {
  61. BOOST_QVM_STATIC_ASSERT(I>=0);
  62. BOOST_QVM_STATIC_ASSERT(I<dim);
  63. return mat_traits<OriginalMatrix>::template write_element<I,Col>(reinterpret_cast<OriginalMatrix &>(x));
  64. }
  65. static
  66. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  67. scalar_type &
  68. write_element_idx( int i, this_vector & x )
  69. {
  70. BOOST_QVM_ASSERT(i>=0);
  71. BOOST_QVM_ASSERT(i<dim);
  72. return mat_traits<OriginalMatrix>::write_element_idx(i,Col,reinterpret_cast<OriginalMatrix &>(x));
  73. }
  74. };
  75. template <int Col,class OriginalMatrix>
  76. struct
  77. col_write_traits<Col,OriginalMatrix,false>
  78. {
  79. typedef qvm_detail::col_<Col,OriginalMatrix> this_vector;
  80. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  81. static int const dim=mat_traits<OriginalMatrix>::rows;
  82. BOOST_QVM_STATIC_ASSERT(Col>=0);
  83. BOOST_QVM_STATIC_ASSERT(Col<mat_traits<OriginalMatrix>::cols);
  84. template <int I>
  85. static
  86. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  87. void
  88. write_element( this_vector & x, scalar_type s )
  89. {
  90. BOOST_QVM_STATIC_ASSERT(I>=0);
  91. BOOST_QVM_STATIC_ASSERT(I<dim);
  92. mat_traits<OriginalMatrix>::template write_element<I,Col>(reinterpret_cast<OriginalMatrix &>(x), s);
  93. }
  94. static
  95. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  96. void
  97. write_element_idx( int i, this_vector & x, scalar_type s )
  98. {
  99. BOOST_QVM_ASSERT(i>=0);
  100. BOOST_QVM_ASSERT(i<dim);
  101. mat_traits<OriginalMatrix>::write_element_idx(i,Col,reinterpret_cast<OriginalMatrix &>(x), s);
  102. }
  103. };
  104. }
  105. template <int Col,class OriginalMatrix>
  106. struct
  107. vec_traits< qvm_detail::col_<Col,OriginalMatrix> >:
  108. qvm_detail::col_write_traits<Col,OriginalMatrix>
  109. {
  110. typedef qvm_detail::col_<Col,OriginalMatrix> this_vector;
  111. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  112. static int const dim=mat_traits<OriginalMatrix>::rows;
  113. BOOST_QVM_STATIC_ASSERT(Col>=0);
  114. BOOST_QVM_STATIC_ASSERT(Col<mat_traits<OriginalMatrix>::cols);
  115. template <int I>
  116. static
  117. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  118. scalar_type
  119. read_element( this_vector const & x )
  120. {
  121. BOOST_QVM_STATIC_ASSERT(I>=0);
  122. BOOST_QVM_STATIC_ASSERT(I<dim);
  123. return mat_traits<OriginalMatrix>::template read_element<I,Col>(reinterpret_cast<OriginalMatrix const &>(x));
  124. }
  125. static
  126. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  127. scalar_type
  128. read_element_idx( int i, this_vector const & x )
  129. {
  130. BOOST_QVM_ASSERT(i>=0);
  131. BOOST_QVM_ASSERT(i<dim);
  132. return mat_traits<OriginalMatrix>::read_element_idx(i,Col,reinterpret_cast<OriginalMatrix const &>(x));
  133. }
  134. };
  135. template <int Col,class OriginalMatrix,int D>
  136. struct
  137. deduce_vec<qvm_detail::col_<Col,OriginalMatrix>,D>
  138. {
  139. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  140. };
  141. template <int Col,class OriginalMatrix,int D>
  142. struct
  143. deduce_vec2<qvm_detail::col_<Col,OriginalMatrix>,qvm_detail::col_<Col,OriginalMatrix>,D>
  144. {
  145. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  146. };
  147. template <int Col,class A>
  148. typename enable_if_c<
  149. is_mat<A>::value,
  150. qvm_detail::col_<Col,A> const &>::type
  151. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  152. col( A const & a )
  153. {
  154. return reinterpret_cast<typename qvm_detail::col_<Col,A> const &>(a);
  155. }
  156. template <int Col,class A>
  157. typename enable_if_c<
  158. is_mat<A>::value,
  159. qvm_detail::col_<Col,A> &>::type
  160. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  161. col( A & a )
  162. {
  163. return reinterpret_cast<typename qvm_detail::col_<Col,A> &>(a);
  164. }
  165. ////////////////////////////////////////////////
  166. namespace
  167. qvm_detail
  168. {
  169. template <int Row,class OriginalMatrix>
  170. class
  171. row_
  172. {
  173. row_( row_ const & );
  174. row_ & operator=( row_ const & );
  175. ~row_();
  176. public:
  177. template <class T>
  178. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  179. row_ &
  180. operator=( T const & x )
  181. {
  182. assign(*this,x);
  183. return *this;
  184. }
  185. template <class R
  186. #if __cplusplus >= 201103L
  187. , class = typename enable_if<is_vec<R> >::type
  188. #endif
  189. >
  190. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  191. operator R() const
  192. {
  193. R r;
  194. assign(r,*this);
  195. return r;
  196. }
  197. };
  198. template <int Row,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
  199. struct row_write_traits;
  200. template <int Row,class OriginalMatrix>
  201. struct
  202. row_write_traits<Row,OriginalMatrix,true>
  203. {
  204. typedef qvm_detail::row_<Row,OriginalMatrix> this_vector;
  205. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  206. static int const dim=mat_traits<OriginalMatrix>::cols;
  207. BOOST_QVM_STATIC_ASSERT(Row>=0);
  208. BOOST_QVM_STATIC_ASSERT(Row<mat_traits<OriginalMatrix>::rows);
  209. template <int I>
  210. static
  211. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  212. scalar_type &
  213. write_element( this_vector & x )
  214. {
  215. BOOST_QVM_STATIC_ASSERT(I>=0);
  216. BOOST_QVM_STATIC_ASSERT(I<dim);
  217. return mat_traits<OriginalMatrix>::template write_element<Row,I>(reinterpret_cast<OriginalMatrix &>(x));
  218. }
  219. static
  220. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  221. scalar_type &
  222. write_element_idx( int i, this_vector & x )
  223. {
  224. BOOST_QVM_ASSERT(i>=0);
  225. BOOST_QVM_ASSERT(i<dim);
  226. return mat_traits<OriginalMatrix>::write_element_idx(Row,i,reinterpret_cast<OriginalMatrix &>(x));
  227. }
  228. };
  229. template <int Row,class OriginalMatrix>
  230. struct
  231. row_write_traits<Row,OriginalMatrix,false>
  232. {
  233. typedef qvm_detail::row_<Row,OriginalMatrix> this_vector;
  234. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  235. static int const dim=mat_traits<OriginalMatrix>::cols;
  236. BOOST_QVM_STATIC_ASSERT(Row>=0);
  237. BOOST_QVM_STATIC_ASSERT(Row<mat_traits<OriginalMatrix>::rows);
  238. template <int I>
  239. static
  240. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  241. void
  242. write_element( this_vector & x, scalar_type s )
  243. {
  244. BOOST_QVM_STATIC_ASSERT(I>=0);
  245. BOOST_QVM_STATIC_ASSERT(I<dim);
  246. mat_traits<OriginalMatrix>::template write_element<Row,I>(reinterpret_cast<OriginalMatrix &>(x), s);
  247. }
  248. static
  249. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  250. void
  251. write_element_idx( int i, this_vector & x, scalar_type s )
  252. {
  253. BOOST_QVM_ASSERT(i>=0);
  254. BOOST_QVM_ASSERT(i<dim);
  255. mat_traits<OriginalMatrix>::write_element_idx(Row,i,reinterpret_cast<OriginalMatrix &>(x), s);
  256. }
  257. };
  258. }
  259. template <int Row,class OriginalMatrix>
  260. struct
  261. vec_traits< qvm_detail::row_<Row,OriginalMatrix> >:
  262. qvm_detail::row_write_traits<Row,OriginalMatrix>
  263. {
  264. typedef qvm_detail::row_<Row,OriginalMatrix> this_vector;
  265. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  266. static int const dim=mat_traits<OriginalMatrix>::cols;
  267. BOOST_QVM_STATIC_ASSERT(Row>=0);
  268. BOOST_QVM_STATIC_ASSERT(Row<mat_traits<OriginalMatrix>::rows);
  269. template <int I>
  270. static
  271. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  272. scalar_type
  273. read_element( this_vector const & x )
  274. {
  275. BOOST_QVM_STATIC_ASSERT(I>=0);
  276. BOOST_QVM_STATIC_ASSERT(I<dim);
  277. return mat_traits<OriginalMatrix>::template read_element<Row,I>(reinterpret_cast<OriginalMatrix const &>(x));
  278. }
  279. static
  280. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  281. scalar_type
  282. read_element_idx( int i, this_vector const & x )
  283. {
  284. BOOST_QVM_ASSERT(i>=0);
  285. BOOST_QVM_ASSERT(i<dim);
  286. return mat_traits<OriginalMatrix>::read_element_idx(Row,i,reinterpret_cast<OriginalMatrix const &>(x));
  287. }
  288. };
  289. template <int Row,class OriginalMatrix,int D>
  290. struct
  291. deduce_vec<qvm_detail::row_<Row,OriginalMatrix>,D>
  292. {
  293. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  294. };
  295. template <int Row,class OriginalMatrix,int D>
  296. struct
  297. deduce_vec2<qvm_detail::row_<Row,OriginalMatrix>,qvm_detail::row_<Row,OriginalMatrix>,D>
  298. {
  299. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  300. };
  301. template <int Row,class A>
  302. typename enable_if_c<
  303. is_mat<A>::value,
  304. qvm_detail::row_<Row,A> const &>::type
  305. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  306. row( A const & a )
  307. {
  308. return reinterpret_cast<typename qvm_detail::row_<Row,A> const &>(a);
  309. }
  310. template <int Row,class A>
  311. typename enable_if_c<
  312. is_mat<A>::value,
  313. qvm_detail::row_<Row,A> &>::type
  314. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  315. row( A & a )
  316. {
  317. return reinterpret_cast<typename qvm_detail::row_<Row,A> &>(a);
  318. }
  319. ////////////////////////////////////////////////
  320. namespace
  321. qvm_detail
  322. {
  323. template <class OriginalMatrix>
  324. class
  325. diag_
  326. {
  327. diag_( diag_ const & );
  328. diag_ & operator=( diag_ const & );
  329. ~diag_();
  330. public:
  331. template <class T>
  332. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  333. diag_ &
  334. operator=( T const & x )
  335. {
  336. assign(*this,x);
  337. return *this;
  338. }
  339. template <class R
  340. #if __cplusplus >= 201103L
  341. , class = typename enable_if<is_vec<R> >::type
  342. #endif
  343. >
  344. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  345. operator R() const
  346. {
  347. R r;
  348. assign(r,*this);
  349. return r;
  350. }
  351. };
  352. template <int X,int Y,bool Which>
  353. struct diag_bool_dispatch;
  354. template <int X,int Y>
  355. struct
  356. diag_bool_dispatch<X,Y,true>
  357. {
  358. static int const value=X;
  359. };
  360. template <int X,int Y>
  361. struct
  362. diag_bool_dispatch<X,Y,false>
  363. {
  364. static int const value=Y;
  365. };
  366. template <class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
  367. struct diag_write_traits;
  368. template <class OriginalMatrix>
  369. struct
  370. diag_write_traits<OriginalMatrix,true>
  371. {
  372. typedef qvm_detail::diag_<OriginalMatrix> this_vector;
  373. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  374. static int const dim=qvm_detail::diag_bool_dispatch<
  375. mat_traits<OriginalMatrix>::rows,
  376. mat_traits<OriginalMatrix>::cols,
  377. mat_traits<OriginalMatrix>::rows<=mat_traits<OriginalMatrix>::cols>::value;
  378. template <int I>
  379. static
  380. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  381. scalar_type &
  382. write_element( this_vector & x )
  383. {
  384. BOOST_QVM_STATIC_ASSERT(I>=0);
  385. BOOST_QVM_STATIC_ASSERT(I<dim);
  386. return mat_traits<OriginalMatrix>::template write_element<I,I>(reinterpret_cast<OriginalMatrix &>(x));
  387. }
  388. static
  389. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  390. scalar_type &
  391. write_element_idx( int i, this_vector & x )
  392. {
  393. BOOST_QVM_ASSERT(i>=0);
  394. BOOST_QVM_ASSERT(i<dim);
  395. return mat_traits<OriginalMatrix>::write_element_idx(i,i,reinterpret_cast<OriginalMatrix &>(x));
  396. }
  397. };
  398. template <class OriginalMatrix>
  399. struct
  400. diag_write_traits<OriginalMatrix,false>
  401. {
  402. typedef qvm_detail::diag_<OriginalMatrix> this_vector;
  403. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  404. static int const dim=qvm_detail::diag_bool_dispatch<
  405. mat_traits<OriginalMatrix>::rows,
  406. mat_traits<OriginalMatrix>::cols,
  407. mat_traits<OriginalMatrix>::rows<=mat_traits<OriginalMatrix>::cols>::value;
  408. template <int I>
  409. static
  410. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  411. void
  412. write_element( this_vector & x, scalar_type s )
  413. {
  414. BOOST_QVM_STATIC_ASSERT(I>=0);
  415. BOOST_QVM_STATIC_ASSERT(I<dim);
  416. mat_traits<OriginalMatrix>::template write_element<I,I>(reinterpret_cast<OriginalMatrix &>(x), s);
  417. }
  418. static
  419. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  420. void
  421. write_element_idx( int i, this_vector & x, scalar_type s )
  422. {
  423. BOOST_QVM_ASSERT(i>=0);
  424. BOOST_QVM_ASSERT(i<dim);
  425. mat_traits<OriginalMatrix>::write_element_idx(i,i,reinterpret_cast<OriginalMatrix &>(x), s);
  426. }
  427. };
  428. }
  429. template <class OriginalMatrix>
  430. struct
  431. vec_traits< qvm_detail::diag_<OriginalMatrix> >:
  432. qvm_detail::diag_write_traits<OriginalMatrix>
  433. {
  434. typedef qvm_detail::diag_<OriginalMatrix> this_vector;
  435. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  436. static int const dim=qvm_detail::diag_bool_dispatch<
  437. mat_traits<OriginalMatrix>::rows,
  438. mat_traits<OriginalMatrix>::cols,
  439. mat_traits<OriginalMatrix>::rows<=mat_traits<OriginalMatrix>::cols>::value;
  440. template <int I>
  441. static
  442. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  443. scalar_type
  444. read_element( this_vector const & x )
  445. {
  446. BOOST_QVM_STATIC_ASSERT(I>=0);
  447. BOOST_QVM_STATIC_ASSERT(I<dim);
  448. return mat_traits<OriginalMatrix>::template read_element<I,I>(reinterpret_cast<OriginalMatrix const &>(x));
  449. }
  450. static
  451. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  452. scalar_type
  453. read_element_idx( int i, this_vector const & x )
  454. {
  455. BOOST_QVM_ASSERT(i>=0);
  456. BOOST_QVM_ASSERT(i<dim);
  457. return mat_traits<OriginalMatrix>::read_element_idx(i,i,reinterpret_cast<OriginalMatrix const &>(x));
  458. }
  459. };
  460. template <class OriginalMatrix,int D>
  461. struct
  462. deduce_vec<qvm_detail::diag_<OriginalMatrix>,D>
  463. {
  464. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  465. };
  466. template <class OriginalMatrix,int D>
  467. struct
  468. deduce_vec2<qvm_detail::diag_<OriginalMatrix>,qvm_detail::diag_<OriginalMatrix>,D>
  469. {
  470. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  471. };
  472. template <class A>
  473. typename enable_if_c<
  474. is_mat<A>::value,
  475. qvm_detail::diag_<A> const &>::type
  476. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  477. diag( A const & a )
  478. {
  479. return reinterpret_cast<typename qvm_detail::diag_<A> const &>(a);
  480. }
  481. template <class A>
  482. typename enable_if_c<
  483. is_mat<A>::value,
  484. qvm_detail::diag_<A> &>::type
  485. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  486. diag( A & a )
  487. {
  488. return reinterpret_cast<typename qvm_detail::diag_<A> &>(a);
  489. }
  490. ////////////////////////////////////////////////
  491. namespace
  492. qvm_detail
  493. {
  494. template <class OriginalMatrix>
  495. class
  496. translation_
  497. {
  498. translation_( translation_ const & );
  499. ~translation_();
  500. public:
  501. translation_ &
  502. operator=( translation_ const & x )
  503. {
  504. assign(*this,x);
  505. return *this;
  506. }
  507. template <class T>
  508. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  509. translation_ &
  510. operator=( T const & x )
  511. {
  512. assign(*this,x);
  513. return *this;
  514. }
  515. template <class R
  516. #if __cplusplus >= 201103L
  517. , class = typename enable_if<is_vec<R> >::type
  518. #endif
  519. >
  520. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  521. operator R() const
  522. {
  523. R r;
  524. assign(r,*this);
  525. return r;
  526. }
  527. };
  528. template <class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
  529. struct translation_write_traits;
  530. template <class OriginalMatrix>
  531. struct
  532. translation_write_traits<OriginalMatrix,true>
  533. {
  534. typedef qvm_detail::translation_<OriginalMatrix> this_vector;
  535. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  536. static int const dim=mat_traits<OriginalMatrix>::cols-1;
  537. BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::rows==mat_traits<OriginalMatrix>::cols || mat_traits<OriginalMatrix>::rows+1==mat_traits<OriginalMatrix>::cols);
  538. BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::cols>=3);
  539. template <int I>
  540. static
  541. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  542. scalar_type &
  543. write_element( this_vector & x )
  544. {
  545. BOOST_QVM_STATIC_ASSERT(I>=0);
  546. BOOST_QVM_STATIC_ASSERT(I<dim);
  547. return mat_traits<OriginalMatrix>::template write_element<I,dim>(reinterpret_cast<OriginalMatrix &>(x));
  548. }
  549. static
  550. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  551. scalar_type &
  552. write_element_idx( int i, this_vector & x )
  553. {
  554. BOOST_QVM_ASSERT(i>=0);
  555. BOOST_QVM_ASSERT(i<dim);
  556. return mat_traits<OriginalMatrix>::write_element_idx(i,dim,reinterpret_cast<OriginalMatrix &>(x));
  557. }
  558. };
  559. template <class OriginalMatrix>
  560. struct
  561. translation_write_traits<OriginalMatrix,false>
  562. {
  563. typedef qvm_detail::translation_<OriginalMatrix> this_vector;
  564. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  565. static int const dim=mat_traits<OriginalMatrix>::cols-1;
  566. BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::rows==mat_traits<OriginalMatrix>::cols || mat_traits<OriginalMatrix>::rows+1==mat_traits<OriginalMatrix>::cols);
  567. BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::cols>=3);
  568. template <int I>
  569. static
  570. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  571. void
  572. write_element( this_vector & x, scalar_type s )
  573. {
  574. BOOST_QVM_STATIC_ASSERT(I>=0);
  575. BOOST_QVM_STATIC_ASSERT(I<dim);
  576. mat_traits<OriginalMatrix>::template write_element<I,dim>(reinterpret_cast<OriginalMatrix &>(x), s);
  577. }
  578. static
  579. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  580. void
  581. write_element_idx( int i, this_vector & x, scalar_type s )
  582. {
  583. BOOST_QVM_ASSERT(i>=0);
  584. BOOST_QVM_ASSERT(i<dim);
  585. mat_traits<OriginalMatrix>::write_element_idx(i,dim,reinterpret_cast<OriginalMatrix &>(x), s);
  586. }
  587. };
  588. }
  589. template <class OriginalMatrix>
  590. struct
  591. vec_traits< qvm_detail::translation_<OriginalMatrix> >:
  592. qvm_detail::translation_write_traits<OriginalMatrix>
  593. {
  594. typedef qvm_detail::translation_<OriginalMatrix> this_vector;
  595. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  596. static int const dim=mat_traits<OriginalMatrix>::cols-1;
  597. BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::rows==mat_traits<OriginalMatrix>::cols || mat_traits<OriginalMatrix>::rows+1==mat_traits<OriginalMatrix>::cols);
  598. BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::cols>=3);
  599. template <int I>
  600. static
  601. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  602. scalar_type
  603. read_element( this_vector const & x )
  604. {
  605. BOOST_QVM_STATIC_ASSERT(I>=0);
  606. BOOST_QVM_STATIC_ASSERT(I<dim);
  607. return mat_traits<OriginalMatrix>::template read_element<I,dim>(reinterpret_cast<OriginalMatrix const &>(x));
  608. }
  609. static
  610. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  611. scalar_type
  612. read_element_idx( int i, this_vector const & x )
  613. {
  614. BOOST_QVM_ASSERT(i>=0);
  615. BOOST_QVM_ASSERT(i<dim);
  616. return mat_traits<OriginalMatrix>::read_element_idx(i,dim,reinterpret_cast<OriginalMatrix const &>(x));
  617. }
  618. };
  619. template <class OriginalMatrix,int D>
  620. struct
  621. deduce_vec<qvm_detail::translation_<OriginalMatrix>,D>
  622. {
  623. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  624. };
  625. template <class OriginalMatrix,int D>
  626. struct
  627. deduce_vec2<qvm_detail::translation_<OriginalMatrix>,qvm_detail::translation_<OriginalMatrix>,D>
  628. {
  629. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  630. };
  631. template <class A>
  632. typename enable_if_c<
  633. is_mat<A>::value && (mat_traits<A>::rows==mat_traits<A>::cols || mat_traits<A>::rows+1==mat_traits<A>::cols) && mat_traits<A>::cols>=3,
  634. qvm_detail::translation_<A> const &>::type
  635. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  636. translation( A const & a )
  637. {
  638. return reinterpret_cast<typename qvm_detail::translation_<A> const &>(a);
  639. }
  640. template <class A>
  641. typename enable_if_c<
  642. is_mat<A>::value && (mat_traits<A>::rows==mat_traits<A>::cols || mat_traits<A>::rows+1==mat_traits<A>::cols) && mat_traits<A>::cols>=3,
  643. qvm_detail::translation_<A> &>::type
  644. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  645. translation( A & a )
  646. {
  647. return reinterpret_cast<typename qvm_detail::translation_<A> &>(a);
  648. }
  649. } }
  650. #endif