mat_operations4.hpp 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124
  1. #ifndef BOOST_QVM_GEN_MAT_OPERATIONS4_HPP_INCLUDED
  2. #define BOOST_QVM_GEN_MAT_OPERATIONS4_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. /// This file was generated by a program. Do not edit manually.
  7. #include <boost/qvm/assert.hpp>
  8. #include <boost/qvm/deduce_mat.hpp>
  9. #include <boost/qvm/deduce_vec.hpp>
  10. #include <boost/qvm/error.hpp>
  11. #include <boost/qvm/gen/mat_assign4.hpp>
  12. #include <boost/qvm/quat_traits.hpp>
  13. #include <boost/qvm/scalar_traits.hpp>
  14. #include <boost/qvm/throw_exception.hpp>
  15. namespace boost { namespace qvm {
  16. template <class A,class B>
  17. BOOST_QVM_INLINE_OPERATIONS
  18. typename lazy_enable_if_c<
  19. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  20. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  21. deduce_mat2<A,B,4,4> >::type
  22. operator+( A const & a, B const & b )
  23. {
  24. typedef typename deduce_mat2<A,B,4,4>::type R;
  25. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
  26. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
  27. R r;
  28. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b);
  29. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b);
  30. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b);
  31. mat_traits<R>::template write_element<0,3>(r)=mat_traits<A>::template read_element<0,3>(a)+mat_traits<B>::template read_element<0,3>(b);
  32. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b);
  33. mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)+mat_traits<B>::template read_element<1,1>(b);
  34. mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)+mat_traits<B>::template read_element<1,2>(b);
  35. mat_traits<R>::template write_element<1,3>(r)=mat_traits<A>::template read_element<1,3>(a)+mat_traits<B>::template read_element<1,3>(b);
  36. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b);
  37. mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)+mat_traits<B>::template read_element<2,1>(b);
  38. mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)+mat_traits<B>::template read_element<2,2>(b);
  39. mat_traits<R>::template write_element<2,3>(r)=mat_traits<A>::template read_element<2,3>(a)+mat_traits<B>::template read_element<2,3>(b);
  40. mat_traits<R>::template write_element<3,0>(r)=mat_traits<A>::template read_element<3,0>(a)+mat_traits<B>::template read_element<3,0>(b);
  41. mat_traits<R>::template write_element<3,1>(r)=mat_traits<A>::template read_element<3,1>(a)+mat_traits<B>::template read_element<3,1>(b);
  42. mat_traits<R>::template write_element<3,2>(r)=mat_traits<A>::template read_element<3,2>(a)+mat_traits<B>::template read_element<3,2>(b);
  43. mat_traits<R>::template write_element<3,3>(r)=mat_traits<A>::template read_element<3,3>(a)+mat_traits<B>::template read_element<3,3>(b);
  44. return r;
  45. }
  46. namespace
  47. sfinae
  48. {
  49. using ::boost::qvm::operator+;
  50. }
  51. namespace
  52. qvm_detail
  53. {
  54. template <int R,int C>
  55. struct plus_mm_defined;
  56. template <>
  57. struct
  58. plus_mm_defined<4,4>
  59. {
  60. static bool const value=true;
  61. };
  62. }
  63. template <class A,class B>
  64. BOOST_QVM_INLINE_OPERATIONS
  65. typename lazy_enable_if_c<
  66. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  67. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  68. deduce_mat2<A,B,4,1> >::type
  69. operator+( A const & a, B const & b )
  70. {
  71. typedef typename deduce_mat2<A,B,4,1>::type R;
  72. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
  73. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
  74. R r;
  75. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b);
  76. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b);
  77. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b);
  78. mat_traits<R>::template write_element<3,0>(r)=mat_traits<A>::template read_element<3,0>(a)+mat_traits<B>::template read_element<3,0>(b);
  79. return r;
  80. }
  81. namespace
  82. sfinae
  83. {
  84. using ::boost::qvm::operator+;
  85. }
  86. namespace
  87. qvm_detail
  88. {
  89. template <int R,int C>
  90. struct plus_mm_defined;
  91. template <>
  92. struct
  93. plus_mm_defined<4,1>
  94. {
  95. static bool const value=true;
  96. };
  97. }
  98. template <class A,class B>
  99. BOOST_QVM_INLINE_OPERATIONS
  100. typename lazy_enable_if_c<
  101. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  102. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  103. deduce_mat2<A,B,1,4> >::type
  104. operator+( A const & a, B const & b )
  105. {
  106. typedef typename deduce_mat2<A,B,1,4>::type R;
  107. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
  108. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
  109. R r;
  110. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b);
  111. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b);
  112. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b);
  113. mat_traits<R>::template write_element<0,3>(r)=mat_traits<A>::template read_element<0,3>(a)+mat_traits<B>::template read_element<0,3>(b);
  114. return r;
  115. }
  116. namespace
  117. sfinae
  118. {
  119. using ::boost::qvm::operator+;
  120. }
  121. namespace
  122. qvm_detail
  123. {
  124. template <int R,int C>
  125. struct plus_mm_defined;
  126. template <>
  127. struct
  128. plus_mm_defined<1,4>
  129. {
  130. static bool const value=true;
  131. };
  132. }
  133. template <class A,class B>
  134. BOOST_QVM_INLINE_OPERATIONS
  135. typename lazy_enable_if_c<
  136. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  137. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  138. deduce_mat2<A,B,4,4> >::type
  139. operator-( A const & a, B const & b )
  140. {
  141. typedef typename deduce_mat2<A,B,4,4>::type R;
  142. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
  143. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
  144. R r;
  145. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b);
  146. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b);
  147. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b);
  148. mat_traits<R>::template write_element<0,3>(r)=mat_traits<A>::template read_element<0,3>(a)-mat_traits<B>::template read_element<0,3>(b);
  149. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b);
  150. mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)-mat_traits<B>::template read_element<1,1>(b);
  151. mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)-mat_traits<B>::template read_element<1,2>(b);
  152. mat_traits<R>::template write_element<1,3>(r)=mat_traits<A>::template read_element<1,3>(a)-mat_traits<B>::template read_element<1,3>(b);
  153. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b);
  154. mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)-mat_traits<B>::template read_element<2,1>(b);
  155. mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)-mat_traits<B>::template read_element<2,2>(b);
  156. mat_traits<R>::template write_element<2,3>(r)=mat_traits<A>::template read_element<2,3>(a)-mat_traits<B>::template read_element<2,3>(b);
  157. mat_traits<R>::template write_element<3,0>(r)=mat_traits<A>::template read_element<3,0>(a)-mat_traits<B>::template read_element<3,0>(b);
  158. mat_traits<R>::template write_element<3,1>(r)=mat_traits<A>::template read_element<3,1>(a)-mat_traits<B>::template read_element<3,1>(b);
  159. mat_traits<R>::template write_element<3,2>(r)=mat_traits<A>::template read_element<3,2>(a)-mat_traits<B>::template read_element<3,2>(b);
  160. mat_traits<R>::template write_element<3,3>(r)=mat_traits<A>::template read_element<3,3>(a)-mat_traits<B>::template read_element<3,3>(b);
  161. return r;
  162. }
  163. namespace
  164. sfinae
  165. {
  166. using ::boost::qvm::operator-;
  167. }
  168. namespace
  169. qvm_detail
  170. {
  171. template <int R,int C>
  172. struct minus_mm_defined;
  173. template <>
  174. struct
  175. minus_mm_defined<4,4>
  176. {
  177. static bool const value=true;
  178. };
  179. }
  180. template <class A,class B>
  181. BOOST_QVM_INLINE_OPERATIONS
  182. typename lazy_enable_if_c<
  183. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  184. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  185. deduce_mat2<A,B,4,1> >::type
  186. operator-( A const & a, B const & b )
  187. {
  188. typedef typename deduce_mat2<A,B,4,1>::type R;
  189. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
  190. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
  191. R r;
  192. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b);
  193. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b);
  194. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b);
  195. mat_traits<R>::template write_element<3,0>(r)=mat_traits<A>::template read_element<3,0>(a)-mat_traits<B>::template read_element<3,0>(b);
  196. return r;
  197. }
  198. namespace
  199. sfinae
  200. {
  201. using ::boost::qvm::operator-;
  202. }
  203. namespace
  204. qvm_detail
  205. {
  206. template <int R,int C>
  207. struct minus_mm_defined;
  208. template <>
  209. struct
  210. minus_mm_defined<4,1>
  211. {
  212. static bool const value=true;
  213. };
  214. }
  215. template <class A,class B>
  216. BOOST_QVM_INLINE_OPERATIONS
  217. typename lazy_enable_if_c<
  218. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  219. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  220. deduce_mat2<A,B,1,4> >::type
  221. operator-( A const & a, B const & b )
  222. {
  223. typedef typename deduce_mat2<A,B,1,4>::type R;
  224. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
  225. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
  226. R r;
  227. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b);
  228. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b);
  229. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b);
  230. mat_traits<R>::template write_element<0,3>(r)=mat_traits<A>::template read_element<0,3>(a)-mat_traits<B>::template read_element<0,3>(b);
  231. return r;
  232. }
  233. namespace
  234. sfinae
  235. {
  236. using ::boost::qvm::operator-;
  237. }
  238. namespace
  239. qvm_detail
  240. {
  241. template <int R,int C>
  242. struct minus_mm_defined;
  243. template <>
  244. struct
  245. minus_mm_defined<1,4>
  246. {
  247. static bool const value=true;
  248. };
  249. }
  250. template <class A,class B>
  251. BOOST_QVM_INLINE_OPERATIONS
  252. typename enable_if_c<
  253. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  254. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  255. A &>::type
  256. operator+=( A & a, B const & b )
  257. {
  258. mat_traits<A>::template write_element<0,0>(a)+=mat_traits<B>::template read_element<0,0>(b);
  259. mat_traits<A>::template write_element<0,1>(a)+=mat_traits<B>::template read_element<0,1>(b);
  260. mat_traits<A>::template write_element<0,2>(a)+=mat_traits<B>::template read_element<0,2>(b);
  261. mat_traits<A>::template write_element<0,3>(a)+=mat_traits<B>::template read_element<0,3>(b);
  262. mat_traits<A>::template write_element<1,0>(a)+=mat_traits<B>::template read_element<1,0>(b);
  263. mat_traits<A>::template write_element<1,1>(a)+=mat_traits<B>::template read_element<1,1>(b);
  264. mat_traits<A>::template write_element<1,2>(a)+=mat_traits<B>::template read_element<1,2>(b);
  265. mat_traits<A>::template write_element<1,3>(a)+=mat_traits<B>::template read_element<1,3>(b);
  266. mat_traits<A>::template write_element<2,0>(a)+=mat_traits<B>::template read_element<2,0>(b);
  267. mat_traits<A>::template write_element<2,1>(a)+=mat_traits<B>::template read_element<2,1>(b);
  268. mat_traits<A>::template write_element<2,2>(a)+=mat_traits<B>::template read_element<2,2>(b);
  269. mat_traits<A>::template write_element<2,3>(a)+=mat_traits<B>::template read_element<2,3>(b);
  270. mat_traits<A>::template write_element<3,0>(a)+=mat_traits<B>::template read_element<3,0>(b);
  271. mat_traits<A>::template write_element<3,1>(a)+=mat_traits<B>::template read_element<3,1>(b);
  272. mat_traits<A>::template write_element<3,2>(a)+=mat_traits<B>::template read_element<3,2>(b);
  273. mat_traits<A>::template write_element<3,3>(a)+=mat_traits<B>::template read_element<3,3>(b);
  274. return a;
  275. }
  276. namespace
  277. sfinae
  278. {
  279. using ::boost::qvm::operator+=;
  280. }
  281. namespace
  282. qvm_detail
  283. {
  284. template <int R,int C>
  285. struct plus_eq_mm_defined;
  286. template <>
  287. struct
  288. plus_eq_mm_defined<4,4>
  289. {
  290. static bool const value=true;
  291. };
  292. }
  293. template <class A,class B>
  294. BOOST_QVM_INLINE_OPERATIONS
  295. typename enable_if_c<
  296. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  297. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  298. A &>::type
  299. operator+=( A & a, B const & b )
  300. {
  301. mat_traits<A>::template write_element<0,0>(a)+=mat_traits<B>::template read_element<0,0>(b);
  302. mat_traits<A>::template write_element<1,0>(a)+=mat_traits<B>::template read_element<1,0>(b);
  303. mat_traits<A>::template write_element<2,0>(a)+=mat_traits<B>::template read_element<2,0>(b);
  304. mat_traits<A>::template write_element<3,0>(a)+=mat_traits<B>::template read_element<3,0>(b);
  305. return a;
  306. }
  307. namespace
  308. sfinae
  309. {
  310. using ::boost::qvm::operator+=;
  311. }
  312. namespace
  313. qvm_detail
  314. {
  315. template <int R,int C>
  316. struct plus_eq_mm_defined;
  317. template <>
  318. struct
  319. plus_eq_mm_defined<4,1>
  320. {
  321. static bool const value=true;
  322. };
  323. }
  324. template <class A,class B>
  325. BOOST_QVM_INLINE_OPERATIONS
  326. typename enable_if_c<
  327. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  328. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  329. A &>::type
  330. operator+=( A & a, B const & b )
  331. {
  332. mat_traits<A>::template write_element<0,0>(a)+=mat_traits<B>::template read_element<0,0>(b);
  333. mat_traits<A>::template write_element<0,1>(a)+=mat_traits<B>::template read_element<0,1>(b);
  334. mat_traits<A>::template write_element<0,2>(a)+=mat_traits<B>::template read_element<0,2>(b);
  335. mat_traits<A>::template write_element<0,3>(a)+=mat_traits<B>::template read_element<0,3>(b);
  336. return a;
  337. }
  338. namespace
  339. sfinae
  340. {
  341. using ::boost::qvm::operator+=;
  342. }
  343. namespace
  344. qvm_detail
  345. {
  346. template <int R,int C>
  347. struct plus_eq_mm_defined;
  348. template <>
  349. struct
  350. plus_eq_mm_defined<1,4>
  351. {
  352. static bool const value=true;
  353. };
  354. }
  355. template <class A,class B>
  356. BOOST_QVM_INLINE_OPERATIONS
  357. typename enable_if_c<
  358. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  359. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  360. A &>::type
  361. operator-=( A & a, B const & b )
  362. {
  363. mat_traits<A>::template write_element<0,0>(a)-=mat_traits<B>::template read_element<0,0>(b);
  364. mat_traits<A>::template write_element<0,1>(a)-=mat_traits<B>::template read_element<0,1>(b);
  365. mat_traits<A>::template write_element<0,2>(a)-=mat_traits<B>::template read_element<0,2>(b);
  366. mat_traits<A>::template write_element<0,3>(a)-=mat_traits<B>::template read_element<0,3>(b);
  367. mat_traits<A>::template write_element<1,0>(a)-=mat_traits<B>::template read_element<1,0>(b);
  368. mat_traits<A>::template write_element<1,1>(a)-=mat_traits<B>::template read_element<1,1>(b);
  369. mat_traits<A>::template write_element<1,2>(a)-=mat_traits<B>::template read_element<1,2>(b);
  370. mat_traits<A>::template write_element<1,3>(a)-=mat_traits<B>::template read_element<1,3>(b);
  371. mat_traits<A>::template write_element<2,0>(a)-=mat_traits<B>::template read_element<2,0>(b);
  372. mat_traits<A>::template write_element<2,1>(a)-=mat_traits<B>::template read_element<2,1>(b);
  373. mat_traits<A>::template write_element<2,2>(a)-=mat_traits<B>::template read_element<2,2>(b);
  374. mat_traits<A>::template write_element<2,3>(a)-=mat_traits<B>::template read_element<2,3>(b);
  375. mat_traits<A>::template write_element<3,0>(a)-=mat_traits<B>::template read_element<3,0>(b);
  376. mat_traits<A>::template write_element<3,1>(a)-=mat_traits<B>::template read_element<3,1>(b);
  377. mat_traits<A>::template write_element<3,2>(a)-=mat_traits<B>::template read_element<3,2>(b);
  378. mat_traits<A>::template write_element<3,3>(a)-=mat_traits<B>::template read_element<3,3>(b);
  379. return a;
  380. }
  381. namespace
  382. sfinae
  383. {
  384. using ::boost::qvm::operator-=;
  385. }
  386. namespace
  387. qvm_detail
  388. {
  389. template <int R,int C>
  390. struct minus_eq_mm_defined;
  391. template <>
  392. struct
  393. minus_eq_mm_defined<4,4>
  394. {
  395. static bool const value=true;
  396. };
  397. }
  398. template <class A,class B>
  399. BOOST_QVM_INLINE_OPERATIONS
  400. typename enable_if_c<
  401. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  402. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  403. A &>::type
  404. operator-=( A & a, B const & b )
  405. {
  406. mat_traits<A>::template write_element<0,0>(a)-=mat_traits<B>::template read_element<0,0>(b);
  407. mat_traits<A>::template write_element<1,0>(a)-=mat_traits<B>::template read_element<1,0>(b);
  408. mat_traits<A>::template write_element<2,0>(a)-=mat_traits<B>::template read_element<2,0>(b);
  409. mat_traits<A>::template write_element<3,0>(a)-=mat_traits<B>::template read_element<3,0>(b);
  410. return a;
  411. }
  412. namespace
  413. sfinae
  414. {
  415. using ::boost::qvm::operator-=;
  416. }
  417. namespace
  418. qvm_detail
  419. {
  420. template <int R,int C>
  421. struct minus_eq_mm_defined;
  422. template <>
  423. struct
  424. minus_eq_mm_defined<4,1>
  425. {
  426. static bool const value=true;
  427. };
  428. }
  429. template <class A,class B>
  430. BOOST_QVM_INLINE_OPERATIONS
  431. typename enable_if_c<
  432. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  433. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  434. A &>::type
  435. operator-=( A & a, B const & b )
  436. {
  437. mat_traits<A>::template write_element<0,0>(a)-=mat_traits<B>::template read_element<0,0>(b);
  438. mat_traits<A>::template write_element<0,1>(a)-=mat_traits<B>::template read_element<0,1>(b);
  439. mat_traits<A>::template write_element<0,2>(a)-=mat_traits<B>::template read_element<0,2>(b);
  440. mat_traits<A>::template write_element<0,3>(a)-=mat_traits<B>::template read_element<0,3>(b);
  441. return a;
  442. }
  443. namespace
  444. sfinae
  445. {
  446. using ::boost::qvm::operator-=;
  447. }
  448. namespace
  449. qvm_detail
  450. {
  451. template <int R,int C>
  452. struct minus_eq_mm_defined;
  453. template <>
  454. struct
  455. minus_eq_mm_defined<1,4>
  456. {
  457. static bool const value=true;
  458. };
  459. }
  460. template <class A,class B>
  461. BOOST_QVM_INLINE_OPERATIONS
  462. typename lazy_enable_if_c<
  463. mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
  464. deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
  465. operator*( A const & a, B b )
  466. {
  467. typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
  468. R r;
  469. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)*b;
  470. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)*b;
  471. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)*b;
  472. mat_traits<R>::template write_element<0,3>(r)=mat_traits<A>::template read_element<0,3>(a)*b;
  473. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)*b;
  474. mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)*b;
  475. mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)*b;
  476. mat_traits<R>::template write_element<1,3>(r)=mat_traits<A>::template read_element<1,3>(a)*b;
  477. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)*b;
  478. mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)*b;
  479. mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)*b;
  480. mat_traits<R>::template write_element<2,3>(r)=mat_traits<A>::template read_element<2,3>(a)*b;
  481. mat_traits<R>::template write_element<3,0>(r)=mat_traits<A>::template read_element<3,0>(a)*b;
  482. mat_traits<R>::template write_element<3,1>(r)=mat_traits<A>::template read_element<3,1>(a)*b;
  483. mat_traits<R>::template write_element<3,2>(r)=mat_traits<A>::template read_element<3,2>(a)*b;
  484. mat_traits<R>::template write_element<3,3>(r)=mat_traits<A>::template read_element<3,3>(a)*b;
  485. return r;
  486. }
  487. namespace
  488. sfinae
  489. {
  490. using ::boost::qvm::operator*;
  491. }
  492. namespace
  493. qvm_detail
  494. {
  495. template <int R,int C>
  496. struct mul_ms_defined;
  497. template <>
  498. struct
  499. mul_ms_defined<4,4>
  500. {
  501. static bool const value=true;
  502. };
  503. }
  504. template <class A,class B>
  505. BOOST_QVM_INLINE_OPERATIONS
  506. typename lazy_enable_if_c<
  507. is_scalar<A>::value && mat_traits<B>::rows==4 && mat_traits<B>::cols==4,
  508. deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
  509. operator*( A a, B const & b )
  510. {
  511. typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
  512. R r;
  513. mat_traits<R>::template write_element<0,0>(r)=a*mat_traits<B>::template read_element<0,0>(b);
  514. mat_traits<R>::template write_element<0,1>(r)=a*mat_traits<B>::template read_element<0,1>(b);
  515. mat_traits<R>::template write_element<0,2>(r)=a*mat_traits<B>::template read_element<0,2>(b);
  516. mat_traits<R>::template write_element<0,3>(r)=a*mat_traits<B>::template read_element<0,3>(b);
  517. mat_traits<R>::template write_element<1,0>(r)=a*mat_traits<B>::template read_element<1,0>(b);
  518. mat_traits<R>::template write_element<1,1>(r)=a*mat_traits<B>::template read_element<1,1>(b);
  519. mat_traits<R>::template write_element<1,2>(r)=a*mat_traits<B>::template read_element<1,2>(b);
  520. mat_traits<R>::template write_element<1,3>(r)=a*mat_traits<B>::template read_element<1,3>(b);
  521. mat_traits<R>::template write_element<2,0>(r)=a*mat_traits<B>::template read_element<2,0>(b);
  522. mat_traits<R>::template write_element<2,1>(r)=a*mat_traits<B>::template read_element<2,1>(b);
  523. mat_traits<R>::template write_element<2,2>(r)=a*mat_traits<B>::template read_element<2,2>(b);
  524. mat_traits<R>::template write_element<2,3>(r)=a*mat_traits<B>::template read_element<2,3>(b);
  525. mat_traits<R>::template write_element<3,0>(r)=a*mat_traits<B>::template read_element<3,0>(b);
  526. mat_traits<R>::template write_element<3,1>(r)=a*mat_traits<B>::template read_element<3,1>(b);
  527. mat_traits<R>::template write_element<3,2>(r)=a*mat_traits<B>::template read_element<3,2>(b);
  528. mat_traits<R>::template write_element<3,3>(r)=a*mat_traits<B>::template read_element<3,3>(b);
  529. return r;
  530. }
  531. namespace
  532. sfinae
  533. {
  534. using ::boost::qvm::operator*;
  535. }
  536. namespace
  537. qvm_detail
  538. {
  539. template <int R,int C>
  540. struct mul_sm_defined;
  541. template <>
  542. struct
  543. mul_sm_defined<4,4>
  544. {
  545. static bool const value=true;
  546. };
  547. }
  548. template <class A,class B>
  549. BOOST_QVM_INLINE_OPERATIONS
  550. typename lazy_enable_if_c<
  551. mat_traits<A>::rows==4 && mat_traits<A>::cols==1 && is_scalar<B>::value,
  552. deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
  553. operator*( A const & a, B b )
  554. {
  555. typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
  556. R r;
  557. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)*b;
  558. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)*b;
  559. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)*b;
  560. mat_traits<R>::template write_element<3,0>(r)=mat_traits<A>::template read_element<3,0>(a)*b;
  561. return r;
  562. }
  563. namespace
  564. sfinae
  565. {
  566. using ::boost::qvm::operator*;
  567. }
  568. namespace
  569. qvm_detail
  570. {
  571. template <int R,int C>
  572. struct mul_ms_defined;
  573. template <>
  574. struct
  575. mul_ms_defined<4,1>
  576. {
  577. static bool const value=true;
  578. };
  579. }
  580. template <class A,class B>
  581. BOOST_QVM_INLINE_OPERATIONS
  582. typename lazy_enable_if_c<
  583. is_scalar<A>::value && mat_traits<B>::rows==4 && mat_traits<B>::cols==1,
  584. deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
  585. operator*( A a, B const & b )
  586. {
  587. typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
  588. R r;
  589. mat_traits<R>::template write_element<0,0>(r)=a*mat_traits<B>::template read_element<0,0>(b);
  590. mat_traits<R>::template write_element<1,0>(r)=a*mat_traits<B>::template read_element<1,0>(b);
  591. mat_traits<R>::template write_element<2,0>(r)=a*mat_traits<B>::template read_element<2,0>(b);
  592. mat_traits<R>::template write_element<3,0>(r)=a*mat_traits<B>::template read_element<3,0>(b);
  593. return r;
  594. }
  595. namespace
  596. sfinae
  597. {
  598. using ::boost::qvm::operator*;
  599. }
  600. namespace
  601. qvm_detail
  602. {
  603. template <int R,int C>
  604. struct mul_sm_defined;
  605. template <>
  606. struct
  607. mul_sm_defined<4,1>
  608. {
  609. static bool const value=true;
  610. };
  611. }
  612. template <class A,class B>
  613. BOOST_QVM_INLINE_OPERATIONS
  614. typename lazy_enable_if_c<
  615. mat_traits<A>::rows==1 && mat_traits<A>::cols==4 && is_scalar<B>::value,
  616. deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
  617. operator*( A const & a, B b )
  618. {
  619. typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
  620. R r;
  621. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)*b;
  622. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)*b;
  623. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)*b;
  624. mat_traits<R>::template write_element<0,3>(r)=mat_traits<A>::template read_element<0,3>(a)*b;
  625. return r;
  626. }
  627. namespace
  628. sfinae
  629. {
  630. using ::boost::qvm::operator*;
  631. }
  632. namespace
  633. qvm_detail
  634. {
  635. template <int R,int C>
  636. struct mul_ms_defined;
  637. template <>
  638. struct
  639. mul_ms_defined<1,4>
  640. {
  641. static bool const value=true;
  642. };
  643. }
  644. template <class A,class B>
  645. BOOST_QVM_INLINE_OPERATIONS
  646. typename lazy_enable_if_c<
  647. is_scalar<A>::value && mat_traits<B>::rows==1 && mat_traits<B>::cols==4,
  648. deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
  649. operator*( A a, B const & b )
  650. {
  651. typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
  652. R r;
  653. mat_traits<R>::template write_element<0,0>(r)=a*mat_traits<B>::template read_element<0,0>(b);
  654. mat_traits<R>::template write_element<0,1>(r)=a*mat_traits<B>::template read_element<0,1>(b);
  655. mat_traits<R>::template write_element<0,2>(r)=a*mat_traits<B>::template read_element<0,2>(b);
  656. mat_traits<R>::template write_element<0,3>(r)=a*mat_traits<B>::template read_element<0,3>(b);
  657. return r;
  658. }
  659. namespace
  660. sfinae
  661. {
  662. using ::boost::qvm::operator*;
  663. }
  664. namespace
  665. qvm_detail
  666. {
  667. template <int R,int C>
  668. struct mul_sm_defined;
  669. template <>
  670. struct
  671. mul_sm_defined<1,4>
  672. {
  673. static bool const value=true;
  674. };
  675. }
  676. template <class A,class B>
  677. BOOST_QVM_INLINE_OPERATIONS
  678. typename enable_if_c<
  679. mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
  680. A &>::type
  681. operator*=( A & a, B b )
  682. {
  683. mat_traits<A>::template write_element<0,0>(a)*=b;
  684. mat_traits<A>::template write_element<0,1>(a)*=b;
  685. mat_traits<A>::template write_element<0,2>(a)*=b;
  686. mat_traits<A>::template write_element<0,3>(a)*=b;
  687. mat_traits<A>::template write_element<1,0>(a)*=b;
  688. mat_traits<A>::template write_element<1,1>(a)*=b;
  689. mat_traits<A>::template write_element<1,2>(a)*=b;
  690. mat_traits<A>::template write_element<1,3>(a)*=b;
  691. mat_traits<A>::template write_element<2,0>(a)*=b;
  692. mat_traits<A>::template write_element<2,1>(a)*=b;
  693. mat_traits<A>::template write_element<2,2>(a)*=b;
  694. mat_traits<A>::template write_element<2,3>(a)*=b;
  695. mat_traits<A>::template write_element<3,0>(a)*=b;
  696. mat_traits<A>::template write_element<3,1>(a)*=b;
  697. mat_traits<A>::template write_element<3,2>(a)*=b;
  698. mat_traits<A>::template write_element<3,3>(a)*=b;
  699. return a;
  700. }
  701. namespace
  702. sfinae
  703. {
  704. using ::boost::qvm::operator*=;
  705. }
  706. namespace
  707. qvm_detail
  708. {
  709. template <int R,int C>
  710. struct mul_eq_ms_defined;
  711. template <>
  712. struct
  713. mul_eq_ms_defined<4,4>
  714. {
  715. static bool const value=true;
  716. };
  717. }
  718. template <class A,class B>
  719. BOOST_QVM_INLINE_OPERATIONS
  720. typename enable_if_c<
  721. mat_traits<A>::rows==4 && mat_traits<A>::cols==1 && is_scalar<B>::value,
  722. A &>::type
  723. operator*=( A & a, B b )
  724. {
  725. mat_traits<A>::template write_element<0,0>(a)*=b;
  726. mat_traits<A>::template write_element<1,0>(a)*=b;
  727. mat_traits<A>::template write_element<2,0>(a)*=b;
  728. mat_traits<A>::template write_element<3,0>(a)*=b;
  729. return a;
  730. }
  731. namespace
  732. sfinae
  733. {
  734. using ::boost::qvm::operator*=;
  735. }
  736. namespace
  737. qvm_detail
  738. {
  739. template <int R,int C>
  740. struct mul_eq_ms_defined;
  741. template <>
  742. struct
  743. mul_eq_ms_defined<4,1>
  744. {
  745. static bool const value=true;
  746. };
  747. }
  748. template <class A,class B>
  749. BOOST_QVM_INLINE_OPERATIONS
  750. typename enable_if_c<
  751. mat_traits<A>::rows==1 && mat_traits<A>::cols==4 && is_scalar<B>::value,
  752. A &>::type
  753. operator*=( A & a, B b )
  754. {
  755. mat_traits<A>::template write_element<0,0>(a)*=b;
  756. mat_traits<A>::template write_element<0,1>(a)*=b;
  757. mat_traits<A>::template write_element<0,2>(a)*=b;
  758. mat_traits<A>::template write_element<0,3>(a)*=b;
  759. return a;
  760. }
  761. namespace
  762. sfinae
  763. {
  764. using ::boost::qvm::operator*=;
  765. }
  766. namespace
  767. qvm_detail
  768. {
  769. template <int R,int C>
  770. struct mul_eq_ms_defined;
  771. template <>
  772. struct
  773. mul_eq_ms_defined<1,4>
  774. {
  775. static bool const value=true;
  776. };
  777. }
  778. template <class A,class B>
  779. BOOST_QVM_INLINE_OPERATIONS
  780. typename lazy_enable_if_c<
  781. mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
  782. deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
  783. operator/( A const & a, B b )
  784. {
  785. typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
  786. R r;
  787. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)/b;
  788. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)/b;
  789. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)/b;
  790. mat_traits<R>::template write_element<0,3>(r)=mat_traits<A>::template read_element<0,3>(a)/b;
  791. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)/b;
  792. mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)/b;
  793. mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)/b;
  794. mat_traits<R>::template write_element<1,3>(r)=mat_traits<A>::template read_element<1,3>(a)/b;
  795. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)/b;
  796. mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)/b;
  797. mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)/b;
  798. mat_traits<R>::template write_element<2,3>(r)=mat_traits<A>::template read_element<2,3>(a)/b;
  799. mat_traits<R>::template write_element<3,0>(r)=mat_traits<A>::template read_element<3,0>(a)/b;
  800. mat_traits<R>::template write_element<3,1>(r)=mat_traits<A>::template read_element<3,1>(a)/b;
  801. mat_traits<R>::template write_element<3,2>(r)=mat_traits<A>::template read_element<3,2>(a)/b;
  802. mat_traits<R>::template write_element<3,3>(r)=mat_traits<A>::template read_element<3,3>(a)/b;
  803. return r;
  804. }
  805. namespace
  806. sfinae
  807. {
  808. using ::boost::qvm::operator/;
  809. }
  810. namespace
  811. qvm_detail
  812. {
  813. template <int R,int C>
  814. struct div_ms_defined;
  815. template <>
  816. struct
  817. div_ms_defined<4,4>
  818. {
  819. static bool const value=true;
  820. };
  821. }
  822. template <class A,class B>
  823. BOOST_QVM_INLINE_OPERATIONS
  824. typename lazy_enable_if_c<
  825. is_scalar<A>::value && mat_traits<B>::rows==4 && mat_traits<B>::cols==4,
  826. deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
  827. operator/( A a, B const & b )
  828. {
  829. typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
  830. R r;
  831. mat_traits<R>::template write_element<0,0>(r)=a/mat_traits<B>::template read_element<0,0>(b);
  832. mat_traits<R>::template write_element<0,1>(r)=a/mat_traits<B>::template read_element<0,1>(b);
  833. mat_traits<R>::template write_element<0,2>(r)=a/mat_traits<B>::template read_element<0,2>(b);
  834. mat_traits<R>::template write_element<0,3>(r)=a/mat_traits<B>::template read_element<0,3>(b);
  835. mat_traits<R>::template write_element<1,0>(r)=a/mat_traits<B>::template read_element<1,0>(b);
  836. mat_traits<R>::template write_element<1,1>(r)=a/mat_traits<B>::template read_element<1,1>(b);
  837. mat_traits<R>::template write_element<1,2>(r)=a/mat_traits<B>::template read_element<1,2>(b);
  838. mat_traits<R>::template write_element<1,3>(r)=a/mat_traits<B>::template read_element<1,3>(b);
  839. mat_traits<R>::template write_element<2,0>(r)=a/mat_traits<B>::template read_element<2,0>(b);
  840. mat_traits<R>::template write_element<2,1>(r)=a/mat_traits<B>::template read_element<2,1>(b);
  841. mat_traits<R>::template write_element<2,2>(r)=a/mat_traits<B>::template read_element<2,2>(b);
  842. mat_traits<R>::template write_element<2,3>(r)=a/mat_traits<B>::template read_element<2,3>(b);
  843. mat_traits<R>::template write_element<3,0>(r)=a/mat_traits<B>::template read_element<3,0>(b);
  844. mat_traits<R>::template write_element<3,1>(r)=a/mat_traits<B>::template read_element<3,1>(b);
  845. mat_traits<R>::template write_element<3,2>(r)=a/mat_traits<B>::template read_element<3,2>(b);
  846. mat_traits<R>::template write_element<3,3>(r)=a/mat_traits<B>::template read_element<3,3>(b);
  847. return r;
  848. }
  849. namespace
  850. sfinae
  851. {
  852. using ::boost::qvm::operator/;
  853. }
  854. namespace
  855. qvm_detail
  856. {
  857. template <int R,int C>
  858. struct div_sm_defined;
  859. template <>
  860. struct
  861. div_sm_defined<4,4>
  862. {
  863. static bool const value=true;
  864. };
  865. }
  866. template <class A,class B>
  867. BOOST_QVM_INLINE_OPERATIONS
  868. typename lazy_enable_if_c<
  869. mat_traits<A>::rows==4 && mat_traits<A>::cols==1 && is_scalar<B>::value,
  870. deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
  871. operator/( A const & a, B b )
  872. {
  873. typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
  874. R r;
  875. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)/b;
  876. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)/b;
  877. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)/b;
  878. mat_traits<R>::template write_element<3,0>(r)=mat_traits<A>::template read_element<3,0>(a)/b;
  879. return r;
  880. }
  881. namespace
  882. sfinae
  883. {
  884. using ::boost::qvm::operator/;
  885. }
  886. namespace
  887. qvm_detail
  888. {
  889. template <int R,int C>
  890. struct div_ms_defined;
  891. template <>
  892. struct
  893. div_ms_defined<4,1>
  894. {
  895. static bool const value=true;
  896. };
  897. }
  898. template <class A,class B>
  899. BOOST_QVM_INLINE_OPERATIONS
  900. typename lazy_enable_if_c<
  901. is_scalar<A>::value && mat_traits<B>::rows==4 && mat_traits<B>::cols==1,
  902. deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
  903. operator/( A a, B const & b )
  904. {
  905. typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
  906. R r;
  907. mat_traits<R>::template write_element<0,0>(r)=a/mat_traits<B>::template read_element<0,0>(b);
  908. mat_traits<R>::template write_element<1,0>(r)=a/mat_traits<B>::template read_element<1,0>(b);
  909. mat_traits<R>::template write_element<2,0>(r)=a/mat_traits<B>::template read_element<2,0>(b);
  910. mat_traits<R>::template write_element<3,0>(r)=a/mat_traits<B>::template read_element<3,0>(b);
  911. return r;
  912. }
  913. namespace
  914. sfinae
  915. {
  916. using ::boost::qvm::operator/;
  917. }
  918. namespace
  919. qvm_detail
  920. {
  921. template <int R,int C>
  922. struct div_sm_defined;
  923. template <>
  924. struct
  925. div_sm_defined<4,1>
  926. {
  927. static bool const value=true;
  928. };
  929. }
  930. template <class A,class B>
  931. BOOST_QVM_INLINE_OPERATIONS
  932. typename lazy_enable_if_c<
  933. mat_traits<A>::rows==1 && mat_traits<A>::cols==4 && is_scalar<B>::value,
  934. deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
  935. operator/( A const & a, B b )
  936. {
  937. typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
  938. R r;
  939. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)/b;
  940. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)/b;
  941. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)/b;
  942. mat_traits<R>::template write_element<0,3>(r)=mat_traits<A>::template read_element<0,3>(a)/b;
  943. return r;
  944. }
  945. namespace
  946. sfinae
  947. {
  948. using ::boost::qvm::operator/;
  949. }
  950. namespace
  951. qvm_detail
  952. {
  953. template <int R,int C>
  954. struct div_ms_defined;
  955. template <>
  956. struct
  957. div_ms_defined<1,4>
  958. {
  959. static bool const value=true;
  960. };
  961. }
  962. template <class A,class B>
  963. BOOST_QVM_INLINE_OPERATIONS
  964. typename enable_if_c<
  965. mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
  966. A &>::type
  967. operator/=( A & a, B b )
  968. {
  969. mat_traits<A>::template write_element<0,0>(a)/=b;
  970. mat_traits<A>::template write_element<0,1>(a)/=b;
  971. mat_traits<A>::template write_element<0,2>(a)/=b;
  972. mat_traits<A>::template write_element<0,3>(a)/=b;
  973. mat_traits<A>::template write_element<1,0>(a)/=b;
  974. mat_traits<A>::template write_element<1,1>(a)/=b;
  975. mat_traits<A>::template write_element<1,2>(a)/=b;
  976. mat_traits<A>::template write_element<1,3>(a)/=b;
  977. mat_traits<A>::template write_element<2,0>(a)/=b;
  978. mat_traits<A>::template write_element<2,1>(a)/=b;
  979. mat_traits<A>::template write_element<2,2>(a)/=b;
  980. mat_traits<A>::template write_element<2,3>(a)/=b;
  981. mat_traits<A>::template write_element<3,0>(a)/=b;
  982. mat_traits<A>::template write_element<3,1>(a)/=b;
  983. mat_traits<A>::template write_element<3,2>(a)/=b;
  984. mat_traits<A>::template write_element<3,3>(a)/=b;
  985. return a;
  986. }
  987. namespace
  988. sfinae
  989. {
  990. using ::boost::qvm::operator/=;
  991. }
  992. namespace
  993. qvm_detail
  994. {
  995. template <int R,int C>
  996. struct div_eq_ms_defined;
  997. template <>
  998. struct
  999. div_eq_ms_defined<4,4>
  1000. {
  1001. static bool const value=true;
  1002. };
  1003. }
  1004. template <class A,class B>
  1005. BOOST_QVM_INLINE_OPERATIONS
  1006. typename enable_if_c<
  1007. mat_traits<A>::rows==4 && mat_traits<A>::cols==1 && is_scalar<B>::value,
  1008. A &>::type
  1009. operator/=( A & a, B b )
  1010. {
  1011. mat_traits<A>::template write_element<0,0>(a)/=b;
  1012. mat_traits<A>::template write_element<1,0>(a)/=b;
  1013. mat_traits<A>::template write_element<2,0>(a)/=b;
  1014. mat_traits<A>::template write_element<3,0>(a)/=b;
  1015. return a;
  1016. }
  1017. namespace
  1018. sfinae
  1019. {
  1020. using ::boost::qvm::operator/=;
  1021. }
  1022. namespace
  1023. qvm_detail
  1024. {
  1025. template <int R,int C>
  1026. struct div_eq_ms_defined;
  1027. template <>
  1028. struct
  1029. div_eq_ms_defined<4,1>
  1030. {
  1031. static bool const value=true;
  1032. };
  1033. }
  1034. template <class A,class B>
  1035. BOOST_QVM_INLINE_OPERATIONS
  1036. typename enable_if_c<
  1037. mat_traits<A>::rows==1 && mat_traits<A>::cols==4 && is_scalar<B>::value,
  1038. A &>::type
  1039. operator/=( A & a, B b )
  1040. {
  1041. mat_traits<A>::template write_element<0,0>(a)/=b;
  1042. mat_traits<A>::template write_element<0,1>(a)/=b;
  1043. mat_traits<A>::template write_element<0,2>(a)/=b;
  1044. mat_traits<A>::template write_element<0,3>(a)/=b;
  1045. return a;
  1046. }
  1047. namespace
  1048. sfinae
  1049. {
  1050. using ::boost::qvm::operator/=;
  1051. }
  1052. namespace
  1053. qvm_detail
  1054. {
  1055. template <int R,int C>
  1056. struct div_eq_ms_defined;
  1057. template <>
  1058. struct
  1059. div_eq_ms_defined<1,4>
  1060. {
  1061. static bool const value=true;
  1062. };
  1063. }
  1064. template <class R,class A>
  1065. BOOST_QVM_INLINE_OPERATIONS
  1066. typename enable_if_c<
  1067. mat_traits<R>::rows==4 && mat_traits<A>::rows==4 &&
  1068. mat_traits<R>::cols==4 && mat_traits<A>::cols==4,
  1069. R>::type
  1070. convert_to( A const & a )
  1071. {
  1072. R r;
  1073. mat_traits<R>::template write_element<0,0>(r) = mat_traits<A>::template read_element<0,0>(a);
  1074. mat_traits<R>::template write_element<0,1>(r) = mat_traits<A>::template read_element<0,1>(a);
  1075. mat_traits<R>::template write_element<0,2>(r) = mat_traits<A>::template read_element<0,2>(a);
  1076. mat_traits<R>::template write_element<0,3>(r) = mat_traits<A>::template read_element<0,3>(a);
  1077. mat_traits<R>::template write_element<1,0>(r) = mat_traits<A>::template read_element<1,0>(a);
  1078. mat_traits<R>::template write_element<1,1>(r) = mat_traits<A>::template read_element<1,1>(a);
  1079. mat_traits<R>::template write_element<1,2>(r) = mat_traits<A>::template read_element<1,2>(a);
  1080. mat_traits<R>::template write_element<1,3>(r) = mat_traits<A>::template read_element<1,3>(a);
  1081. mat_traits<R>::template write_element<2,0>(r) = mat_traits<A>::template read_element<2,0>(a);
  1082. mat_traits<R>::template write_element<2,1>(r) = mat_traits<A>::template read_element<2,1>(a);
  1083. mat_traits<R>::template write_element<2,2>(r) = mat_traits<A>::template read_element<2,2>(a);
  1084. mat_traits<R>::template write_element<2,3>(r) = mat_traits<A>::template read_element<2,3>(a);
  1085. mat_traits<R>::template write_element<3,0>(r) = mat_traits<A>::template read_element<3,0>(a);
  1086. mat_traits<R>::template write_element<3,1>(r) = mat_traits<A>::template read_element<3,1>(a);
  1087. mat_traits<R>::template write_element<3,2>(r) = mat_traits<A>::template read_element<3,2>(a);
  1088. mat_traits<R>::template write_element<3,3>(r) = mat_traits<A>::template read_element<3,3>(a);
  1089. return r;
  1090. }
  1091. template <class R,class A>
  1092. BOOST_QVM_INLINE
  1093. typename enable_if_c<
  1094. is_mat<R>::value && is_quat<A>::value &&
  1095. mat_traits<R>::rows==4 && mat_traits<R>::cols==4,
  1096. R>::type
  1097. convert_to( A const & q )
  1098. {
  1099. typedef typename mat_traits<R>::scalar_type T;
  1100. T const a=quat_traits<A>::template read_element<0>(q);
  1101. T const b=quat_traits<A>::template read_element<1>(q);
  1102. T const c=quat_traits<A>::template read_element<2>(q);
  1103. T const d=quat_traits<A>::template read_element<3>(q);
  1104. T const bb = b*b;
  1105. T const cc = c*c;
  1106. T const dd = d*d;
  1107. T const bc = b*c;
  1108. T const bd = b*d;
  1109. T const cd = c*d;
  1110. T const ab = a*b;
  1111. T const ac = a*c;
  1112. T const ad = a*d;
  1113. T const zero = scalar_traits<T>::value(0);
  1114. T const one = scalar_traits<T>::value(1);
  1115. T const two = one+one;
  1116. R r;
  1117. mat_traits<R>::template write_element<0,0>(r) = one - two*(cc+dd);
  1118. mat_traits<R>::template write_element<0,1>(r) = two*(bc-ad);
  1119. mat_traits<R>::template write_element<0,2>(r) = two*(bd+ac);
  1120. mat_traits<R>::template write_element<0,3>(r) = zero;
  1121. mat_traits<R>::template write_element<1,0>(r) = two*(bc+ad);
  1122. mat_traits<R>::template write_element<1,1>(r) = one - two*(bb+dd);
  1123. mat_traits<R>::template write_element<1,2>(r) = two*(cd-ab);
  1124. mat_traits<R>::template write_element<1,3>(r) = zero;
  1125. mat_traits<R>::template write_element<2,0>(r) = two*(bd-ac);
  1126. mat_traits<R>::template write_element<2,1>(r) = two*(cd+ab);
  1127. mat_traits<R>::template write_element<2,2>(r) = one - two*(bb+cc);
  1128. mat_traits<R>::template write_element<2,3>(r) = zero;
  1129. mat_traits<R>::template write_element<3,0>(r) = zero;
  1130. mat_traits<R>::template write_element<3,1>(r) = zero;
  1131. mat_traits<R>::template write_element<3,2>(r) = zero;
  1132. mat_traits<R>::template write_element<3,3>(r) = one;
  1133. return r;
  1134. }
  1135. namespace
  1136. sfinae
  1137. {
  1138. using ::boost::qvm::convert_to;
  1139. }
  1140. namespace
  1141. qvm_detail
  1142. {
  1143. template <int R,int C>
  1144. struct convert_to_m_defined;
  1145. template <>
  1146. struct
  1147. convert_to_m_defined<4,4>
  1148. {
  1149. static bool const value=true;
  1150. };
  1151. }
  1152. template <class R,class A>
  1153. BOOST_QVM_INLINE_OPERATIONS
  1154. typename enable_if_c<
  1155. mat_traits<R>::rows==4 && mat_traits<A>::rows==4 &&
  1156. mat_traits<R>::cols==1 && mat_traits<A>::cols==1,
  1157. R>::type
  1158. convert_to( A const & a )
  1159. {
  1160. R r;
  1161. mat_traits<R>::template write_element<0,0>(r) = mat_traits<A>::template read_element<0,0>(a);
  1162. mat_traits<R>::template write_element<1,0>(r) = mat_traits<A>::template read_element<1,0>(a);
  1163. mat_traits<R>::template write_element<2,0>(r) = mat_traits<A>::template read_element<2,0>(a);
  1164. mat_traits<R>::template write_element<3,0>(r) = mat_traits<A>::template read_element<3,0>(a);
  1165. return r;
  1166. }
  1167. namespace
  1168. sfinae
  1169. {
  1170. using ::boost::qvm::convert_to;
  1171. }
  1172. namespace
  1173. qvm_detail
  1174. {
  1175. template <int R,int C>
  1176. struct convert_to_m_defined;
  1177. template <>
  1178. struct
  1179. convert_to_m_defined<4,1>
  1180. {
  1181. static bool const value=true;
  1182. };
  1183. }
  1184. template <class R,class A>
  1185. BOOST_QVM_INLINE_OPERATIONS
  1186. typename enable_if_c<
  1187. mat_traits<R>::rows==1 && mat_traits<A>::rows==1 &&
  1188. mat_traits<R>::cols==4 && mat_traits<A>::cols==4,
  1189. R>::type
  1190. convert_to( A const & a )
  1191. {
  1192. R r;
  1193. mat_traits<R>::template write_element<0,0>(r) = mat_traits<A>::template read_element<0,0>(a);
  1194. mat_traits<R>::template write_element<0,1>(r) = mat_traits<A>::template read_element<0,1>(a);
  1195. mat_traits<R>::template write_element<0,2>(r) = mat_traits<A>::template read_element<0,2>(a);
  1196. mat_traits<R>::template write_element<0,3>(r) = mat_traits<A>::template read_element<0,3>(a);
  1197. return r;
  1198. }
  1199. namespace
  1200. sfinae
  1201. {
  1202. using ::boost::qvm::convert_to;
  1203. }
  1204. namespace
  1205. qvm_detail
  1206. {
  1207. template <int R,int C>
  1208. struct convert_to_m_defined;
  1209. template <>
  1210. struct
  1211. convert_to_m_defined<1,4>
  1212. {
  1213. static bool const value=true;
  1214. };
  1215. }
  1216. template <class A,class B>
  1217. BOOST_QVM_INLINE_OPERATIONS
  1218. typename enable_if_c<
  1219. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  1220. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  1221. bool>::type
  1222. operator==( A const & a, B const & b )
  1223. {
  1224. return
  1225. mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
  1226. mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) &&
  1227. mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b) &&
  1228. mat_traits<A>::template read_element<0,3>(a)==mat_traits<B>::template read_element<0,3>(b) &&
  1229. mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) &&
  1230. mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b) &&
  1231. mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b) &&
  1232. mat_traits<A>::template read_element<1,3>(a)==mat_traits<B>::template read_element<1,3>(b) &&
  1233. mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b) &&
  1234. mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b) &&
  1235. mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b) &&
  1236. mat_traits<A>::template read_element<2,3>(a)==mat_traits<B>::template read_element<2,3>(b) &&
  1237. mat_traits<A>::template read_element<3,0>(a)==mat_traits<B>::template read_element<3,0>(b) &&
  1238. mat_traits<A>::template read_element<3,1>(a)==mat_traits<B>::template read_element<3,1>(b) &&
  1239. mat_traits<A>::template read_element<3,2>(a)==mat_traits<B>::template read_element<3,2>(b) &&
  1240. mat_traits<A>::template read_element<3,3>(a)==mat_traits<B>::template read_element<3,3>(b);
  1241. }
  1242. namespace
  1243. sfinae
  1244. {
  1245. using ::boost::qvm::operator==;
  1246. }
  1247. namespace
  1248. qvm_detail
  1249. {
  1250. template <int R,int C>
  1251. struct eq_mm_defined;
  1252. template <>
  1253. struct
  1254. eq_mm_defined<4,4>
  1255. {
  1256. static bool const value=true;
  1257. };
  1258. }
  1259. template <class A,class B>
  1260. BOOST_QVM_INLINE_OPERATIONS
  1261. typename enable_if_c<
  1262. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  1263. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  1264. bool>::type
  1265. operator==( A const & a, B const & b )
  1266. {
  1267. return
  1268. mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
  1269. mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) &&
  1270. mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b) &&
  1271. mat_traits<A>::template read_element<3,0>(a)==mat_traits<B>::template read_element<3,0>(b);
  1272. }
  1273. namespace
  1274. sfinae
  1275. {
  1276. using ::boost::qvm::operator==;
  1277. }
  1278. namespace
  1279. qvm_detail
  1280. {
  1281. template <int R,int C>
  1282. struct eq_mm_defined;
  1283. template <>
  1284. struct
  1285. eq_mm_defined<4,1>
  1286. {
  1287. static bool const value=true;
  1288. };
  1289. }
  1290. template <class A,class B>
  1291. BOOST_QVM_INLINE_OPERATIONS
  1292. typename enable_if_c<
  1293. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  1294. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  1295. bool>::type
  1296. operator==( A const & a, B const & b )
  1297. {
  1298. return
  1299. mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
  1300. mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) &&
  1301. mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b) &&
  1302. mat_traits<A>::template read_element<0,3>(a)==mat_traits<B>::template read_element<0,3>(b);
  1303. }
  1304. namespace
  1305. sfinae
  1306. {
  1307. using ::boost::qvm::operator==;
  1308. }
  1309. namespace
  1310. qvm_detail
  1311. {
  1312. template <int R,int C>
  1313. struct eq_mm_defined;
  1314. template <>
  1315. struct
  1316. eq_mm_defined<1,4>
  1317. {
  1318. static bool const value=true;
  1319. };
  1320. }
  1321. template <class A,class B>
  1322. BOOST_QVM_INLINE_OPERATIONS
  1323. typename enable_if_c<
  1324. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  1325. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  1326. bool>::type
  1327. operator!=( A const & a, B const & b )
  1328. {
  1329. return
  1330. !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
  1331. !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) ||
  1332. !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b)) ||
  1333. !(mat_traits<A>::template read_element<0,3>(a)==mat_traits<B>::template read_element<0,3>(b)) ||
  1334. !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) ||
  1335. !(mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b)) ||
  1336. !(mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b)) ||
  1337. !(mat_traits<A>::template read_element<1,3>(a)==mat_traits<B>::template read_element<1,3>(b)) ||
  1338. !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b)) ||
  1339. !(mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b)) ||
  1340. !(mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b)) ||
  1341. !(mat_traits<A>::template read_element<2,3>(a)==mat_traits<B>::template read_element<2,3>(b)) ||
  1342. !(mat_traits<A>::template read_element<3,0>(a)==mat_traits<B>::template read_element<3,0>(b)) ||
  1343. !(mat_traits<A>::template read_element<3,1>(a)==mat_traits<B>::template read_element<3,1>(b)) ||
  1344. !(mat_traits<A>::template read_element<3,2>(a)==mat_traits<B>::template read_element<3,2>(b)) ||
  1345. !(mat_traits<A>::template read_element<3,3>(a)==mat_traits<B>::template read_element<3,3>(b));
  1346. }
  1347. namespace
  1348. sfinae
  1349. {
  1350. using ::boost::qvm::operator!=;
  1351. }
  1352. namespace
  1353. qvm_detail
  1354. {
  1355. template <int R,int C>
  1356. struct neq_mm_defined;
  1357. template <>
  1358. struct
  1359. neq_mm_defined<4,4>
  1360. {
  1361. static bool const value=true;
  1362. };
  1363. }
  1364. template <class A,class B>
  1365. BOOST_QVM_INLINE_OPERATIONS
  1366. typename enable_if_c<
  1367. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  1368. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  1369. bool>::type
  1370. operator!=( A const & a, B const & b )
  1371. {
  1372. return
  1373. !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
  1374. !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) ||
  1375. !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b)) ||
  1376. !(mat_traits<A>::template read_element<3,0>(a)==mat_traits<B>::template read_element<3,0>(b));
  1377. }
  1378. namespace
  1379. sfinae
  1380. {
  1381. using ::boost::qvm::operator!=;
  1382. }
  1383. namespace
  1384. qvm_detail
  1385. {
  1386. template <int R,int C>
  1387. struct neq_mm_defined;
  1388. template <>
  1389. struct
  1390. neq_mm_defined<4,1>
  1391. {
  1392. static bool const value=true;
  1393. };
  1394. }
  1395. template <class A,class B>
  1396. BOOST_QVM_INLINE_OPERATIONS
  1397. typename enable_if_c<
  1398. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  1399. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  1400. bool>::type
  1401. operator!=( A const & a, B const & b )
  1402. {
  1403. return
  1404. !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
  1405. !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) ||
  1406. !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b)) ||
  1407. !(mat_traits<A>::template read_element<0,3>(a)==mat_traits<B>::template read_element<0,3>(b));
  1408. }
  1409. namespace
  1410. sfinae
  1411. {
  1412. using ::boost::qvm::operator!=;
  1413. }
  1414. namespace
  1415. qvm_detail
  1416. {
  1417. template <int R,int C>
  1418. struct neq_mm_defined;
  1419. template <>
  1420. struct
  1421. neq_mm_defined<1,4>
  1422. {
  1423. static bool const value=true;
  1424. };
  1425. }
  1426. template <class A>
  1427. BOOST_QVM_INLINE_OPERATIONS
  1428. typename lazy_enable_if_c<
  1429. mat_traits<A>::rows==4 && mat_traits<A>::cols==4,
  1430. deduce_mat<A> >::type
  1431. operator-( A const & a )
  1432. {
  1433. typedef typename deduce_mat<A>::type R;
  1434. R r;
  1435. mat_traits<R>::template write_element<0,0>(r)=-mat_traits<A>::template read_element<0,0>(a);
  1436. mat_traits<R>::template write_element<0,1>(r)=-mat_traits<A>::template read_element<0,1>(a);
  1437. mat_traits<R>::template write_element<0,2>(r)=-mat_traits<A>::template read_element<0,2>(a);
  1438. mat_traits<R>::template write_element<0,3>(r)=-mat_traits<A>::template read_element<0,3>(a);
  1439. mat_traits<R>::template write_element<1,0>(r)=-mat_traits<A>::template read_element<1,0>(a);
  1440. mat_traits<R>::template write_element<1,1>(r)=-mat_traits<A>::template read_element<1,1>(a);
  1441. mat_traits<R>::template write_element<1,2>(r)=-mat_traits<A>::template read_element<1,2>(a);
  1442. mat_traits<R>::template write_element<1,3>(r)=-mat_traits<A>::template read_element<1,3>(a);
  1443. mat_traits<R>::template write_element<2,0>(r)=-mat_traits<A>::template read_element<2,0>(a);
  1444. mat_traits<R>::template write_element<2,1>(r)=-mat_traits<A>::template read_element<2,1>(a);
  1445. mat_traits<R>::template write_element<2,2>(r)=-mat_traits<A>::template read_element<2,2>(a);
  1446. mat_traits<R>::template write_element<2,3>(r)=-mat_traits<A>::template read_element<2,3>(a);
  1447. mat_traits<R>::template write_element<3,0>(r)=-mat_traits<A>::template read_element<3,0>(a);
  1448. mat_traits<R>::template write_element<3,1>(r)=-mat_traits<A>::template read_element<3,1>(a);
  1449. mat_traits<R>::template write_element<3,2>(r)=-mat_traits<A>::template read_element<3,2>(a);
  1450. mat_traits<R>::template write_element<3,3>(r)=-mat_traits<A>::template read_element<3,3>(a);
  1451. return r;
  1452. }
  1453. namespace
  1454. sfinae
  1455. {
  1456. using ::boost::qvm::operator-;
  1457. }
  1458. namespace
  1459. qvm_detail
  1460. {
  1461. template <int R,int C>
  1462. struct minus_m_defined;
  1463. template <>
  1464. struct
  1465. minus_m_defined<4,4>
  1466. {
  1467. static bool const value=true;
  1468. };
  1469. }
  1470. template <class A>
  1471. BOOST_QVM_INLINE_OPERATIONS
  1472. typename lazy_enable_if_c<
  1473. mat_traits<A>::rows==4 && mat_traits<A>::cols==1,
  1474. deduce_mat<A> >::type
  1475. operator-( A const & a )
  1476. {
  1477. typedef typename deduce_mat<A>::type R;
  1478. R r;
  1479. mat_traits<R>::template write_element<0,0>(r)=-mat_traits<A>::template read_element<0,0>(a);
  1480. mat_traits<R>::template write_element<1,0>(r)=-mat_traits<A>::template read_element<1,0>(a);
  1481. mat_traits<R>::template write_element<2,0>(r)=-mat_traits<A>::template read_element<2,0>(a);
  1482. mat_traits<R>::template write_element<3,0>(r)=-mat_traits<A>::template read_element<3,0>(a);
  1483. return r;
  1484. }
  1485. namespace
  1486. sfinae
  1487. {
  1488. using ::boost::qvm::operator-;
  1489. }
  1490. namespace
  1491. qvm_detail
  1492. {
  1493. template <int R,int C>
  1494. struct minus_m_defined;
  1495. template <>
  1496. struct
  1497. minus_m_defined<4,1>
  1498. {
  1499. static bool const value=true;
  1500. };
  1501. }
  1502. template <class A>
  1503. BOOST_QVM_INLINE_OPERATIONS
  1504. typename lazy_enable_if_c<
  1505. mat_traits<A>::rows==1 && mat_traits<A>::cols==4,
  1506. deduce_mat<A> >::type
  1507. operator-( A const & a )
  1508. {
  1509. typedef typename deduce_mat<A>::type R;
  1510. R r;
  1511. mat_traits<R>::template write_element<0,0>(r)=-mat_traits<A>::template read_element<0,0>(a);
  1512. mat_traits<R>::template write_element<0,1>(r)=-mat_traits<A>::template read_element<0,1>(a);
  1513. mat_traits<R>::template write_element<0,2>(r)=-mat_traits<A>::template read_element<0,2>(a);
  1514. mat_traits<R>::template write_element<0,3>(r)=-mat_traits<A>::template read_element<0,3>(a);
  1515. return r;
  1516. }
  1517. namespace
  1518. sfinae
  1519. {
  1520. using ::boost::qvm::operator-;
  1521. }
  1522. namespace
  1523. qvm_detail
  1524. {
  1525. template <int R,int C>
  1526. struct minus_m_defined;
  1527. template <>
  1528. struct
  1529. minus_m_defined<1,4>
  1530. {
  1531. static bool const value=true;
  1532. };
  1533. }
  1534. template <class A>
  1535. BOOST_QVM_INLINE_OPERATIONS
  1536. typename enable_if_c<
  1537. mat_traits<A>::rows==4 && mat_traits<A>::cols==4,
  1538. typename mat_traits<A>::scalar_type>::type
  1539. determinant( A const & a )
  1540. {
  1541. typedef typename mat_traits<A>::scalar_type T;
  1542. T const a00=mat_traits<A>::template read_element<0,0>(a);
  1543. T const a01=mat_traits<A>::template read_element<0,1>(a);
  1544. T const a02=mat_traits<A>::template read_element<0,2>(a);
  1545. T const a03=mat_traits<A>::template read_element<0,3>(a);
  1546. T const a10=mat_traits<A>::template read_element<1,0>(a);
  1547. T const a11=mat_traits<A>::template read_element<1,1>(a);
  1548. T const a12=mat_traits<A>::template read_element<1,2>(a);
  1549. T const a13=mat_traits<A>::template read_element<1,3>(a);
  1550. T const a20=mat_traits<A>::template read_element<2,0>(a);
  1551. T const a21=mat_traits<A>::template read_element<2,1>(a);
  1552. T const a22=mat_traits<A>::template read_element<2,2>(a);
  1553. T const a23=mat_traits<A>::template read_element<2,3>(a);
  1554. T const a30=mat_traits<A>::template read_element<3,0>(a);
  1555. T const a31=mat_traits<A>::template read_element<3,1>(a);
  1556. T const a32=mat_traits<A>::template read_element<3,2>(a);
  1557. T const a33=mat_traits<A>::template read_element<3,3>(a);
  1558. T det=(a00*(a11*(a22*a33-a23*a32)-a12*(a21*a33-a23*a31)+a13*(a21*a32-a22*a31))-a01*(a10*(a22*a33-a23*a32)-a12*(a20*a33-a23*a30)+a13*(a20*a32-a22*a30))+a02*(a10*(a21*a33-a23*a31)-a11*(a20*a33-a23*a30)+a13*(a20*a31-a21*a30))-a03*(a10*(a21*a32-a22*a31)-a11*(a20*a32-a22*a30)+a12*(a20*a31-a21*a30)));
  1559. return det;
  1560. }
  1561. namespace
  1562. sfinae
  1563. {
  1564. using ::boost::qvm::determinant;
  1565. }
  1566. namespace
  1567. qvm_detail
  1568. {
  1569. template <int D>
  1570. struct determinant_defined;
  1571. template <>
  1572. struct
  1573. determinant_defined<4>
  1574. {
  1575. static bool const value=true;
  1576. };
  1577. }
  1578. template <class A,class B>
  1579. BOOST_QVM_INLINE_OPERATIONS
  1580. typename lazy_enable_if_c<
  1581. mat_traits<A>::rows==4 && mat_traits<A>::cols==4 && is_scalar<B>::value,
  1582. deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
  1583. inverse( A const & a, B det )
  1584. {
  1585. typedef typename mat_traits<A>::scalar_type T;
  1586. BOOST_QVM_ASSERT(det!=scalar_traits<B>::value(0));
  1587. T const a00=mat_traits<A>::template read_element<0,0>(a);
  1588. T const a01=mat_traits<A>::template read_element<0,1>(a);
  1589. T const a02=mat_traits<A>::template read_element<0,2>(a);
  1590. T const a03=mat_traits<A>::template read_element<0,3>(a);
  1591. T const a10=mat_traits<A>::template read_element<1,0>(a);
  1592. T const a11=mat_traits<A>::template read_element<1,1>(a);
  1593. T const a12=mat_traits<A>::template read_element<1,2>(a);
  1594. T const a13=mat_traits<A>::template read_element<1,3>(a);
  1595. T const a20=mat_traits<A>::template read_element<2,0>(a);
  1596. T const a21=mat_traits<A>::template read_element<2,1>(a);
  1597. T const a22=mat_traits<A>::template read_element<2,2>(a);
  1598. T const a23=mat_traits<A>::template read_element<2,3>(a);
  1599. T const a30=mat_traits<A>::template read_element<3,0>(a);
  1600. T const a31=mat_traits<A>::template read_element<3,1>(a);
  1601. T const a32=mat_traits<A>::template read_element<3,2>(a);
  1602. T const a33=mat_traits<A>::template read_element<3,3>(a);
  1603. T const f=scalar_traits<T>::value(1)/det;
  1604. typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
  1605. R r;
  1606. mat_traits<R>::template write_element<0,0>(r)= f*(a11*(a22*a33-a23*a32)-a12*(a21*a33-a23*a31)+a13*(a21*a32-a22*a31));
  1607. mat_traits<R>::template write_element<0,1>(r)=-f*(a01*(a22*a33-a23*a32)-a02*(a21*a33-a23*a31)+a03*(a21*a32-a22*a31));
  1608. mat_traits<R>::template write_element<0,2>(r)= f*(a01*(a12*a33-a13*a32)-a02*(a11*a33-a13*a31)+a03*(a11*a32-a12*a31));
  1609. mat_traits<R>::template write_element<0,3>(r)=-f*(a01*(a12*a23-a13*a22)-a02*(a11*a23-a13*a21)+a03*(a11*a22-a12*a21));
  1610. mat_traits<R>::template write_element<1,0>(r)=-f*(a10*(a22*a33-a23*a32)-a12*(a20*a33-a23*a30)+a13*(a20*a32-a22*a30));
  1611. mat_traits<R>::template write_element<1,1>(r)= f*(a00*(a22*a33-a23*a32)-a02*(a20*a33-a23*a30)+a03*(a20*a32-a22*a30));
  1612. mat_traits<R>::template write_element<1,2>(r)=-f*(a00*(a12*a33-a13*a32)-a02*(a10*a33-a13*a30)+a03*(a10*a32-a12*a30));
  1613. mat_traits<R>::template write_element<1,3>(r)= f*(a00*(a12*a23-a13*a22)-a02*(a10*a23-a13*a20)+a03*(a10*a22-a12*a20));
  1614. mat_traits<R>::template write_element<2,0>(r)= f*(a10*(a21*a33-a23*a31)-a11*(a20*a33-a23*a30)+a13*(a20*a31-a21*a30));
  1615. mat_traits<R>::template write_element<2,1>(r)=-f*(a00*(a21*a33-a23*a31)-a01*(a20*a33-a23*a30)+a03*(a20*a31-a21*a30));
  1616. mat_traits<R>::template write_element<2,2>(r)= f*(a00*(a11*a33-a13*a31)-a01*(a10*a33-a13*a30)+a03*(a10*a31-a11*a30));
  1617. mat_traits<R>::template write_element<2,3>(r)=-f*(a00*(a11*a23-a13*a21)-a01*(a10*a23-a13*a20)+a03*(a10*a21-a11*a20));
  1618. mat_traits<R>::template write_element<3,0>(r)=-f*(a10*(a21*a32-a22*a31)-a11*(a20*a32-a22*a30)+a12*(a20*a31-a21*a30));
  1619. mat_traits<R>::template write_element<3,1>(r)= f*(a00*(a21*a32-a22*a31)-a01*(a20*a32-a22*a30)+a02*(a20*a31-a21*a30));
  1620. mat_traits<R>::template write_element<3,2>(r)=-f*(a00*(a11*a32-a12*a31)-a01*(a10*a32-a12*a30)+a02*(a10*a31-a11*a30));
  1621. mat_traits<R>::template write_element<3,3>(r)= f*(a00*(a11*a22-a12*a21)-a01*(a10*a22-a12*a20)+a02*(a10*a21-a11*a20));
  1622. return r;
  1623. }
  1624. template <class A>
  1625. BOOST_QVM_INLINE_OPERATIONS
  1626. typename lazy_enable_if_c<
  1627. mat_traits<A>::rows==4 && mat_traits<A>::cols==4,
  1628. deduce_mat<A> >::type
  1629. inverse( A const & a )
  1630. {
  1631. typedef typename mat_traits<A>::scalar_type T;
  1632. T det=determinant(a);
  1633. if( det==scalar_traits<T>::value(0) )
  1634. BOOST_QVM_THROW_EXCEPTION(zero_determinant_error());
  1635. return inverse(a,det);
  1636. }
  1637. namespace
  1638. sfinae
  1639. {
  1640. using ::boost::qvm::inverse;
  1641. }
  1642. namespace
  1643. qvm_detail
  1644. {
  1645. template <int D>
  1646. struct inverse_m_defined;
  1647. template <>
  1648. struct
  1649. inverse_m_defined<4>
  1650. {
  1651. static bool const value=true;
  1652. };
  1653. }
  1654. template <class A,class B>
  1655. BOOST_QVM_INLINE_OPERATIONS
  1656. typename lazy_enable_if_c<
  1657. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  1658. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  1659. deduce_mat2<A,B,4,4> >::type
  1660. operator*( A const & a, B const & b )
  1661. {
  1662. typedef typename mat_traits<A>::scalar_type Ta;
  1663. typedef typename mat_traits<B>::scalar_type Tb;
  1664. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  1665. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  1666. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  1667. Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
  1668. Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
  1669. Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
  1670. Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
  1671. Ta const a13 = mat_traits<A>::template read_element<1,3>(a);
  1672. Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
  1673. Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
  1674. Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
  1675. Ta const a23 = mat_traits<A>::template read_element<2,3>(a);
  1676. Ta const a30 = mat_traits<A>::template read_element<3,0>(a);
  1677. Ta const a31 = mat_traits<A>::template read_element<3,1>(a);
  1678. Ta const a32 = mat_traits<A>::template read_element<3,2>(a);
  1679. Ta const a33 = mat_traits<A>::template read_element<3,3>(a);
  1680. Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
  1681. Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
  1682. Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
  1683. Tb const b03 = mat_traits<B>::template read_element<0,3>(b);
  1684. Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
  1685. Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
  1686. Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
  1687. Tb const b13 = mat_traits<B>::template read_element<1,3>(b);
  1688. Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
  1689. Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
  1690. Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
  1691. Tb const b23 = mat_traits<B>::template read_element<2,3>(b);
  1692. Tb const b30 = mat_traits<B>::template read_element<3,0>(b);
  1693. Tb const b31 = mat_traits<B>::template read_element<3,1>(b);
  1694. Tb const b32 = mat_traits<B>::template read_element<3,2>(b);
  1695. Tb const b33 = mat_traits<B>::template read_element<3,3>(b);
  1696. typedef typename deduce_mat2<A,B,4,4>::type R;
  1697. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
  1698. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
  1699. R r;
  1700. mat_traits<R>::template write_element<0,0>(r)=a00*b00+a01*b10+a02*b20+a03*b30;
  1701. mat_traits<R>::template write_element<0,1>(r)=a00*b01+a01*b11+a02*b21+a03*b31;
  1702. mat_traits<R>::template write_element<0,2>(r)=a00*b02+a01*b12+a02*b22+a03*b32;
  1703. mat_traits<R>::template write_element<0,3>(r)=a00*b03+a01*b13+a02*b23+a03*b33;
  1704. mat_traits<R>::template write_element<1,0>(r)=a10*b00+a11*b10+a12*b20+a13*b30;
  1705. mat_traits<R>::template write_element<1,1>(r)=a10*b01+a11*b11+a12*b21+a13*b31;
  1706. mat_traits<R>::template write_element<1,2>(r)=a10*b02+a11*b12+a12*b22+a13*b32;
  1707. mat_traits<R>::template write_element<1,3>(r)=a10*b03+a11*b13+a12*b23+a13*b33;
  1708. mat_traits<R>::template write_element<2,0>(r)=a20*b00+a21*b10+a22*b20+a23*b30;
  1709. mat_traits<R>::template write_element<2,1>(r)=a20*b01+a21*b11+a22*b21+a23*b31;
  1710. mat_traits<R>::template write_element<2,2>(r)=a20*b02+a21*b12+a22*b22+a23*b32;
  1711. mat_traits<R>::template write_element<2,3>(r)=a20*b03+a21*b13+a22*b23+a23*b33;
  1712. mat_traits<R>::template write_element<3,0>(r)=a30*b00+a31*b10+a32*b20+a33*b30;
  1713. mat_traits<R>::template write_element<3,1>(r)=a30*b01+a31*b11+a32*b21+a33*b31;
  1714. mat_traits<R>::template write_element<3,2>(r)=a30*b02+a31*b12+a32*b22+a33*b32;
  1715. mat_traits<R>::template write_element<3,3>(r)=a30*b03+a31*b13+a32*b23+a33*b33;
  1716. return r;
  1717. }
  1718. namespace
  1719. sfinae
  1720. {
  1721. using ::boost::qvm::operator*;
  1722. }
  1723. namespace
  1724. qvm_detail
  1725. {
  1726. template <int R,int /*CR*/,int C>
  1727. struct mul_mm_defined;
  1728. template <>
  1729. struct
  1730. mul_mm_defined<4,4,4>
  1731. {
  1732. static bool const value=true;
  1733. };
  1734. }
  1735. template <class A,class B>
  1736. BOOST_QVM_INLINE_OPERATIONS
  1737. typename enable_if_c<
  1738. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  1739. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  1740. A &>::type
  1741. operator*=( A & a, B const & b )
  1742. {
  1743. typedef typename mat_traits<A>::scalar_type Ta;
  1744. typedef typename mat_traits<B>::scalar_type Tb;
  1745. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  1746. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  1747. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  1748. Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
  1749. Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
  1750. Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
  1751. Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
  1752. Ta const a13 = mat_traits<A>::template read_element<1,3>(a);
  1753. Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
  1754. Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
  1755. Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
  1756. Ta const a23 = mat_traits<A>::template read_element<2,3>(a);
  1757. Ta const a30 = mat_traits<A>::template read_element<3,0>(a);
  1758. Ta const a31 = mat_traits<A>::template read_element<3,1>(a);
  1759. Ta const a32 = mat_traits<A>::template read_element<3,2>(a);
  1760. Ta const a33 = mat_traits<A>::template read_element<3,3>(a);
  1761. Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
  1762. Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
  1763. Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
  1764. Tb const b03 = mat_traits<B>::template read_element<0,3>(b);
  1765. Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
  1766. Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
  1767. Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
  1768. Tb const b13 = mat_traits<B>::template read_element<1,3>(b);
  1769. Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
  1770. Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
  1771. Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
  1772. Tb const b23 = mat_traits<B>::template read_element<2,3>(b);
  1773. Tb const b30 = mat_traits<B>::template read_element<3,0>(b);
  1774. Tb const b31 = mat_traits<B>::template read_element<3,1>(b);
  1775. Tb const b32 = mat_traits<B>::template read_element<3,2>(b);
  1776. Tb const b33 = mat_traits<B>::template read_element<3,3>(b);
  1777. mat_traits<A>::template write_element<0,0>(a)=a00*b00+a01*b10+a02*b20+a03*b30;
  1778. mat_traits<A>::template write_element<0,1>(a)=a00*b01+a01*b11+a02*b21+a03*b31;
  1779. mat_traits<A>::template write_element<0,2>(a)=a00*b02+a01*b12+a02*b22+a03*b32;
  1780. mat_traits<A>::template write_element<0,3>(a)=a00*b03+a01*b13+a02*b23+a03*b33;
  1781. mat_traits<A>::template write_element<1,0>(a)=a10*b00+a11*b10+a12*b20+a13*b30;
  1782. mat_traits<A>::template write_element<1,1>(a)=a10*b01+a11*b11+a12*b21+a13*b31;
  1783. mat_traits<A>::template write_element<1,2>(a)=a10*b02+a11*b12+a12*b22+a13*b32;
  1784. mat_traits<A>::template write_element<1,3>(a)=a10*b03+a11*b13+a12*b23+a13*b33;
  1785. mat_traits<A>::template write_element<2,0>(a)=a20*b00+a21*b10+a22*b20+a23*b30;
  1786. mat_traits<A>::template write_element<2,1>(a)=a20*b01+a21*b11+a22*b21+a23*b31;
  1787. mat_traits<A>::template write_element<2,2>(a)=a20*b02+a21*b12+a22*b22+a23*b32;
  1788. mat_traits<A>::template write_element<2,3>(a)=a20*b03+a21*b13+a22*b23+a23*b33;
  1789. mat_traits<A>::template write_element<3,0>(a)=a30*b00+a31*b10+a32*b20+a33*b30;
  1790. mat_traits<A>::template write_element<3,1>(a)=a30*b01+a31*b11+a32*b21+a33*b31;
  1791. mat_traits<A>::template write_element<3,2>(a)=a30*b02+a31*b12+a32*b22+a33*b32;
  1792. mat_traits<A>::template write_element<3,3>(a)=a30*b03+a31*b13+a32*b23+a33*b33;
  1793. return a;
  1794. }
  1795. namespace
  1796. sfinae
  1797. {
  1798. using ::boost::qvm::operator*=;
  1799. }
  1800. namespace
  1801. qvm_detail
  1802. {
  1803. template <int D>
  1804. struct mul_eq_mm_defined;
  1805. template <>
  1806. struct
  1807. mul_eq_mm_defined<4>
  1808. {
  1809. static bool const value=true;
  1810. };
  1811. }
  1812. template <class A,class B>
  1813. BOOST_QVM_INLINE_OPERATIONS
  1814. typename lazy_enable_if_c<
  1815. mat_traits<A>::rows==4 && mat_traits<B>::rows==4 &&
  1816. mat_traits<A>::cols==4 && mat_traits<B>::cols==1,
  1817. deduce_mat2<A,B,4,1> >::type
  1818. operator*( A const & a, B const & b )
  1819. {
  1820. typedef typename mat_traits<A>::scalar_type Ta;
  1821. typedef typename mat_traits<B>::scalar_type Tb;
  1822. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  1823. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  1824. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  1825. Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
  1826. Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
  1827. Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
  1828. Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
  1829. Ta const a13 = mat_traits<A>::template read_element<1,3>(a);
  1830. Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
  1831. Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
  1832. Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
  1833. Ta const a23 = mat_traits<A>::template read_element<2,3>(a);
  1834. Ta const a30 = mat_traits<A>::template read_element<3,0>(a);
  1835. Ta const a31 = mat_traits<A>::template read_element<3,1>(a);
  1836. Ta const a32 = mat_traits<A>::template read_element<3,2>(a);
  1837. Ta const a33 = mat_traits<A>::template read_element<3,3>(a);
  1838. Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
  1839. Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
  1840. Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
  1841. Tb const b30 = mat_traits<B>::template read_element<3,0>(b);
  1842. typedef typename deduce_mat2<A,B,4,1>::type R;
  1843. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==4);
  1844. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
  1845. R r;
  1846. mat_traits<R>::template write_element<0,0>(r)=a00*b00+a01*b10+a02*b20+a03*b30;
  1847. mat_traits<R>::template write_element<1,0>(r)=a10*b00+a11*b10+a12*b20+a13*b30;
  1848. mat_traits<R>::template write_element<2,0>(r)=a20*b00+a21*b10+a22*b20+a23*b30;
  1849. mat_traits<R>::template write_element<3,0>(r)=a30*b00+a31*b10+a32*b20+a33*b30;
  1850. return r;
  1851. }
  1852. namespace
  1853. sfinae
  1854. {
  1855. using ::boost::qvm::operator*;
  1856. }
  1857. namespace
  1858. qvm_detail
  1859. {
  1860. template <int R,int /*CR*/,int C>
  1861. struct mul_mm_defined;
  1862. template <>
  1863. struct
  1864. mul_mm_defined<4,4,1>
  1865. {
  1866. static bool const value=true;
  1867. };
  1868. }
  1869. template <class A,class B>
  1870. BOOST_QVM_INLINE_OPERATIONS
  1871. typename lazy_enable_if_c<
  1872. mat_traits<A>::rows==1 && mat_traits<B>::rows==4 &&
  1873. mat_traits<A>::cols==4 && mat_traits<B>::cols==4,
  1874. deduce_mat2<A,B,1,4> >::type
  1875. operator*( A const & a, B const & b )
  1876. {
  1877. typedef typename mat_traits<A>::scalar_type Ta;
  1878. typedef typename mat_traits<B>::scalar_type Tb;
  1879. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  1880. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  1881. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  1882. Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
  1883. Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
  1884. Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
  1885. Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
  1886. Tb const b03 = mat_traits<B>::template read_element<0,3>(b);
  1887. Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
  1888. Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
  1889. Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
  1890. Tb const b13 = mat_traits<B>::template read_element<1,3>(b);
  1891. Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
  1892. Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
  1893. Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
  1894. Tb const b23 = mat_traits<B>::template read_element<2,3>(b);
  1895. Tb const b30 = mat_traits<B>::template read_element<3,0>(b);
  1896. Tb const b31 = mat_traits<B>::template read_element<3,1>(b);
  1897. Tb const b32 = mat_traits<B>::template read_element<3,2>(b);
  1898. Tb const b33 = mat_traits<B>::template read_element<3,3>(b);
  1899. typedef typename deduce_mat2<A,B,1,4>::type R;
  1900. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
  1901. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==4);
  1902. R r;
  1903. mat_traits<R>::template write_element<0,0>(r)=a00*b00+a01*b10+a02*b20+a03*b30;
  1904. mat_traits<R>::template write_element<0,1>(r)=a00*b01+a01*b11+a02*b21+a03*b31;
  1905. mat_traits<R>::template write_element<0,2>(r)=a00*b02+a01*b12+a02*b22+a03*b32;
  1906. mat_traits<R>::template write_element<0,3>(r)=a00*b03+a01*b13+a02*b23+a03*b33;
  1907. return r;
  1908. }
  1909. namespace
  1910. sfinae
  1911. {
  1912. using ::boost::qvm::operator*;
  1913. }
  1914. namespace
  1915. qvm_detail
  1916. {
  1917. template <int R,int /*CR*/,int C>
  1918. struct mul_mm_defined;
  1919. template <>
  1920. struct
  1921. mul_mm_defined<1,4,4>
  1922. {
  1923. static bool const value=true;
  1924. };
  1925. }
  1926. } }
  1927. #endif