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