mat_operations4.hpp 91 KB

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