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