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

source code of boost/libs/qvm/include/boost/qvm/gen/mat_operations3.hpp