map_vec_mat.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. #ifndef BOOST_QVM_MAP_VEC_MAT_HPP_INCLUDED
  2. #define BOOST_QVM_MAP_VEC_MAT_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/deduce_mat.hpp>
  8. #include <boost/qvm/vec_traits.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 <class OriginalVector>
  16. class
  17. col_mat_
  18. {
  19. col_mat_( col_mat_ const & );
  20. col_mat_ & operator=( col_mat_ const & );
  21. ~col_mat_();
  22. public:
  23. template <class T>
  24. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  25. col_mat_ &
  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_mat<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 <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
  45. struct col_mat_write_traits;
  46. template <class OriginalVector>
  47. struct
  48. col_mat_write_traits<OriginalVector,true>
  49. {
  50. typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
  51. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  52. static int const rows=vec_traits<OriginalVector>::dim;
  53. static int const cols=1;
  54. template <int Row,int Col>
  55. static
  56. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  57. scalar_type &
  58. write_element( this_matrix & x )
  59. {
  60. BOOST_QVM_STATIC_ASSERT(Col==0);
  61. BOOST_QVM_STATIC_ASSERT(Row>=0);
  62. BOOST_QVM_STATIC_ASSERT(Row<rows);
  63. return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
  64. }
  65. static
  66. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  67. scalar_type &
  68. write_element_idx( int row, int col, this_matrix & x )
  69. {
  70. BOOST_QVM_ASSERT(col==0);
  71. BOOST_QVM_ASSERT(row>=0);
  72. BOOST_QVM_ASSERT(row<rows);
  73. return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
  74. }
  75. };
  76. template <class OriginalVector>
  77. struct
  78. col_mat_write_traits<OriginalVector,false>
  79. {
  80. typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
  81. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  82. static int const rows=vec_traits<OriginalVector>::dim;
  83. static int const cols=1;
  84. template <int Row,int Col>
  85. static
  86. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  87. void
  88. write_element( this_matrix & x, scalar_type s )
  89. {
  90. BOOST_QVM_STATIC_ASSERT(Col==0);
  91. BOOST_QVM_STATIC_ASSERT(Row>=0);
  92. BOOST_QVM_STATIC_ASSERT(Row<rows);
  93. vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
  94. }
  95. static
  96. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  97. void
  98. write_element_idx( int row, int col, this_matrix & x, scalar_type s )
  99. {
  100. BOOST_QVM_ASSERT(col==0);
  101. BOOST_QVM_ASSERT(row>=0);
  102. BOOST_QVM_ASSERT(row<rows);
  103. vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
  104. }
  105. };
  106. }
  107. template <class OriginalVector>
  108. struct
  109. mat_traits< qvm_detail::col_mat_<OriginalVector> >:
  110. qvm_detail::col_mat_write_traits<OriginalVector>
  111. {
  112. typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
  113. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  114. static int const rows=vec_traits<OriginalVector>::dim;
  115. static int const cols=1;
  116. template <int Row,int Col>
  117. static
  118. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  119. scalar_type
  120. read_element( this_matrix const & x )
  121. {
  122. BOOST_QVM_STATIC_ASSERT(Col==0);
  123. BOOST_QVM_STATIC_ASSERT(Row>=0);
  124. BOOST_QVM_STATIC_ASSERT(Row<rows);
  125. return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
  126. }
  127. static
  128. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  129. scalar_type
  130. read_element_idx( int row, int col, this_matrix const & x )
  131. {
  132. BOOST_QVM_ASSERT(col==0);
  133. BOOST_QVM_ASSERT(row>=0);
  134. BOOST_QVM_ASSERT(row<rows);
  135. return vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x));
  136. }
  137. };
  138. template <class OriginalVector,int R,int C>
  139. struct
  140. deduce_mat<qvm_detail::col_mat_<OriginalVector>,R,C>
  141. {
  142. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  143. };
  144. template <class OriginalVector,int R,int C>
  145. struct
  146. deduce_mat2<qvm_detail::col_mat_<OriginalVector>,qvm_detail::col_mat_<OriginalVector>,R,C>
  147. {
  148. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  149. };
  150. template <class A>
  151. typename enable_if_c<
  152. is_vec<A>::value,
  153. qvm_detail::col_mat_<A> const &>::type
  154. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  155. col_mat( A const & a )
  156. {
  157. return reinterpret_cast<typename qvm_detail::col_mat_<A> const &>(a);
  158. }
  159. template <class A>
  160. typename enable_if_c<
  161. is_vec<A>::value,
  162. qvm_detail::col_mat_<A> &>::type
  163. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  164. col_mat( A & a )
  165. {
  166. return reinterpret_cast<typename qvm_detail::col_mat_<A> &>(a);
  167. }
  168. ////////////////////////////////////////////////
  169. namespace
  170. qvm_detail
  171. {
  172. template <class OriginalVector>
  173. class
  174. row_mat_
  175. {
  176. row_mat_( row_mat_ const & );
  177. row_mat_ & operator=( row_mat_ const & );
  178. ~row_mat_();
  179. public:
  180. template <class T>
  181. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  182. row_mat_ &
  183. operator=( T const & x )
  184. {
  185. assign(*this,x);
  186. return *this;
  187. }
  188. template <class R
  189. #if __cplusplus >= 201103L
  190. , class = typename enable_if<is_mat<R> >::type
  191. #endif
  192. >
  193. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  194. operator R() const
  195. {
  196. R r;
  197. assign(r,*this);
  198. return r;
  199. }
  200. };
  201. template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
  202. struct row_mat_write_traits;
  203. template <class OriginalVector>
  204. struct
  205. row_mat_write_traits<OriginalVector,true>
  206. {
  207. typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
  208. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  209. static int const rows=1;
  210. static int const cols=vec_traits<OriginalVector>::dim;
  211. template <int Row,int Col>
  212. static
  213. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  214. scalar_type &
  215. write_element( this_matrix & x )
  216. {
  217. BOOST_QVM_STATIC_ASSERT(Row==0);
  218. BOOST_QVM_STATIC_ASSERT(Col>=0);
  219. BOOST_QVM_STATIC_ASSERT(Col<cols);
  220. return vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x));
  221. }
  222. static
  223. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  224. scalar_type &
  225. write_element_idx( int row, int col, this_matrix & x )
  226. {
  227. BOOST_QVM_ASSERT(row==0);
  228. BOOST_QVM_ASSERT(col>=0);
  229. BOOST_QVM_ASSERT(col<cols);
  230. return vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x));
  231. }
  232. };
  233. template <class OriginalVector>
  234. struct
  235. row_mat_write_traits<OriginalVector,false>
  236. {
  237. typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
  238. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  239. static int const rows=1;
  240. static int const cols=vec_traits<OriginalVector>::dim;
  241. template <int Row,int Col>
  242. static
  243. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  244. void
  245. write_element( this_matrix & x, scalar_type s )
  246. {
  247. BOOST_QVM_STATIC_ASSERT(Row==0);
  248. BOOST_QVM_STATIC_ASSERT(Col>=0);
  249. BOOST_QVM_STATIC_ASSERT(Col<cols);
  250. vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x), s);
  251. }
  252. static
  253. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  254. void
  255. write_element_idx( int row, int col, this_matrix & x, scalar_type s )
  256. {
  257. BOOST_QVM_ASSERT(row==0);
  258. BOOST_QVM_ASSERT(col>=0);
  259. BOOST_QVM_ASSERT(col<cols);
  260. vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x), s);
  261. }
  262. };
  263. }
  264. template <class OriginalVector>
  265. struct
  266. mat_traits< qvm_detail::row_mat_<OriginalVector> >:
  267. qvm_detail::row_mat_write_traits<OriginalVector>
  268. {
  269. typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
  270. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  271. static int const rows=1;
  272. static int const cols=vec_traits<OriginalVector>::dim;
  273. template <int Row,int Col>
  274. static
  275. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  276. scalar_type
  277. read_element( this_matrix const & x )
  278. {
  279. BOOST_QVM_STATIC_ASSERT(Row==0);
  280. BOOST_QVM_STATIC_ASSERT(Col>=0);
  281. BOOST_QVM_STATIC_ASSERT(Col<cols);
  282. return vec_traits<OriginalVector>::template read_element<Col>(reinterpret_cast<OriginalVector const &>(x));
  283. }
  284. static
  285. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  286. scalar_type
  287. read_element_idx( int row, int col, this_matrix const & x )
  288. {
  289. BOOST_QVM_ASSERT(row==0);
  290. BOOST_QVM_ASSERT(col>=0);
  291. BOOST_QVM_ASSERT(col<cols);
  292. return vec_traits<OriginalVector>::read_element_idx(col,reinterpret_cast<OriginalVector const &>(x));
  293. }
  294. };
  295. template <class OriginalVector,int R,int C>
  296. struct
  297. deduce_mat<qvm_detail::row_mat_<OriginalVector>,R,C>
  298. {
  299. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  300. };
  301. template <class OriginalVector,int R,int C>
  302. struct
  303. deduce_mat2<qvm_detail::row_mat_<OriginalVector>,qvm_detail::row_mat_<OriginalVector>,R,C>
  304. {
  305. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  306. };
  307. template <class A>
  308. typename enable_if_c<
  309. is_vec<A>::value,
  310. qvm_detail::row_mat_<A> const &>::type
  311. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  312. row_mat( A const & a )
  313. {
  314. return reinterpret_cast<typename qvm_detail::row_mat_<A> const &>(a);
  315. }
  316. template <class A>
  317. typename enable_if_c<
  318. is_vec<A>::value,
  319. qvm_detail::row_mat_<A> &>::type
  320. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  321. row_mat( A & a )
  322. {
  323. return reinterpret_cast<typename qvm_detail::row_mat_<A> &>(a);
  324. }
  325. ////////////////////////////////////////////////
  326. namespace
  327. qvm_detail
  328. {
  329. template <class OriginalVector>
  330. class
  331. translation_mat_
  332. {
  333. translation_mat_( translation_mat_ const & );
  334. translation_mat_ & operator=( translation_mat_ const & );
  335. ~translation_mat_();
  336. public:
  337. template <class T>
  338. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  339. translation_mat_ &
  340. operator=( T const & x )
  341. {
  342. assign(*this,x);
  343. return *this;
  344. }
  345. template <class R
  346. #if __cplusplus >= 201103L
  347. , class = typename enable_if<is_mat<R> >::type
  348. #endif
  349. >
  350. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  351. operator R() const
  352. {
  353. R r;
  354. assign(r,*this);
  355. return r;
  356. }
  357. };
  358. template <class M,int Row,int Col,bool TransCol=(Col==mat_traits<M>::cols-1)>
  359. struct read_translation_matat;
  360. template <class OriginalVector,int Row,int Col,bool TransCol>
  361. struct
  362. read_translation_matat<translation_mat_<OriginalVector>,Row,Col,TransCol>
  363. {
  364. static
  365. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  366. typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
  367. f( translation_mat_<OriginalVector> const & )
  368. {
  369. return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(0);
  370. }
  371. };
  372. template <class OriginalVector,int D>
  373. struct
  374. read_translation_matat<translation_mat_<OriginalVector>,D,D,false>
  375. {
  376. static
  377. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  378. typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
  379. f( translation_mat_<OriginalVector> const & )
  380. {
  381. return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
  382. }
  383. };
  384. template <class OriginalVector,int D>
  385. struct
  386. read_translation_matat<translation_mat_<OriginalVector>,D,D,true>
  387. {
  388. static
  389. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  390. typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
  391. f( translation_mat_<OriginalVector> const & )
  392. {
  393. return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
  394. }
  395. };
  396. template <class OriginalVector,int Row,int Col>
  397. struct
  398. read_translation_matat<translation_mat_<OriginalVector>,Row,Col,true>
  399. {
  400. static
  401. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  402. typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
  403. f( translation_mat_<OriginalVector> const & x )
  404. {
  405. return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
  406. }
  407. };
  408. template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
  409. struct translation_mat_write_traits;
  410. template <class OriginalVector>
  411. struct
  412. translation_mat_write_traits<OriginalVector,true>
  413. {
  414. typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
  415. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  416. static int const rows=vec_traits<OriginalVector>::dim+1;
  417. static int const cols=vec_traits<OriginalVector>::dim+1;
  418. template <int Row,int Col>
  419. static
  420. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  421. scalar_type &
  422. write_element( this_matrix & x )
  423. {
  424. BOOST_QVM_STATIC_ASSERT(Row>=0);
  425. BOOST_QVM_STATIC_ASSERT(Row<rows-1);
  426. BOOST_QVM_STATIC_ASSERT(Col==cols-1 || Col==0);
  427. //The following should be a static_assert, but this is a constexpr
  428. //function and it gets instantiated with Row=0 and Col=0 in the
  429. //mat_write_element_ref test (in a sizeof expression).
  430. BOOST_QVM_ASSERT(Col==cols-1);
  431. return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
  432. }
  433. static
  434. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  435. scalar_type &
  436. write_element_idx( int row, int col, this_matrix const & x )
  437. {
  438. BOOST_QVM_ASSERT(row>=0);
  439. BOOST_QVM_ASSERT(row<rows-1);
  440. BOOST_QVM_ASSERT(col==cols-1);
  441. return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
  442. }
  443. };
  444. template <class OriginalVector>
  445. struct
  446. translation_mat_write_traits<OriginalVector,false>
  447. {
  448. typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
  449. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  450. static int const rows=vec_traits<OriginalVector>::dim+1;
  451. static int const cols=vec_traits<OriginalVector>::dim+1;
  452. template <int Row,int Col>
  453. static
  454. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  455. void
  456. write_element( this_matrix & x, scalar_type s )
  457. {
  458. BOOST_QVM_STATIC_ASSERT(Row>=0);
  459. BOOST_QVM_STATIC_ASSERT(Row<rows-1);
  460. BOOST_QVM_STATIC_ASSERT(Col==cols-1 || Col==0);
  461. //The following should be a static_assert, but this is a constexpr
  462. //function and it gets instantiated with Row=0 and Col=0 in the
  463. //mat_write_element_ref test (in a sizeof expression).
  464. BOOST_QVM_ASSERT(Col==cols-1);
  465. vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
  466. }
  467. static
  468. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  469. void
  470. write_element_idx( int row, int col, this_matrix const & x, scalar_type s )
  471. {
  472. BOOST_QVM_ASSERT(row>=0);
  473. BOOST_QVM_ASSERT(row<rows);
  474. BOOST_QVM_ASSERT(col==cols-1);
  475. BOOST_QVM_ASSERT(col!=row);
  476. vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
  477. }
  478. };
  479. }
  480. template <class OriginalVector>
  481. struct
  482. mat_traits< qvm_detail::translation_mat_<OriginalVector> >:
  483. qvm_detail::translation_mat_write_traits<OriginalVector>
  484. {
  485. typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
  486. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  487. static int const rows=vec_traits<OriginalVector>::dim+1;
  488. static int const cols=vec_traits<OriginalVector>::dim+1;
  489. template <int Row,int Col>
  490. static
  491. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  492. scalar_type
  493. read_element( this_matrix const & x )
  494. {
  495. BOOST_QVM_STATIC_ASSERT(Row>=0);
  496. BOOST_QVM_STATIC_ASSERT(Row<rows);
  497. BOOST_QVM_STATIC_ASSERT(Col>=0);
  498. BOOST_QVM_STATIC_ASSERT(Col<cols);
  499. return qvm_detail::read_translation_matat<qvm_detail::translation_mat_<OriginalVector>,Row,Col>::f(x);
  500. }
  501. static
  502. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  503. scalar_type
  504. read_element_idx( int row, int col, this_matrix const & x )
  505. {
  506. BOOST_QVM_ASSERT(row>=0);
  507. BOOST_QVM_ASSERT(row<rows);
  508. BOOST_QVM_ASSERT(col>=0);
  509. BOOST_QVM_ASSERT(col<cols);
  510. return
  511. row==col?
  512. scalar_traits<scalar_type>::value(1):
  513. (col==cols-1?
  514. vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):
  515. scalar_traits<scalar_type>::value(0));
  516. }
  517. };
  518. template <class OriginalVector,int R,int C>
  519. struct
  520. deduce_mat<qvm_detail::translation_mat_<OriginalVector>,R,C>
  521. {
  522. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  523. };
  524. template <class OriginalVector,int R,int C>
  525. struct
  526. deduce_mat2<qvm_detail::translation_mat_<OriginalVector>,qvm_detail::translation_mat_<OriginalVector>,R,C>
  527. {
  528. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  529. };
  530. template <class A>
  531. typename enable_if_c<
  532. is_vec<A>::value,
  533. qvm_detail::translation_mat_<A> const &>::type
  534. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  535. translation_mat( A const & a )
  536. {
  537. return reinterpret_cast<typename qvm_detail::translation_mat_<A> const &>(a);
  538. }
  539. template <class A>
  540. typename enable_if_c<
  541. is_vec<A>::value,
  542. qvm_detail::translation_mat_<A> &>::type
  543. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  544. translation_mat( A & a )
  545. {
  546. return reinterpret_cast<typename qvm_detail::translation_mat_<A> &>(a);
  547. }
  548. ////////////////////////////////////////////////
  549. namespace
  550. qvm_detail
  551. {
  552. template <class OriginalVector>
  553. class
  554. diag_mat_
  555. {
  556. diag_mat_( diag_mat_ const & );
  557. diag_mat_ & operator=( diag_mat_ const & );
  558. ~diag_mat_();
  559. public:
  560. template <class T>
  561. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  562. diag_mat_ &
  563. operator=( T const & x )
  564. {
  565. assign(*this,x);
  566. return *this;
  567. }
  568. template <class R
  569. #if __cplusplus >= 201103L
  570. , class = typename enable_if<is_mat<R> >::type
  571. #endif
  572. >
  573. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  574. operator R() const
  575. {
  576. R r;
  577. assign(r,*this);
  578. return r;
  579. }
  580. };
  581. template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
  582. struct diag_mat_write_traits;
  583. template <class OriginalVector>
  584. struct
  585. diag_mat_write_traits<OriginalVector,true>
  586. {
  587. typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
  588. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  589. static int const rows=vec_traits<OriginalVector>::dim;
  590. static int const cols=vec_traits<OriginalVector>::dim;
  591. template <int Row,int Col>
  592. static
  593. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  594. scalar_type &
  595. write_element( this_matrix & x )
  596. {
  597. BOOST_QVM_STATIC_ASSERT(Row>=0);
  598. BOOST_QVM_STATIC_ASSERT(Row<rows);
  599. BOOST_QVM_STATIC_ASSERT(Row==Col);
  600. return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
  601. }
  602. static
  603. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  604. scalar_type &
  605. write_element_idx( int row, int col, this_matrix & x )
  606. {
  607. BOOST_QVM_ASSERT(row>=0);
  608. BOOST_QVM_ASSERT(row<rows);
  609. BOOST_QVM_ASSERT(row==col);
  610. return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
  611. }
  612. };
  613. template <class OriginalVector>
  614. struct
  615. diag_mat_write_traits<OriginalVector,false>
  616. {
  617. typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
  618. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  619. static int const rows=vec_traits<OriginalVector>::dim;
  620. static int const cols=vec_traits<OriginalVector>::dim;
  621. template <int Row,int Col>
  622. static
  623. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  624. void
  625. write_element( this_matrix & x, scalar_type s )
  626. {
  627. BOOST_QVM_STATIC_ASSERT(Row>=0);
  628. BOOST_QVM_STATIC_ASSERT(Row<rows);
  629. BOOST_QVM_STATIC_ASSERT(Row==Col);
  630. vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
  631. }
  632. static
  633. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  634. void
  635. write_element_idx( int row, int col, this_matrix & x, scalar_type s )
  636. {
  637. BOOST_QVM_ASSERT(row>=0);
  638. BOOST_QVM_ASSERT(row<rows);
  639. BOOST_QVM_ASSERT(row==col);
  640. vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
  641. }
  642. };
  643. }
  644. template <class OriginalVector>
  645. struct
  646. mat_traits< qvm_detail::diag_mat_<OriginalVector> >:
  647. qvm_detail::diag_mat_write_traits<OriginalVector>
  648. {
  649. typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
  650. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  651. static int const rows=vec_traits<OriginalVector>::dim;
  652. static int const cols=vec_traits<OriginalVector>::dim;
  653. template <int Row,int Col>
  654. static
  655. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  656. scalar_type
  657. read_element( this_matrix const & x )
  658. {
  659. BOOST_QVM_STATIC_ASSERT(Row>=0);
  660. BOOST_QVM_STATIC_ASSERT(Row<rows);
  661. BOOST_QVM_STATIC_ASSERT(Col>=0);
  662. BOOST_QVM_STATIC_ASSERT(Col<cols);
  663. return Row==Col?vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
  664. }
  665. static
  666. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  667. scalar_type
  668. read_element_idx( int row, int col, this_matrix const & x )
  669. {
  670. BOOST_QVM_ASSERT(row>=0);
  671. BOOST_QVM_ASSERT(row<rows);
  672. BOOST_QVM_ASSERT(col>=0);
  673. BOOST_QVM_ASSERT(col<cols);
  674. return row==col?vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
  675. }
  676. };
  677. template <class OriginalVector,int R,int C>
  678. struct
  679. deduce_mat<qvm_detail::diag_mat_<OriginalVector>,R,C>
  680. {
  681. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  682. };
  683. template <class OriginalVector,int R,int C>
  684. struct
  685. deduce_mat2<qvm_detail::diag_mat_<OriginalVector>,qvm_detail::diag_mat_<OriginalVector>,R,C>
  686. {
  687. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  688. };
  689. template <class A>
  690. typename enable_if_c<
  691. is_vec<A>::value,
  692. qvm_detail::diag_mat_<A> const &>::type
  693. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  694. diag_mat( A const & a )
  695. {
  696. return reinterpret_cast<typename qvm_detail::diag_mat_<A> const &>(a);
  697. }
  698. template <class A>
  699. typename enable_if_c<
  700. is_vec<A>::value,
  701. qvm_detail::diag_mat_<A> &>::type
  702. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  703. diag_mat( A & a )
  704. {
  705. return reinterpret_cast<typename qvm_detail::diag_mat_<A> &>(a);
  706. }
  707. } }
  708. #endif