map_mat_vec.hpp 17 KB

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