map_mat_vec.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. #ifndef BOOST_QVM_MAP_MAT_VEC_HPP_INCLUDED
  2. #define BOOST_QVM_MAP_MAT_VEC_HPP_INCLUDED
  3. /// Copyright (c) 2008-2021 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/inline.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_INLINE_TRIVIAL
  25. col_ &
  26. operator=( T const & x )
  27. {
  28. assign(*this,x);
  29. return *this;
  30. }
  31. template <class R>
  32. BOOST_QVM_INLINE_TRIVIAL
  33. operator R() const
  34. {
  35. R r;
  36. assign(r,*this);
  37. return r;
  38. }
  39. };
  40. }
  41. template <int Col,class OriginalMatrix>
  42. struct
  43. vec_traits< qvm_detail::col_<Col,OriginalMatrix> >
  44. {
  45. typedef qvm_detail::col_<Col,OriginalMatrix> this_vector;
  46. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  47. static int const dim=mat_traits<OriginalMatrix>::rows;
  48. BOOST_QVM_STATIC_ASSERT(Col>=0);
  49. BOOST_QVM_STATIC_ASSERT(Col<mat_traits<OriginalMatrix>::cols);
  50. template <int I>
  51. static
  52. BOOST_QVM_INLINE_CRITICAL
  53. scalar_type
  54. read_element( this_vector const & x )
  55. {
  56. BOOST_QVM_STATIC_ASSERT(I>=0);
  57. BOOST_QVM_STATIC_ASSERT(I<dim);
  58. return mat_traits<OriginalMatrix>::template read_element<I,Col>(reinterpret_cast<OriginalMatrix const &>(x));
  59. }
  60. template <int I>
  61. static
  62. BOOST_QVM_INLINE_CRITICAL
  63. scalar_type &
  64. write_element( this_vector & x )
  65. {
  66. BOOST_QVM_STATIC_ASSERT(I>=0);
  67. BOOST_QVM_STATIC_ASSERT(I<dim);
  68. return mat_traits<OriginalMatrix>::template write_element<I,Col>(reinterpret_cast<OriginalMatrix &>(x));
  69. }
  70. static
  71. BOOST_QVM_INLINE_CRITICAL
  72. scalar_type
  73. read_element_idx( int i, this_vector const & x )
  74. {
  75. BOOST_QVM_ASSERT(i>=0);
  76. BOOST_QVM_ASSERT(i<dim);
  77. return mat_traits<OriginalMatrix>::read_element_idx(i,Col,reinterpret_cast<OriginalMatrix const &>(x));
  78. }
  79. static
  80. BOOST_QVM_INLINE_CRITICAL
  81. scalar_type &
  82. write_element_idx( int i, this_vector & x )
  83. {
  84. BOOST_QVM_ASSERT(i>=0);
  85. BOOST_QVM_ASSERT(i<dim);
  86. return mat_traits<OriginalMatrix>::write_element_idx(i,Col,reinterpret_cast<OriginalMatrix &>(x));
  87. }
  88. };
  89. template <int Col,class OriginalMatrix,int D>
  90. struct
  91. deduce_vec<qvm_detail::col_<Col,OriginalMatrix>,D>
  92. {
  93. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  94. };
  95. template <int Col,class OriginalMatrix,int D>
  96. struct
  97. deduce_vec2<qvm_detail::col_<Col,OriginalMatrix>,qvm_detail::col_<Col,OriginalMatrix>,D>
  98. {
  99. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  100. };
  101. template <int Col,class A>
  102. typename enable_if_c<
  103. is_mat<A>::value,
  104. qvm_detail::col_<Col,A> const &>::type
  105. BOOST_QVM_INLINE_TRIVIAL
  106. col( A const & a )
  107. {
  108. return reinterpret_cast<typename qvm_detail::col_<Col,A> const &>(a);
  109. }
  110. template <int Col,class A>
  111. typename enable_if_c<
  112. is_mat<A>::value,
  113. qvm_detail::col_<Col,A> &>::type
  114. BOOST_QVM_INLINE_TRIVIAL
  115. col( A & a )
  116. {
  117. return reinterpret_cast<typename qvm_detail::col_<Col,A> &>(a);
  118. }
  119. ////////////////////////////////////////////////
  120. namespace
  121. qvm_detail
  122. {
  123. template <int Row,class OriginalMatrix>
  124. class
  125. row_
  126. {
  127. row_( row_ const & );
  128. row_ & operator=( row_ const & );
  129. ~row_();
  130. public:
  131. template <class T>
  132. BOOST_QVM_INLINE_TRIVIAL
  133. row_ &
  134. operator=( T const & x )
  135. {
  136. assign(*this,x);
  137. return *this;
  138. }
  139. template <class R>
  140. BOOST_QVM_INLINE_TRIVIAL
  141. operator R() const
  142. {
  143. R r;
  144. assign(r,*this);
  145. return r;
  146. }
  147. };
  148. }
  149. template <int Row,class OriginalMatrix>
  150. struct
  151. vec_traits< qvm_detail::row_<Row,OriginalMatrix> >
  152. {
  153. typedef qvm_detail::row_<Row,OriginalMatrix> this_vector;
  154. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  155. static int const dim=mat_traits<OriginalMatrix>::cols;
  156. BOOST_QVM_STATIC_ASSERT(Row>=0);
  157. BOOST_QVM_STATIC_ASSERT(Row<mat_traits<OriginalMatrix>::rows);
  158. template <int I>
  159. static
  160. BOOST_QVM_INLINE_CRITICAL
  161. scalar_type
  162. read_element( this_vector const & x )
  163. {
  164. BOOST_QVM_STATIC_ASSERT(I>=0);
  165. BOOST_QVM_STATIC_ASSERT(I<dim);
  166. return mat_traits<OriginalMatrix>::template read_element<Row,I>(reinterpret_cast<OriginalMatrix const &>(x));
  167. }
  168. template <int I>
  169. static
  170. BOOST_QVM_INLINE_CRITICAL
  171. scalar_type &
  172. write_element( this_vector & x )
  173. {
  174. BOOST_QVM_STATIC_ASSERT(I>=0);
  175. BOOST_QVM_STATIC_ASSERT(I<dim);
  176. return mat_traits<OriginalMatrix>::template write_element<Row,I>(reinterpret_cast<OriginalMatrix &>(x));
  177. }
  178. static
  179. BOOST_QVM_INLINE_CRITICAL
  180. scalar_type
  181. read_element_idx( int i, this_vector const & x )
  182. {
  183. BOOST_QVM_ASSERT(i>=0);
  184. BOOST_QVM_ASSERT(i<dim);
  185. return mat_traits<OriginalMatrix>::read_element_idx(Row,i,reinterpret_cast<OriginalMatrix const &>(x));
  186. }
  187. static
  188. BOOST_QVM_INLINE_CRITICAL
  189. scalar_type &
  190. write_element_idx( int i, this_vector & x )
  191. {
  192. BOOST_QVM_ASSERT(i>=0);
  193. BOOST_QVM_ASSERT(i<dim);
  194. return mat_traits<OriginalMatrix>::write_element_idx(Row,i,reinterpret_cast<OriginalMatrix &>(x));
  195. }
  196. };
  197. template <int Row,class OriginalMatrix,int D>
  198. struct
  199. deduce_vec<qvm_detail::row_<Row,OriginalMatrix>,D>
  200. {
  201. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  202. };
  203. template <int Row,class OriginalMatrix,int D>
  204. struct
  205. deduce_vec2<qvm_detail::row_<Row,OriginalMatrix>,qvm_detail::row_<Row,OriginalMatrix>,D>
  206. {
  207. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  208. };
  209. template <int Row,class A>
  210. typename enable_if_c<
  211. is_mat<A>::value,
  212. qvm_detail::row_<Row,A> const &>::type
  213. BOOST_QVM_INLINE_TRIVIAL
  214. row( A const & a )
  215. {
  216. return reinterpret_cast<typename qvm_detail::row_<Row,A> const &>(a);
  217. }
  218. template <int Row,class A>
  219. typename enable_if_c<
  220. is_mat<A>::value,
  221. qvm_detail::row_<Row,A> &>::type
  222. BOOST_QVM_INLINE_TRIVIAL
  223. row( A & a )
  224. {
  225. return reinterpret_cast<typename qvm_detail::row_<Row,A> &>(a);
  226. }
  227. ////////////////////////////////////////////////
  228. namespace
  229. qvm_detail
  230. {
  231. template <class OriginalMatrix>
  232. class
  233. diag_
  234. {
  235. diag_( diag_ const & );
  236. diag_ & operator=( diag_ const & );
  237. ~diag_();
  238. public:
  239. template <class T>
  240. BOOST_QVM_INLINE_TRIVIAL
  241. diag_ &
  242. operator=( T const & x )
  243. {
  244. assign(*this,x);
  245. return *this;
  246. }
  247. template <class R>
  248. BOOST_QVM_INLINE_TRIVIAL
  249. operator R() const
  250. {
  251. R r;
  252. assign(r,*this);
  253. return r;
  254. }
  255. };
  256. template <int X,int Y,bool Which>
  257. struct diag_bool_dispatch;
  258. template <int X,int Y>
  259. struct
  260. diag_bool_dispatch<X,Y,true>
  261. {
  262. static int const value=X;
  263. };
  264. template <int X,int Y>
  265. struct
  266. diag_bool_dispatch<X,Y,false>
  267. {
  268. static int const value=Y;
  269. };
  270. }
  271. template <class OriginalMatrix>
  272. struct
  273. vec_traits< qvm_detail::diag_<OriginalMatrix> >
  274. {
  275. typedef qvm_detail::diag_<OriginalMatrix> this_vector;
  276. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  277. static int const dim=qvm_detail::diag_bool_dispatch<
  278. mat_traits<OriginalMatrix>::rows,
  279. mat_traits<OriginalMatrix>::cols,
  280. mat_traits<OriginalMatrix>::rows<=mat_traits<OriginalMatrix>::cols>::value;
  281. template <int I>
  282. static
  283. BOOST_QVM_INLINE_CRITICAL
  284. scalar_type
  285. read_element( this_vector const & x )
  286. {
  287. BOOST_QVM_STATIC_ASSERT(I>=0);
  288. BOOST_QVM_STATIC_ASSERT(I<dim);
  289. return mat_traits<OriginalMatrix>::template read_element<I,I>(reinterpret_cast<OriginalMatrix const &>(x));
  290. }
  291. template <int I>
  292. static
  293. BOOST_QVM_INLINE_CRITICAL
  294. scalar_type &
  295. write_element( this_vector & x )
  296. {
  297. BOOST_QVM_STATIC_ASSERT(I>=0);
  298. BOOST_QVM_STATIC_ASSERT(I<dim);
  299. return mat_traits<OriginalMatrix>::template write_element<I,I>(reinterpret_cast<OriginalMatrix &>(x));
  300. }
  301. static
  302. BOOST_QVM_INLINE_CRITICAL
  303. scalar_type
  304. read_element_idx( int i, this_vector const & x )
  305. {
  306. BOOST_QVM_ASSERT(i>=0);
  307. BOOST_QVM_ASSERT(i<dim);
  308. return mat_traits<OriginalMatrix>::read_element_idx(i,i,reinterpret_cast<OriginalMatrix const &>(x));
  309. }
  310. static
  311. BOOST_QVM_INLINE_CRITICAL
  312. scalar_type &
  313. write_element_idx( int i, this_vector & x )
  314. {
  315. BOOST_QVM_ASSERT(i>=0);
  316. BOOST_QVM_ASSERT(i<dim);
  317. return mat_traits<OriginalMatrix>::write_element_idx(i,i,reinterpret_cast<OriginalMatrix &>(x));
  318. }
  319. };
  320. template <class OriginalMatrix,int D>
  321. struct
  322. deduce_vec<qvm_detail::diag_<OriginalMatrix>,D>
  323. {
  324. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  325. };
  326. template <class OriginalMatrix,int D>
  327. struct
  328. deduce_vec2<qvm_detail::diag_<OriginalMatrix>,qvm_detail::diag_<OriginalMatrix>,D>
  329. {
  330. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  331. };
  332. template <class A>
  333. typename enable_if_c<
  334. is_mat<A>::value,
  335. qvm_detail::diag_<A> const &>::type
  336. BOOST_QVM_INLINE_TRIVIAL
  337. diag( A const & a )
  338. {
  339. return reinterpret_cast<typename qvm_detail::diag_<A> const &>(a);
  340. }
  341. template <class A>
  342. typename enable_if_c<
  343. is_mat<A>::value,
  344. qvm_detail::diag_<A> &>::type
  345. BOOST_QVM_INLINE_TRIVIAL
  346. diag( A & a )
  347. {
  348. return reinterpret_cast<typename qvm_detail::diag_<A> &>(a);
  349. }
  350. ////////////////////////////////////////////////
  351. namespace
  352. qvm_detail
  353. {
  354. template <class OriginalMatrix>
  355. class
  356. translation_
  357. {
  358. translation_( translation_ const & );
  359. ~translation_();
  360. public:
  361. translation_ &
  362. operator=( translation_ const & x )
  363. {
  364. assign(*this,x);
  365. return *this;
  366. }
  367. template <class T>
  368. BOOST_QVM_INLINE_TRIVIAL
  369. translation_ &
  370. operator=( T const & x )
  371. {
  372. assign(*this,x);
  373. return *this;
  374. }
  375. template <class R>
  376. BOOST_QVM_INLINE_TRIVIAL
  377. operator R() const
  378. {
  379. R r;
  380. assign(r,*this);
  381. return r;
  382. }
  383. };
  384. }
  385. template <class OriginalMatrix>
  386. struct
  387. vec_traits< qvm_detail::translation_<OriginalMatrix> >
  388. {
  389. typedef qvm_detail::translation_<OriginalMatrix> this_vector;
  390. typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
  391. static int const dim=mat_traits<OriginalMatrix>::rows-1;
  392. BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::rows==mat_traits<OriginalMatrix>::cols);
  393. BOOST_QVM_STATIC_ASSERT(mat_traits<OriginalMatrix>::rows>=3);
  394. template <int I>
  395. static
  396. BOOST_QVM_INLINE_CRITICAL
  397. scalar_type
  398. read_element( this_vector const & x )
  399. {
  400. BOOST_QVM_STATIC_ASSERT(I>=0);
  401. BOOST_QVM_STATIC_ASSERT(I<dim);
  402. return mat_traits<OriginalMatrix>::template read_element<I,dim>(reinterpret_cast<OriginalMatrix const &>(x));
  403. }
  404. template <int I>
  405. static
  406. BOOST_QVM_INLINE_CRITICAL
  407. scalar_type &
  408. write_element( this_vector & x )
  409. {
  410. BOOST_QVM_STATIC_ASSERT(I>=0);
  411. BOOST_QVM_STATIC_ASSERT(I<dim);
  412. return mat_traits<OriginalMatrix>::template write_element<I,dim>(reinterpret_cast<OriginalMatrix &>(x));
  413. }
  414. static
  415. BOOST_QVM_INLINE_CRITICAL
  416. scalar_type
  417. read_element_idx( int i, this_vector const & x )
  418. {
  419. BOOST_QVM_ASSERT(i>=0);
  420. BOOST_QVM_ASSERT(i<dim);
  421. return mat_traits<OriginalMatrix>::read_element_idx(i,dim,reinterpret_cast<OriginalMatrix const &>(x));
  422. }
  423. static
  424. BOOST_QVM_INLINE_CRITICAL
  425. scalar_type &
  426. write_element_idx( int i, this_vector & x )
  427. {
  428. BOOST_QVM_ASSERT(i>=0);
  429. BOOST_QVM_ASSERT(i<dim);
  430. return mat_traits<OriginalMatrix>::write_element_idx(i,dim,reinterpret_cast<OriginalMatrix &>(x));
  431. }
  432. };
  433. template <class OriginalMatrix,int D>
  434. struct
  435. deduce_vec<qvm_detail::translation_<OriginalMatrix>,D>
  436. {
  437. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  438. };
  439. template <class OriginalMatrix,int D>
  440. struct
  441. deduce_vec2<qvm_detail::translation_<OriginalMatrix>,qvm_detail::translation_<OriginalMatrix>,D>
  442. {
  443. typedef vec<typename mat_traits<OriginalMatrix>::scalar_type,D> type;
  444. };
  445. template <class A>
  446. typename enable_if_c<
  447. is_mat<A>::value && mat_traits<A>::rows==mat_traits<A>::cols && mat_traits<A>::rows>=3,
  448. qvm_detail::translation_<A> const &>::type
  449. BOOST_QVM_INLINE_TRIVIAL
  450. translation( A const & a )
  451. {
  452. return reinterpret_cast<typename qvm_detail::translation_<A> const &>(a);
  453. }
  454. template <class A>
  455. typename enable_if_c<
  456. is_mat<A>::value && mat_traits<A>::rows==mat_traits<A>::cols && mat_traits<A>::rows>=3,
  457. qvm_detail::translation_<A> &>::type
  458. BOOST_QVM_INLINE_TRIVIAL
  459. translation( A & a )
  460. {
  461. return reinterpret_cast<typename qvm_detail::translation_<A> &>(a);
  462. }
  463. } }
  464. #endif