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