map_mat_mat.hpp 25 KB

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