gen.cpp 65 KB

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