Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:44

0001 #ifndef BOOST_QVM_GEN_MAT_OPERATIONS3_HPP_INCLUDED
0002 #define BOOST_QVM_GEN_MAT_OPERATIONS3_HPP_INCLUDED
0003 
0004 // Copyright 2008-2022 Emil Dotchevski and Reverge Studios, Inc.
0005 
0006 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0007 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 // This file was generated by a program. Do not edit manually.
0010 
0011 #include <boost/qvm/assert.hpp>
0012 #include <boost/qvm/deduce_mat.hpp>
0013 #include <boost/qvm/deduce_vec.hpp>
0014 #include <boost/qvm/error.hpp>
0015 #include <boost/qvm/gen/mat_assign3.hpp>
0016 #include <boost/qvm/quat_traits.hpp>
0017 #include <boost/qvm/scalar_traits.hpp>
0018 #include <boost/qvm/throw_exception.hpp>
0019 
0020 namespace boost { namespace qvm {
0021 
0022 template <class A,class B>
0023 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0024 typename lazy_enable_if_c<
0025     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0026     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0027     deduce_mat2<A,B,3,3> >::type
0028 operator+( A const & a, B const & b )
0029     {
0030     typedef typename deduce_mat2<A,B,3,3>::type R;
0031     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
0032     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
0033     R r;
0034     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0035     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0036     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0037     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0038     write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)+mat_traits<B>::template read_element<1,1>(b));
0039     write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)+mat_traits<B>::template read_element<1,2>(b));
0040     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0041     write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)+mat_traits<B>::template read_element<2,1>(b));
0042     write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)+mat_traits<B>::template read_element<2,2>(b));
0043     return r;
0044     }
0045 
0046 namespace
0047 sfinae
0048     {
0049     using ::boost::qvm::operator+;
0050     }
0051 
0052 namespace
0053 qvm_detail
0054     {
0055     template <int R,int C>
0056     struct plus_mm_defined;
0057 
0058     template <>
0059     struct
0060     plus_mm_defined<3,3>
0061         {
0062         static bool const value=true;
0063         };
0064     }
0065 
0066 template <class A,class B>
0067 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0068 typename lazy_enable_if_c<
0069     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0070     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0071     deduce_mat2<A,B,3,1> >::type
0072 operator+( A const & a, B const & b )
0073     {
0074     typedef typename deduce_mat2<A,B,3,1>::type R;
0075     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
0076     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
0077     R r;
0078     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0079     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0080     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0081     return r;
0082     }
0083 
0084 namespace
0085 sfinae
0086     {
0087     using ::boost::qvm::operator+;
0088     }
0089 
0090 namespace
0091 qvm_detail
0092     {
0093     template <int R,int C>
0094     struct plus_mm_defined;
0095 
0096     template <>
0097     struct
0098     plus_mm_defined<3,1>
0099         {
0100         static bool const value=true;
0101         };
0102     }
0103 
0104 template <class A,class B>
0105 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0106 typename lazy_enable_if_c<
0107     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0108     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0109     deduce_mat2<A,B,1,3> >::type
0110 operator+( A const & a, B const & b )
0111     {
0112     typedef typename deduce_mat2<A,B,1,3>::type R;
0113     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
0114     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
0115     R r;
0116     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0117     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0118     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0119     return r;
0120     }
0121 
0122 namespace
0123 sfinae
0124     {
0125     using ::boost::qvm::operator+;
0126     }
0127 
0128 namespace
0129 qvm_detail
0130     {
0131     template <int R,int C>
0132     struct plus_mm_defined;
0133 
0134     template <>
0135     struct
0136     plus_mm_defined<1,3>
0137         {
0138         static bool const value=true;
0139         };
0140     }
0141 
0142 template <class A,class B>
0143 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0144 typename lazy_enable_if_c<
0145     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0146     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0147     deduce_mat2<A,B,3,3> >::type
0148 operator-( A const & a, B const & b )
0149     {
0150     typedef typename deduce_mat2<A,B,3,3>::type R;
0151     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
0152     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
0153     R r;
0154     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0155     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0156     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0157     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0158     write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)-mat_traits<B>::template read_element<1,1>(b));
0159     write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)-mat_traits<B>::template read_element<1,2>(b));
0160     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0161     write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)-mat_traits<B>::template read_element<2,1>(b));
0162     write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)-mat_traits<B>::template read_element<2,2>(b));
0163     return r;
0164     }
0165 
0166 namespace
0167 sfinae
0168     {
0169     using ::boost::qvm::operator-;
0170     }
0171 
0172 namespace
0173 qvm_detail
0174     {
0175     template <int R,int C>
0176     struct minus_mm_defined;
0177 
0178     template <>
0179     struct
0180     minus_mm_defined<3,3>
0181         {
0182         static bool const value=true;
0183         };
0184     }
0185 
0186 template <class A,class B>
0187 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0188 typename lazy_enable_if_c<
0189     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0190     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0191     deduce_mat2<A,B,3,1> >::type
0192 operator-( A const & a, B const & b )
0193     {
0194     typedef typename deduce_mat2<A,B,3,1>::type R;
0195     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
0196     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
0197     R r;
0198     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0199     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0200     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0201     return r;
0202     }
0203 
0204 namespace
0205 sfinae
0206     {
0207     using ::boost::qvm::operator-;
0208     }
0209 
0210 namespace
0211 qvm_detail
0212     {
0213     template <int R,int C>
0214     struct minus_mm_defined;
0215 
0216     template <>
0217     struct
0218     minus_mm_defined<3,1>
0219         {
0220         static bool const value=true;
0221         };
0222     }
0223 
0224 template <class A,class B>
0225 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0226 typename lazy_enable_if_c<
0227     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0228     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0229     deduce_mat2<A,B,1,3> >::type
0230 operator-( A const & a, B const & b )
0231     {
0232     typedef typename deduce_mat2<A,B,1,3>::type R;
0233     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
0234     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
0235     R r;
0236     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0237     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0238     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0239     return r;
0240     }
0241 
0242 namespace
0243 sfinae
0244     {
0245     using ::boost::qvm::operator-;
0246     }
0247 
0248 namespace
0249 qvm_detail
0250     {
0251     template <int R,int C>
0252     struct minus_mm_defined;
0253 
0254     template <>
0255     struct
0256     minus_mm_defined<1,3>
0257         {
0258         static bool const value=true;
0259         };
0260     }
0261 
0262 template <class A,class B>
0263 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0264 typename enable_if_c<
0265     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0266     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0267     A &>::type
0268 operator+=( A & a, B const & b )
0269     {
0270     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0271     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0272     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0273     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0274     write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)+mat_traits<B>::template read_element<1,1>(b));
0275     write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)+mat_traits<B>::template read_element<1,2>(b));
0276     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0277     write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)+mat_traits<B>::template read_element<2,1>(b));
0278     write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)+mat_traits<B>::template read_element<2,2>(b));
0279     return a;
0280     }
0281 
0282 namespace
0283 sfinae
0284     {
0285     using ::boost::qvm::operator+=;
0286     }
0287 
0288 namespace
0289 qvm_detail
0290     {
0291     template <int R,int C>
0292     struct plus_eq_mm_defined;
0293 
0294     template <>
0295     struct
0296     plus_eq_mm_defined<3,3>
0297         {
0298         static bool const value=true;
0299         };
0300     }
0301 
0302 template <class A,class B>
0303 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0304 typename enable_if_c<
0305     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0306     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0307     A &>::type
0308 operator+=( A & a, B const & b )
0309     {
0310     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0311     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0312     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0313     return a;
0314     }
0315 
0316 namespace
0317 sfinae
0318     {
0319     using ::boost::qvm::operator+=;
0320     }
0321 
0322 namespace
0323 qvm_detail
0324     {
0325     template <int R,int C>
0326     struct plus_eq_mm_defined;
0327 
0328     template <>
0329     struct
0330     plus_eq_mm_defined<3,1>
0331         {
0332         static bool const value=true;
0333         };
0334     }
0335 
0336 template <class A,class B>
0337 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0338 typename enable_if_c<
0339     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0340     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0341     A &>::type
0342 operator+=( A & a, B const & b )
0343     {
0344     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0345     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0346     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0347     return a;
0348     }
0349 
0350 namespace
0351 sfinae
0352     {
0353     using ::boost::qvm::operator+=;
0354     }
0355 
0356 namespace
0357 qvm_detail
0358     {
0359     template <int R,int C>
0360     struct plus_eq_mm_defined;
0361 
0362     template <>
0363     struct
0364     plus_eq_mm_defined<1,3>
0365         {
0366         static bool const value=true;
0367         };
0368     }
0369 
0370 template <class A,class B>
0371 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0372 typename enable_if_c<
0373     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0374     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0375     A &>::type
0376 operator-=( A & a, B const & b )
0377     {
0378     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0379     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0380     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0381     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0382     write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)-mat_traits<B>::template read_element<1,1>(b));
0383     write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)-mat_traits<B>::template read_element<1,2>(b));
0384     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0385     write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)-mat_traits<B>::template read_element<2,1>(b));
0386     write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)-mat_traits<B>::template read_element<2,2>(b));
0387     return a;
0388     }
0389 
0390 namespace
0391 sfinae
0392     {
0393     using ::boost::qvm::operator-=;
0394     }
0395 
0396 namespace
0397 qvm_detail
0398     {
0399     template <int R,int C>
0400     struct minus_eq_mm_defined;
0401 
0402     template <>
0403     struct
0404     minus_eq_mm_defined<3,3>
0405         {
0406         static bool const value=true;
0407         };
0408     }
0409 
0410 template <class A,class B>
0411 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0412 typename enable_if_c<
0413     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0414     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0415     A &>::type
0416 operator-=( A & a, B const & b )
0417     {
0418     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0419     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0420     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0421     return a;
0422     }
0423 
0424 namespace
0425 sfinae
0426     {
0427     using ::boost::qvm::operator-=;
0428     }
0429 
0430 namespace
0431 qvm_detail
0432     {
0433     template <int R,int C>
0434     struct minus_eq_mm_defined;
0435 
0436     template <>
0437     struct
0438     minus_eq_mm_defined<3,1>
0439         {
0440         static bool const value=true;
0441         };
0442     }
0443 
0444 template <class A,class B>
0445 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0446 typename enable_if_c<
0447     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0448     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0449     A &>::type
0450 operator-=( A & a, B const & b )
0451     {
0452     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0453     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0454     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0455     return a;
0456     }
0457 
0458 namespace
0459 sfinae
0460     {
0461     using ::boost::qvm::operator-=;
0462     }
0463 
0464 namespace
0465 qvm_detail
0466     {
0467     template <int R,int C>
0468     struct minus_eq_mm_defined;
0469 
0470     template <>
0471     struct
0472     minus_eq_mm_defined<1,3>
0473         {
0474         static bool const value=true;
0475         };
0476     }
0477 
0478 template <class A,class B>
0479 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0480 typename lazy_enable_if_c<
0481     mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0482     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0483 operator*( A const & a, B b )
0484     {
0485     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0486     R r;
0487     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)*b);
0488     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)*b);
0489     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)*b);
0490     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)*b);
0491     write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)*b);
0492     write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)*b);
0493     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)*b);
0494     write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)*b);
0495     write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)*b);
0496     return r;
0497     }
0498 
0499 namespace
0500 sfinae
0501     {
0502     using ::boost::qvm::operator*;
0503     }
0504 
0505 namespace
0506 qvm_detail
0507     {
0508     template <int R,int C>
0509     struct mul_ms_defined;
0510 
0511     template <>
0512     struct
0513     mul_ms_defined<3,3>
0514         {
0515         static bool const value=true;
0516         };
0517     }
0518 
0519 template <class A,class B>
0520 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0521 typename lazy_enable_if_c<
0522     is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==3,
0523     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0524 operator*( A a, B const & b )
0525     {
0526     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0527     R r;
0528     write_mat_element<0,0>(r,a*mat_traits<B>::template read_element<0,0>(b));
0529     write_mat_element<0,1>(r,a*mat_traits<B>::template read_element<0,1>(b));
0530     write_mat_element<0,2>(r,a*mat_traits<B>::template read_element<0,2>(b));
0531     write_mat_element<1,0>(r,a*mat_traits<B>::template read_element<1,0>(b));
0532     write_mat_element<1,1>(r,a*mat_traits<B>::template read_element<1,1>(b));
0533     write_mat_element<1,2>(r,a*mat_traits<B>::template read_element<1,2>(b));
0534     write_mat_element<2,0>(r,a*mat_traits<B>::template read_element<2,0>(b));
0535     write_mat_element<2,1>(r,a*mat_traits<B>::template read_element<2,1>(b));
0536     write_mat_element<2,2>(r,a*mat_traits<B>::template read_element<2,2>(b));
0537     return r;
0538     }
0539 
0540 namespace
0541 sfinae
0542     {
0543     using ::boost::qvm::operator*;
0544     }
0545 
0546 namespace
0547 qvm_detail
0548     {
0549     template <int R,int C>
0550     struct mul_sm_defined;
0551 
0552     template <>
0553     struct
0554     mul_sm_defined<3,3>
0555         {
0556         static bool const value=true;
0557         };
0558     }
0559 
0560 template <class A,class B>
0561 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0562 typename lazy_enable_if_c<
0563     mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
0564     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0565 operator*( A const & a, B b )
0566     {
0567     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0568     R r;
0569     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)*b);
0570     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)*b);
0571     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)*b);
0572     return r;
0573     }
0574 
0575 namespace
0576 sfinae
0577     {
0578     using ::boost::qvm::operator*;
0579     }
0580 
0581 namespace
0582 qvm_detail
0583     {
0584     template <int R,int C>
0585     struct mul_ms_defined;
0586 
0587     template <>
0588     struct
0589     mul_ms_defined<3,1>
0590         {
0591         static bool const value=true;
0592         };
0593     }
0594 
0595 template <class A,class B>
0596 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0597 typename lazy_enable_if_c<
0598     is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==1,
0599     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0600 operator*( A a, B const & b )
0601     {
0602     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0603     R r;
0604     write_mat_element<0,0>(r,a*mat_traits<B>::template read_element<0,0>(b));
0605     write_mat_element<1,0>(r,a*mat_traits<B>::template read_element<1,0>(b));
0606     write_mat_element<2,0>(r,a*mat_traits<B>::template read_element<2,0>(b));
0607     return r;
0608     }
0609 
0610 namespace
0611 sfinae
0612     {
0613     using ::boost::qvm::operator*;
0614     }
0615 
0616 namespace
0617 qvm_detail
0618     {
0619     template <int R,int C>
0620     struct mul_sm_defined;
0621 
0622     template <>
0623     struct
0624     mul_sm_defined<3,1>
0625         {
0626         static bool const value=true;
0627         };
0628     }
0629 
0630 template <class A,class B>
0631 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0632 typename lazy_enable_if_c<
0633     mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0634     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0635 operator*( A const & a, B b )
0636     {
0637     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0638     R r;
0639     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)*b);
0640     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)*b);
0641     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)*b);
0642     return r;
0643     }
0644 
0645 namespace
0646 sfinae
0647     {
0648     using ::boost::qvm::operator*;
0649     }
0650 
0651 namespace
0652 qvm_detail
0653     {
0654     template <int R,int C>
0655     struct mul_ms_defined;
0656 
0657     template <>
0658     struct
0659     mul_ms_defined<1,3>
0660         {
0661         static bool const value=true;
0662         };
0663     }
0664 
0665 template <class A,class B>
0666 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0667 typename lazy_enable_if_c<
0668     is_scalar<A>::value && mat_traits<B>::rows==1 && mat_traits<B>::cols==3,
0669     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0670 operator*( A a, B const & b )
0671     {
0672     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0673     R r;
0674     write_mat_element<0,0>(r,a*mat_traits<B>::template read_element<0,0>(b));
0675     write_mat_element<0,1>(r,a*mat_traits<B>::template read_element<0,1>(b));
0676     write_mat_element<0,2>(r,a*mat_traits<B>::template read_element<0,2>(b));
0677     return r;
0678     }
0679 
0680 namespace
0681 sfinae
0682     {
0683     using ::boost::qvm::operator*;
0684     }
0685 
0686 namespace
0687 qvm_detail
0688     {
0689     template <int R,int C>
0690     struct mul_sm_defined;
0691 
0692     template <>
0693     struct
0694     mul_sm_defined<1,3>
0695         {
0696         static bool const value=true;
0697         };
0698     }
0699 
0700 template <class A,class B>
0701 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0702 typename enable_if_c<
0703     mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0704     A &>::type
0705 operator*=( A & a, B b )
0706     {
0707     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)*b);
0708     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)*b);
0709     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)*b);
0710     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)*b);
0711     write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)*b);
0712     write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)*b);
0713     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)*b);
0714     write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)*b);
0715     write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)*b);
0716     return a;
0717     }
0718 
0719 namespace
0720 sfinae
0721     {
0722     using ::boost::qvm::operator*=;
0723     }
0724 
0725 namespace
0726 qvm_detail
0727     {
0728     template <int R,int C>
0729     struct mul_eq_ms_defined;
0730 
0731     template <>
0732     struct
0733     mul_eq_ms_defined<3,3>
0734         {
0735         static bool const value=true;
0736         };
0737     }
0738 
0739 template <class A,class B>
0740 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0741 typename enable_if_c<
0742     mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
0743     A &>::type
0744 operator*=( A & a, B b )
0745     {
0746     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)*b);
0747     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)*b);
0748     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)*b);
0749     return a;
0750     }
0751 
0752 namespace
0753 sfinae
0754     {
0755     using ::boost::qvm::operator*=;
0756     }
0757 
0758 namespace
0759 qvm_detail
0760     {
0761     template <int R,int C>
0762     struct mul_eq_ms_defined;
0763 
0764     template <>
0765     struct
0766     mul_eq_ms_defined<3,1>
0767         {
0768         static bool const value=true;
0769         };
0770     }
0771 
0772 template <class A,class B>
0773 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0774 typename enable_if_c<
0775     mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0776     A &>::type
0777 operator*=( A & a, B b )
0778     {
0779     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)*b);
0780     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)*b);
0781     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)*b);
0782     return a;
0783     }
0784 
0785 namespace
0786 sfinae
0787     {
0788     using ::boost::qvm::operator*=;
0789     }
0790 
0791 namespace
0792 qvm_detail
0793     {
0794     template <int R,int C>
0795     struct mul_eq_ms_defined;
0796 
0797     template <>
0798     struct
0799     mul_eq_ms_defined<1,3>
0800         {
0801         static bool const value=true;
0802         };
0803     }
0804 
0805 template <class A,class B>
0806 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0807 typename lazy_enable_if_c<
0808     mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0809     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0810 operator/( A const & a, B b )
0811     {
0812     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0813     R r;
0814     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)/b);
0815     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)/b);
0816     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)/b);
0817     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)/b);
0818     write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)/b);
0819     write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)/b);
0820     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)/b);
0821     write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)/b);
0822     write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)/b);
0823     return r;
0824     }
0825 
0826 namespace
0827 sfinae
0828     {
0829     using ::boost::qvm::operator/;
0830     }
0831 
0832 namespace
0833 qvm_detail
0834     {
0835     template <int R,int C>
0836     struct div_ms_defined;
0837 
0838     template <>
0839     struct
0840     div_ms_defined<3,3>
0841         {
0842         static bool const value=true;
0843         };
0844     }
0845 
0846 template <class A,class B>
0847 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0848 typename lazy_enable_if_c<
0849     is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==3,
0850     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0851 operator/( A a, B const & b )
0852     {
0853     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0854     R r;
0855     write_mat_element<0,0>(r,a/mat_traits<B>::template read_element<0,0>(b));
0856     write_mat_element<0,1>(r,a/mat_traits<B>::template read_element<0,1>(b));
0857     write_mat_element<0,2>(r,a/mat_traits<B>::template read_element<0,2>(b));
0858     write_mat_element<1,0>(r,a/mat_traits<B>::template read_element<1,0>(b));
0859     write_mat_element<1,1>(r,a/mat_traits<B>::template read_element<1,1>(b));
0860     write_mat_element<1,2>(r,a/mat_traits<B>::template read_element<1,2>(b));
0861     write_mat_element<2,0>(r,a/mat_traits<B>::template read_element<2,0>(b));
0862     write_mat_element<2,1>(r,a/mat_traits<B>::template read_element<2,1>(b));
0863     write_mat_element<2,2>(r,a/mat_traits<B>::template read_element<2,2>(b));
0864     return r;
0865     }
0866 
0867 namespace
0868 sfinae
0869     {
0870     using ::boost::qvm::operator/;
0871     }
0872 
0873 namespace
0874 qvm_detail
0875     {
0876     template <int R,int C>
0877     struct div_sm_defined;
0878 
0879     template <>
0880     struct
0881     div_sm_defined<3,3>
0882         {
0883         static bool const value=true;
0884         };
0885     }
0886 
0887 template <class A,class B>
0888 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0889 typename lazy_enable_if_c<
0890     mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
0891     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0892 operator/( A const & a, B b )
0893     {
0894     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0895     R r;
0896     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)/b);
0897     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)/b);
0898     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)/b);
0899     return r;
0900     }
0901 
0902 namespace
0903 sfinae
0904     {
0905     using ::boost::qvm::operator/;
0906     }
0907 
0908 namespace
0909 qvm_detail
0910     {
0911     template <int R,int C>
0912     struct div_ms_defined;
0913 
0914     template <>
0915     struct
0916     div_ms_defined<3,1>
0917         {
0918         static bool const value=true;
0919         };
0920     }
0921 
0922 template <class A,class B>
0923 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0924 typename lazy_enable_if_c<
0925     is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==1,
0926     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0927 operator/( A a, B const & b )
0928     {
0929     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0930     R r;
0931     write_mat_element<0,0>(r,a/mat_traits<B>::template read_element<0,0>(b));
0932     write_mat_element<1,0>(r,a/mat_traits<B>::template read_element<1,0>(b));
0933     write_mat_element<2,0>(r,a/mat_traits<B>::template read_element<2,0>(b));
0934     return r;
0935     }
0936 
0937 namespace
0938 sfinae
0939     {
0940     using ::boost::qvm::operator/;
0941     }
0942 
0943 namespace
0944 qvm_detail
0945     {
0946     template <int R,int C>
0947     struct div_sm_defined;
0948 
0949     template <>
0950     struct
0951     div_sm_defined<3,1>
0952         {
0953         static bool const value=true;
0954         };
0955     }
0956 
0957 template <class A,class B>
0958 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0959 typename lazy_enable_if_c<
0960     mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0961     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0962 operator/( A const & a, B b )
0963     {
0964     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0965     R r;
0966     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)/b);
0967     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)/b);
0968     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)/b);
0969     return r;
0970     }
0971 
0972 namespace
0973 sfinae
0974     {
0975     using ::boost::qvm::operator/;
0976     }
0977 
0978 namespace
0979 qvm_detail
0980     {
0981     template <int R,int C>
0982     struct div_ms_defined;
0983 
0984     template <>
0985     struct
0986     div_ms_defined<1,3>
0987         {
0988         static bool const value=true;
0989         };
0990     }
0991 
0992 template <class A,class B>
0993 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0994 typename enable_if_c<
0995     mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0996     A &>::type
0997 operator/=( A & a, B b )
0998     {
0999     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 
1011 namespace
1012 sfinae
1013     {
1014     using ::boost::qvm::operator/=;
1015     }
1016 
1017 namespace
1018 qvm_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 
1031 template <class A,class B>
1032 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1033 typename enable_if_c<
1034     mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
1035     A &>::type
1036 operator/=( 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 
1044 namespace
1045 sfinae
1046     {
1047     using ::boost::qvm::operator/=;
1048     }
1049 
1050 namespace
1051 qvm_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 
1064 template <class A,class B>
1065 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1066 typename enable_if_c<
1067     mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
1068     A &>::type
1069 operator/=( 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 
1077 namespace
1078 sfinae
1079     {
1080     using ::boost::qvm::operator/=;
1081     }
1082 
1083 namespace
1084 qvm_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 
1097 template <class R,class A>
1098 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1099 typename 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
1103 convert_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 
1118 template <class R,class A>
1119 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1120 typename 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
1124 convert_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 
1155 namespace
1156 sfinae
1157     {
1158     using ::boost::qvm::convert_to;
1159     }
1160 
1161 namespace
1162 qvm_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 
1175 template <class R,class A>
1176 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1177 typename 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
1181 convert_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 
1190 namespace
1191 sfinae
1192     {
1193     using ::boost::qvm::convert_to;
1194     }
1195 
1196 namespace
1197 qvm_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 
1210 template <class R,class A>
1211 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1212 typename 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
1216 convert_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 
1225 namespace
1226 sfinae
1227     {
1228     using ::boost::qvm::convert_to;
1229     }
1230 
1231 namespace
1232 qvm_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 
1245 template <class A,class B>
1246 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1247 typename 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
1251 operator==( 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 
1265 namespace
1266 sfinae
1267     {
1268     using ::boost::qvm::operator==;
1269     }
1270 
1271 namespace
1272 qvm_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 
1285 template <class A,class B>
1286 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1287 typename 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
1291 operator==( 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 
1299 namespace
1300 sfinae
1301     {
1302     using ::boost::qvm::operator==;
1303     }
1304 
1305 namespace
1306 qvm_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 
1319 template <class A,class B>
1320 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1321 typename 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
1325 operator==( 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 
1333 namespace
1334 sfinae
1335     {
1336     using ::boost::qvm::operator==;
1337     }
1338 
1339 namespace
1340 qvm_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 
1353 template <class A,class B>
1354 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1355 typename 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
1359 operator!=( 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 
1373 namespace
1374 sfinae
1375     {
1376     using ::boost::qvm::operator!=;
1377     }
1378 
1379 namespace
1380 qvm_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 
1393 template <class A,class B>
1394 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1395 typename 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
1399 operator!=( 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 
1407 namespace
1408 sfinae
1409     {
1410     using ::boost::qvm::operator!=;
1411     }
1412 
1413 namespace
1414 qvm_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 
1427 template <class A,class B>
1428 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1429 typename 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
1433 operator!=( 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 
1441 namespace
1442 sfinae
1443     {
1444     using ::boost::qvm::operator!=;
1445     }
1446 
1447 namespace
1448 qvm_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 
1461 template <class A>
1462 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1463 typename lazy_enable_if_c<
1464     mat_traits<A>::rows==3 && mat_traits<A>::cols==3,
1465     deduce_mat<A> >::type
1466 operator-( 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 
1482 namespace
1483 sfinae
1484     {
1485     using ::boost::qvm::operator-;
1486     }
1487 
1488 namespace
1489 qvm_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 
1502 template <class A>
1503 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1504 typename lazy_enable_if_c<
1505     mat_traits<A>::rows==3 && mat_traits<A>::cols==1,
1506     deduce_mat<A> >::type
1507 operator-( 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 
1517 namespace
1518 sfinae
1519     {
1520     using ::boost::qvm::operator-;
1521     }
1522 
1523 namespace
1524 qvm_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 
1537 template <class A>
1538 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1539 typename lazy_enable_if_c<
1540     mat_traits<A>::rows==1 && mat_traits<A>::cols==3,
1541     deduce_mat<A> >::type
1542 operator-( 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 
1552 namespace
1553 sfinae
1554     {
1555     using ::boost::qvm::operator-;
1556     }
1557 
1558 namespace
1559 qvm_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 
1572 template <class A>
1573 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1574 typename enable_if_c<
1575     mat_traits<A>::rows==3 && mat_traits<A>::cols==3,
1576     typename mat_traits<A>::scalar_type>::type
1577 determinant( 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 
1593 namespace
1594 sfinae
1595     {
1596     using ::boost::qvm::determinant;
1597     }
1598 
1599 namespace
1600 qvm_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 
1613 template <class A,class B>
1614 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1615 typename 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
1618 inverse( 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 
1646 template <class A>
1647 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1648 typename lazy_enable_if_c<
1649     mat_traits<A>::rows==3 && mat_traits<A>::cols==3,
1650     deduce_mat<A> >::type
1651 inverse( 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(zero_determinant_error());
1657     return inverse(a,det);
1658     }
1659 
1660 namespace
1661 sfinae
1662     {
1663     using ::boost::qvm::inverse;
1664     }
1665 
1666 namespace
1667 qvm_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 
1680 template <class A,class B>
1681 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1682 typename 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
1686 operator*( 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 
1724 namespace
1725 sfinae
1726     {
1727     using ::boost::qvm::operator*;
1728     }
1729 
1730 namespace
1731 qvm_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 
1744 template <class A,class B>
1745 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1746 typename 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
1750 operator*=( 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 
1784 namespace
1785 sfinae
1786     {
1787     using ::boost::qvm::operator*=;
1788     }
1789 
1790 namespace
1791 qvm_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 
1804 template <class A,class B>
1805 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1806 typename 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
1810 operator*( 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 
1836 namespace
1837 sfinae
1838     {
1839     using ::boost::qvm::operator*;
1840     }
1841 
1842 namespace
1843 qvm_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 
1856 template <class A,class B>
1857 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1858 typename 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
1862 operator*( 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 
1888 namespace
1889 sfinae
1890     {
1891     using ::boost::qvm::operator*;
1892     }
1893 
1894 namespace
1895 qvm_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