Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-26 08:36:24

0001 #ifndef BOOST_QVM_GEN_MAT_OPERATIONS3_HPP_INCLUDED
0002 #define BOOST_QVM_GEN_MAT_OPERATIONS3_HPP_INCLUDED
0003 
0004 // Copyright 2008-2024 Emil Dotchevski and Reverge Studios, Inc.
0005 // This file was generated by a program. Do not edit manually.
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 #include <boost/qvm/assert.hpp>
0010 #include <boost/qvm/deduce_mat.hpp>
0011 #include <boost/qvm/deduce_vec.hpp>
0012 #include <boost/qvm/error.hpp>
0013 #include <boost/qvm/gen/mat_assign3.hpp>
0014 #include <boost/qvm/quat_traits.hpp>
0015 #include <boost/qvm/scalar_traits.hpp>
0016 #include <boost/qvm/throw_exception.hpp>
0017 
0018 namespace boost { namespace qvm {
0019 
0020 template <class A,class B>
0021 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0022 typename lazy_enable_if_c<
0023     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0024     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0025     deduce_mat2<A,B,3,3> >::type
0026 operator+( A const & a, B const & b )
0027     {
0028     typedef typename deduce_mat2<A,B,3,3>::type R;
0029     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
0030     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
0031     R r;
0032     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0033     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0034     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0035     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0036     write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)+mat_traits<B>::template read_element<1,1>(b));
0037     write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)+mat_traits<B>::template read_element<1,2>(b));
0038     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0039     write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)+mat_traits<B>::template read_element<2,1>(b));
0040     write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)+mat_traits<B>::template read_element<2,2>(b));
0041     return r;
0042     }
0043 
0044 namespace
0045 sfinae
0046     {
0047     using ::boost::qvm::operator+;
0048     }
0049 
0050 namespace
0051 qvm_detail
0052     {
0053     template <int R,int C>
0054     struct plus_mm_defined;
0055 
0056     template <>
0057     struct
0058     plus_mm_defined<3,3>
0059         {
0060         static bool const value=true;
0061         };
0062     }
0063 
0064 template <class A,class B>
0065 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0066 typename lazy_enable_if_c<
0067     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0068     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0069     deduce_mat2<A,B,3,1> >::type
0070 operator+( A const & a, B const & b )
0071     {
0072     typedef typename deduce_mat2<A,B,3,1>::type R;
0073     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
0074     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
0075     R r;
0076     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0077     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0078     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0079     return r;
0080     }
0081 
0082 namespace
0083 sfinae
0084     {
0085     using ::boost::qvm::operator+;
0086     }
0087 
0088 namespace
0089 qvm_detail
0090     {
0091     template <int R,int C>
0092     struct plus_mm_defined;
0093 
0094     template <>
0095     struct
0096     plus_mm_defined<3,1>
0097         {
0098         static bool const value=true;
0099         };
0100     }
0101 
0102 template <class A,class B>
0103 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0104 typename lazy_enable_if_c<
0105     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0106     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0107     deduce_mat2<A,B,1,3> >::type
0108 operator+( A const & a, B const & b )
0109     {
0110     typedef typename deduce_mat2<A,B,1,3>::type R;
0111     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
0112     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
0113     R r;
0114     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0115     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0116     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0117     return r;
0118     }
0119 
0120 namespace
0121 sfinae
0122     {
0123     using ::boost::qvm::operator+;
0124     }
0125 
0126 namespace
0127 qvm_detail
0128     {
0129     template <int R,int C>
0130     struct plus_mm_defined;
0131 
0132     template <>
0133     struct
0134     plus_mm_defined<1,3>
0135         {
0136         static bool const value=true;
0137         };
0138     }
0139 
0140 template <class A,class B>
0141 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0142 typename lazy_enable_if_c<
0143     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0144     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0145     deduce_mat2<A,B,3,3> >::type
0146 operator-( A const & a, B const & b )
0147     {
0148     typedef typename deduce_mat2<A,B,3,3>::type R;
0149     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
0150     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
0151     R r;
0152     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0153     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0154     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0155     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0156     write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)-mat_traits<B>::template read_element<1,1>(b));
0157     write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)-mat_traits<B>::template read_element<1,2>(b));
0158     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0159     write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)-mat_traits<B>::template read_element<2,1>(b));
0160     write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)-mat_traits<B>::template read_element<2,2>(b));
0161     return r;
0162     }
0163 
0164 namespace
0165 sfinae
0166     {
0167     using ::boost::qvm::operator-;
0168     }
0169 
0170 namespace
0171 qvm_detail
0172     {
0173     template <int R,int C>
0174     struct minus_mm_defined;
0175 
0176     template <>
0177     struct
0178     minus_mm_defined<3,3>
0179         {
0180         static bool const value=true;
0181         };
0182     }
0183 
0184 template <class A,class B>
0185 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0186 typename lazy_enable_if_c<
0187     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0188     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0189     deduce_mat2<A,B,3,1> >::type
0190 operator-( A const & a, B const & b )
0191     {
0192     typedef typename deduce_mat2<A,B,3,1>::type R;
0193     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
0194     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
0195     R r;
0196     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0197     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0198     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0199     return r;
0200     }
0201 
0202 namespace
0203 sfinae
0204     {
0205     using ::boost::qvm::operator-;
0206     }
0207 
0208 namespace
0209 qvm_detail
0210     {
0211     template <int R,int C>
0212     struct minus_mm_defined;
0213 
0214     template <>
0215     struct
0216     minus_mm_defined<3,1>
0217         {
0218         static bool const value=true;
0219         };
0220     }
0221 
0222 template <class A,class B>
0223 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0224 typename lazy_enable_if_c<
0225     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0226     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0227     deduce_mat2<A,B,1,3> >::type
0228 operator-( A const & a, B const & b )
0229     {
0230     typedef typename deduce_mat2<A,B,1,3>::type R;
0231     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
0232     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
0233     R r;
0234     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0235     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0236     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0237     return r;
0238     }
0239 
0240 namespace
0241 sfinae
0242     {
0243     using ::boost::qvm::operator-;
0244     }
0245 
0246 namespace
0247 qvm_detail
0248     {
0249     template <int R,int C>
0250     struct minus_mm_defined;
0251 
0252     template <>
0253     struct
0254     minus_mm_defined<1,3>
0255         {
0256         static bool const value=true;
0257         };
0258     }
0259 
0260 template <class A,class B>
0261 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0262 typename enable_if_c<
0263     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0264     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0265     A &>::type
0266 operator+=( A & a, B const & b )
0267     {
0268     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0269     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0270     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0271     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0272     write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)+mat_traits<B>::template read_element<1,1>(b));
0273     write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)+mat_traits<B>::template read_element<1,2>(b));
0274     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0275     write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)+mat_traits<B>::template read_element<2,1>(b));
0276     write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)+mat_traits<B>::template read_element<2,2>(b));
0277     return a;
0278     }
0279 
0280 namespace
0281 sfinae
0282     {
0283     using ::boost::qvm::operator+=;
0284     }
0285 
0286 namespace
0287 qvm_detail
0288     {
0289     template <int R,int C>
0290     struct plus_eq_mm_defined;
0291 
0292     template <>
0293     struct
0294     plus_eq_mm_defined<3,3>
0295         {
0296         static bool const value=true;
0297         };
0298     }
0299 
0300 template <class A,class B>
0301 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0302 typename enable_if_c<
0303     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0304     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0305     A &>::type
0306 operator+=( A & a, B const & b )
0307     {
0308     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0309     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b));
0310     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b));
0311     return a;
0312     }
0313 
0314 namespace
0315 sfinae
0316     {
0317     using ::boost::qvm::operator+=;
0318     }
0319 
0320 namespace
0321 qvm_detail
0322     {
0323     template <int R,int C>
0324     struct plus_eq_mm_defined;
0325 
0326     template <>
0327     struct
0328     plus_eq_mm_defined<3,1>
0329         {
0330         static bool const value=true;
0331         };
0332     }
0333 
0334 template <class A,class B>
0335 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0336 typename enable_if_c<
0337     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0338     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0339     A &>::type
0340 operator+=( A & a, B const & b )
0341     {
0342     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b));
0343     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b));
0344     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b));
0345     return a;
0346     }
0347 
0348 namespace
0349 sfinae
0350     {
0351     using ::boost::qvm::operator+=;
0352     }
0353 
0354 namespace
0355 qvm_detail
0356     {
0357     template <int R,int C>
0358     struct plus_eq_mm_defined;
0359 
0360     template <>
0361     struct
0362     plus_eq_mm_defined<1,3>
0363         {
0364         static bool const value=true;
0365         };
0366     }
0367 
0368 template <class A,class B>
0369 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0370 typename enable_if_c<
0371     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0372     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0373     A &>::type
0374 operator-=( A & a, B const & b )
0375     {
0376     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0377     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0378     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0379     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0380     write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)-mat_traits<B>::template read_element<1,1>(b));
0381     write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)-mat_traits<B>::template read_element<1,2>(b));
0382     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0383     write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)-mat_traits<B>::template read_element<2,1>(b));
0384     write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)-mat_traits<B>::template read_element<2,2>(b));
0385     return a;
0386     }
0387 
0388 namespace
0389 sfinae
0390     {
0391     using ::boost::qvm::operator-=;
0392     }
0393 
0394 namespace
0395 qvm_detail
0396     {
0397     template <int R,int C>
0398     struct minus_eq_mm_defined;
0399 
0400     template <>
0401     struct
0402     minus_eq_mm_defined<3,3>
0403         {
0404         static bool const value=true;
0405         };
0406     }
0407 
0408 template <class A,class B>
0409 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0410 typename enable_if_c<
0411     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
0412     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
0413     A &>::type
0414 operator-=( A & a, B const & b )
0415     {
0416     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0417     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b));
0418     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b));
0419     return a;
0420     }
0421 
0422 namespace
0423 sfinae
0424     {
0425     using ::boost::qvm::operator-=;
0426     }
0427 
0428 namespace
0429 qvm_detail
0430     {
0431     template <int R,int C>
0432     struct minus_eq_mm_defined;
0433 
0434     template <>
0435     struct
0436     minus_eq_mm_defined<3,1>
0437         {
0438         static bool const value=true;
0439         };
0440     }
0441 
0442 template <class A,class B>
0443 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0444 typename enable_if_c<
0445     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
0446     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
0447     A &>::type
0448 operator-=( A & a, B const & b )
0449     {
0450     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b));
0451     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b));
0452     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b));
0453     return a;
0454     }
0455 
0456 namespace
0457 sfinae
0458     {
0459     using ::boost::qvm::operator-=;
0460     }
0461 
0462 namespace
0463 qvm_detail
0464     {
0465     template <int R,int C>
0466     struct minus_eq_mm_defined;
0467 
0468     template <>
0469     struct
0470     minus_eq_mm_defined<1,3>
0471         {
0472         static bool const value=true;
0473         };
0474     }
0475 
0476 template <class A,class B>
0477 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0478 typename lazy_enable_if_c<
0479     mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0480     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0481 operator*( A const & a, B b )
0482     {
0483     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0484     R r;
0485     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)*b);
0486     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)*b);
0487     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)*b);
0488     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)*b);
0489     write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)*b);
0490     write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)*b);
0491     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)*b);
0492     write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)*b);
0493     write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)*b);
0494     return r;
0495     }
0496 
0497 namespace
0498 sfinae
0499     {
0500     using ::boost::qvm::operator*;
0501     }
0502 
0503 namespace
0504 qvm_detail
0505     {
0506     template <int R,int C>
0507     struct mul_ms_defined;
0508 
0509     template <>
0510     struct
0511     mul_ms_defined<3,3>
0512         {
0513         static bool const value=true;
0514         };
0515     }
0516 
0517 template <class A,class B>
0518 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0519 typename lazy_enable_if_c<
0520     is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==3,
0521     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0522 operator*( A a, B const & b )
0523     {
0524     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0525     R r;
0526     write_mat_element<0,0>(r,a*mat_traits<B>::template read_element<0,0>(b));
0527     write_mat_element<0,1>(r,a*mat_traits<B>::template read_element<0,1>(b));
0528     write_mat_element<0,2>(r,a*mat_traits<B>::template read_element<0,2>(b));
0529     write_mat_element<1,0>(r,a*mat_traits<B>::template read_element<1,0>(b));
0530     write_mat_element<1,1>(r,a*mat_traits<B>::template read_element<1,1>(b));
0531     write_mat_element<1,2>(r,a*mat_traits<B>::template read_element<1,2>(b));
0532     write_mat_element<2,0>(r,a*mat_traits<B>::template read_element<2,0>(b));
0533     write_mat_element<2,1>(r,a*mat_traits<B>::template read_element<2,1>(b));
0534     write_mat_element<2,2>(r,a*mat_traits<B>::template read_element<2,2>(b));
0535     return r;
0536     }
0537 
0538 namespace
0539 sfinae
0540     {
0541     using ::boost::qvm::operator*;
0542     }
0543 
0544 namespace
0545 qvm_detail
0546     {
0547     template <int R,int C>
0548     struct mul_sm_defined;
0549 
0550     template <>
0551     struct
0552     mul_sm_defined<3,3>
0553         {
0554         static bool const value=true;
0555         };
0556     }
0557 
0558 template <class A,class B>
0559 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0560 typename lazy_enable_if_c<
0561     mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
0562     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0563 operator*( A const & a, B b )
0564     {
0565     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0566     R r;
0567     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)*b);
0568     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)*b);
0569     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)*b);
0570     return r;
0571     }
0572 
0573 namespace
0574 sfinae
0575     {
0576     using ::boost::qvm::operator*;
0577     }
0578 
0579 namespace
0580 qvm_detail
0581     {
0582     template <int R,int C>
0583     struct mul_ms_defined;
0584 
0585     template <>
0586     struct
0587     mul_ms_defined<3,1>
0588         {
0589         static bool const value=true;
0590         };
0591     }
0592 
0593 template <class A,class B>
0594 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0595 typename lazy_enable_if_c<
0596     is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==1,
0597     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0598 operator*( A a, B const & b )
0599     {
0600     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0601     R r;
0602     write_mat_element<0,0>(r,a*mat_traits<B>::template read_element<0,0>(b));
0603     write_mat_element<1,0>(r,a*mat_traits<B>::template read_element<1,0>(b));
0604     write_mat_element<2,0>(r,a*mat_traits<B>::template read_element<2,0>(b));
0605     return r;
0606     }
0607 
0608 namespace
0609 sfinae
0610     {
0611     using ::boost::qvm::operator*;
0612     }
0613 
0614 namespace
0615 qvm_detail
0616     {
0617     template <int R,int C>
0618     struct mul_sm_defined;
0619 
0620     template <>
0621     struct
0622     mul_sm_defined<3,1>
0623         {
0624         static bool const value=true;
0625         };
0626     }
0627 
0628 template <class A,class B>
0629 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0630 typename lazy_enable_if_c<
0631     mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0632     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0633 operator*( A const & a, B b )
0634     {
0635     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0636     R r;
0637     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)*b);
0638     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)*b);
0639     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)*b);
0640     return r;
0641     }
0642 
0643 namespace
0644 sfinae
0645     {
0646     using ::boost::qvm::operator*;
0647     }
0648 
0649 namespace
0650 qvm_detail
0651     {
0652     template <int R,int C>
0653     struct mul_ms_defined;
0654 
0655     template <>
0656     struct
0657     mul_ms_defined<1,3>
0658         {
0659         static bool const value=true;
0660         };
0661     }
0662 
0663 template <class A,class B>
0664 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0665 typename lazy_enable_if_c<
0666     is_scalar<A>::value && mat_traits<B>::rows==1 && mat_traits<B>::cols==3,
0667     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0668 operator*( A a, B const & b )
0669     {
0670     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0671     R r;
0672     write_mat_element<0,0>(r,a*mat_traits<B>::template read_element<0,0>(b));
0673     write_mat_element<0,1>(r,a*mat_traits<B>::template read_element<0,1>(b));
0674     write_mat_element<0,2>(r,a*mat_traits<B>::template read_element<0,2>(b));
0675     return r;
0676     }
0677 
0678 namespace
0679 sfinae
0680     {
0681     using ::boost::qvm::operator*;
0682     }
0683 
0684 namespace
0685 qvm_detail
0686     {
0687     template <int R,int C>
0688     struct mul_sm_defined;
0689 
0690     template <>
0691     struct
0692     mul_sm_defined<1,3>
0693         {
0694         static bool const value=true;
0695         };
0696     }
0697 
0698 template <class A,class B>
0699 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0700 typename enable_if_c<
0701     mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0702     A &>::type
0703 operator*=( A & a, B b )
0704     {
0705     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)*b);
0706     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)*b);
0707     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)*b);
0708     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)*b);
0709     write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)*b);
0710     write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)*b);
0711     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)*b);
0712     write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)*b);
0713     write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)*b);
0714     return a;
0715     }
0716 
0717 namespace
0718 sfinae
0719     {
0720     using ::boost::qvm::operator*=;
0721     }
0722 
0723 namespace
0724 qvm_detail
0725     {
0726     template <int R,int C>
0727     struct mul_eq_ms_defined;
0728 
0729     template <>
0730     struct
0731     mul_eq_ms_defined<3,3>
0732         {
0733         static bool const value=true;
0734         };
0735     }
0736 
0737 template <class A,class B>
0738 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0739 typename enable_if_c<
0740     mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
0741     A &>::type
0742 operator*=( A & a, B b )
0743     {
0744     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)*b);
0745     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)*b);
0746     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)*b);
0747     return a;
0748     }
0749 
0750 namespace
0751 sfinae
0752     {
0753     using ::boost::qvm::operator*=;
0754     }
0755 
0756 namespace
0757 qvm_detail
0758     {
0759     template <int R,int C>
0760     struct mul_eq_ms_defined;
0761 
0762     template <>
0763     struct
0764     mul_eq_ms_defined<3,1>
0765         {
0766         static bool const value=true;
0767         };
0768     }
0769 
0770 template <class A,class B>
0771 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0772 typename enable_if_c<
0773     mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0774     A &>::type
0775 operator*=( A & a, B b )
0776     {
0777     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)*b);
0778     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)*b);
0779     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)*b);
0780     return a;
0781     }
0782 
0783 namespace
0784 sfinae
0785     {
0786     using ::boost::qvm::operator*=;
0787     }
0788 
0789 namespace
0790 qvm_detail
0791     {
0792     template <int R,int C>
0793     struct mul_eq_ms_defined;
0794 
0795     template <>
0796     struct
0797     mul_eq_ms_defined<1,3>
0798         {
0799         static bool const value=true;
0800         };
0801     }
0802 
0803 template <class A,class B>
0804 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0805 typename lazy_enable_if_c<
0806     mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0807     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0808 operator/( A const & a, B b )
0809     {
0810     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0811     R r;
0812     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)/b);
0813     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)/b);
0814     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)/b);
0815     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)/b);
0816     write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a)/b);
0817     write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a)/b);
0818     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)/b);
0819     write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a)/b);
0820     write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a)/b);
0821     return r;
0822     }
0823 
0824 namespace
0825 sfinae
0826     {
0827     using ::boost::qvm::operator/;
0828     }
0829 
0830 namespace
0831 qvm_detail
0832     {
0833     template <int R,int C>
0834     struct div_ms_defined;
0835 
0836     template <>
0837     struct
0838     div_ms_defined<3,3>
0839         {
0840         static bool const value=true;
0841         };
0842     }
0843 
0844 template <class A,class B>
0845 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0846 typename lazy_enable_if_c<
0847     is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==3,
0848     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0849 operator/( A a, B const & b )
0850     {
0851     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0852     R r;
0853     write_mat_element<0,0>(r,a/mat_traits<B>::template read_element<0,0>(b));
0854     write_mat_element<0,1>(r,a/mat_traits<B>::template read_element<0,1>(b));
0855     write_mat_element<0,2>(r,a/mat_traits<B>::template read_element<0,2>(b));
0856     write_mat_element<1,0>(r,a/mat_traits<B>::template read_element<1,0>(b));
0857     write_mat_element<1,1>(r,a/mat_traits<B>::template read_element<1,1>(b));
0858     write_mat_element<1,2>(r,a/mat_traits<B>::template read_element<1,2>(b));
0859     write_mat_element<2,0>(r,a/mat_traits<B>::template read_element<2,0>(b));
0860     write_mat_element<2,1>(r,a/mat_traits<B>::template read_element<2,1>(b));
0861     write_mat_element<2,2>(r,a/mat_traits<B>::template read_element<2,2>(b));
0862     return r;
0863     }
0864 
0865 namespace
0866 sfinae
0867     {
0868     using ::boost::qvm::operator/;
0869     }
0870 
0871 namespace
0872 qvm_detail
0873     {
0874     template <int R,int C>
0875     struct div_sm_defined;
0876 
0877     template <>
0878     struct
0879     div_sm_defined<3,3>
0880         {
0881         static bool const value=true;
0882         };
0883     }
0884 
0885 template <class A,class B>
0886 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0887 typename lazy_enable_if_c<
0888     mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
0889     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0890 operator/( A const & a, B b )
0891     {
0892     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0893     R r;
0894     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)/b);
0895     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a)/b);
0896     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a)/b);
0897     return r;
0898     }
0899 
0900 namespace
0901 sfinae
0902     {
0903     using ::boost::qvm::operator/;
0904     }
0905 
0906 namespace
0907 qvm_detail
0908     {
0909     template <int R,int C>
0910     struct div_ms_defined;
0911 
0912     template <>
0913     struct
0914     div_ms_defined<3,1>
0915         {
0916         static bool const value=true;
0917         };
0918     }
0919 
0920 template <class A,class B>
0921 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0922 typename lazy_enable_if_c<
0923     is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==1,
0924     deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
0925 operator/( A a, B const & b )
0926     {
0927     typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
0928     R r;
0929     write_mat_element<0,0>(r,a/mat_traits<B>::template read_element<0,0>(b));
0930     write_mat_element<1,0>(r,a/mat_traits<B>::template read_element<1,0>(b));
0931     write_mat_element<2,0>(r,a/mat_traits<B>::template read_element<2,0>(b));
0932     return r;
0933     }
0934 
0935 namespace
0936 sfinae
0937     {
0938     using ::boost::qvm::operator/;
0939     }
0940 
0941 namespace
0942 qvm_detail
0943     {
0944     template <int R,int C>
0945     struct div_sm_defined;
0946 
0947     template <>
0948     struct
0949     div_sm_defined<3,1>
0950         {
0951         static bool const value=true;
0952         };
0953     }
0954 
0955 template <class A,class B>
0956 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0957 typename lazy_enable_if_c<
0958     mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0959     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
0960 operator/( A const & a, B b )
0961     {
0962     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
0963     R r;
0964     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a)/b);
0965     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a)/b);
0966     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a)/b);
0967     return r;
0968     }
0969 
0970 namespace
0971 sfinae
0972     {
0973     using ::boost::qvm::operator/;
0974     }
0975 
0976 namespace
0977 qvm_detail
0978     {
0979     template <int R,int C>
0980     struct div_ms_defined;
0981 
0982     template <>
0983     struct
0984     div_ms_defined<1,3>
0985         {
0986         static bool const value=true;
0987         };
0988     }
0989 
0990 template <class A,class B>
0991 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0992 typename enable_if_c<
0993     mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
0994     A &>::type
0995 operator/=( A & a, B b )
0996     {
0997     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)/b);
0998     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)/b);
0999     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)/b);
1000     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)/b);
1001     write_mat_element<1,1>(a,mat_traits<A>::template read_element<1,1>(a)/b);
1002     write_mat_element<1,2>(a,mat_traits<A>::template read_element<1,2>(a)/b);
1003     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)/b);
1004     write_mat_element<2,1>(a,mat_traits<A>::template read_element<2,1>(a)/b);
1005     write_mat_element<2,2>(a,mat_traits<A>::template read_element<2,2>(a)/b);
1006     return a;
1007     }
1008 
1009 namespace
1010 sfinae
1011     {
1012     using ::boost::qvm::operator/=;
1013     }
1014 
1015 namespace
1016 qvm_detail
1017     {
1018     template <int R,int C>
1019     struct div_eq_ms_defined;
1020 
1021     template <>
1022     struct
1023     div_eq_ms_defined<3,3>
1024         {
1025         static bool const value=true;
1026         };
1027     }
1028 
1029 template <class A,class B>
1030 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1031 typename enable_if_c<
1032     mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
1033     A &>::type
1034 operator/=( A & a, B b )
1035     {
1036     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)/b);
1037     write_mat_element<1,0>(a,mat_traits<A>::template read_element<1,0>(a)/b);
1038     write_mat_element<2,0>(a,mat_traits<A>::template read_element<2,0>(a)/b);
1039     return a;
1040     }
1041 
1042 namespace
1043 sfinae
1044     {
1045     using ::boost::qvm::operator/=;
1046     }
1047 
1048 namespace
1049 qvm_detail
1050     {
1051     template <int R,int C>
1052     struct div_eq_ms_defined;
1053 
1054     template <>
1055     struct
1056     div_eq_ms_defined<3,1>
1057         {
1058         static bool const value=true;
1059         };
1060     }
1061 
1062 template <class A,class B>
1063 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1064 typename enable_if_c<
1065     mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
1066     A &>::type
1067 operator/=( A & a, B b )
1068     {
1069     write_mat_element<0,0>(a,mat_traits<A>::template read_element<0,0>(a)/b);
1070     write_mat_element<0,1>(a,mat_traits<A>::template read_element<0,1>(a)/b);
1071     write_mat_element<0,2>(a,mat_traits<A>::template read_element<0,2>(a)/b);
1072     return a;
1073     }
1074 
1075 namespace
1076 sfinae
1077     {
1078     using ::boost::qvm::operator/=;
1079     }
1080 
1081 namespace
1082 qvm_detail
1083     {
1084     template <int R,int C>
1085     struct div_eq_ms_defined;
1086 
1087     template <>
1088     struct
1089     div_eq_ms_defined<1,3>
1090         {
1091         static bool const value=true;
1092         };
1093     }
1094 
1095 template <class R,class A>
1096 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1097 typename enable_if_c<
1098     mat_traits<R>::rows==3 && mat_traits<A>::rows==3 &&
1099     mat_traits<R>::cols==3 && mat_traits<A>::cols==3,
1100     R>::type
1101 convert_to( A const & a )
1102     {
1103     R r;
1104     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a));
1105     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a));
1106     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a));
1107     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a));
1108     write_mat_element<1,1>(r,mat_traits<A>::template read_element<1,1>(a));
1109     write_mat_element<1,2>(r,mat_traits<A>::template read_element<1,2>(a));
1110     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a));
1111     write_mat_element<2,1>(r,mat_traits<A>::template read_element<2,1>(a));
1112     write_mat_element<2,2>(r,mat_traits<A>::template read_element<2,2>(a));
1113     return r;
1114     }
1115 
1116 template <class R,class A>
1117 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1118 typename enable_if_c<
1119     is_mat<R>::value && is_quat<A>::value &&
1120     mat_traits<R>::rows==3 && mat_traits<R>::cols==3,
1121     R>::type
1122 convert_to( A const & q )
1123     {
1124     typedef typename mat_traits<R>::scalar_type T;
1125     T const a=quat_traits<A>::template read_element<0>(q);
1126     T const b=quat_traits<A>::template read_element<1>(q);
1127     T const c=quat_traits<A>::template read_element<2>(q);
1128     T const d=quat_traits<A>::template read_element<3>(q);
1129     T const bb = b*b;
1130     T const cc = c*c;
1131     T const dd = d*d;
1132     T const bc = b*c;
1133     T const bd = b*d;
1134     T const cd = c*d;
1135     T const ab = a*b;
1136     T const ac = a*c;
1137     T const ad = a*d;
1138     T const one = scalar_traits<T>::value(1);
1139     T const two = one+one;
1140     R r;
1141     write_mat_element<0,0>(r,one - two*(cc+dd));
1142     write_mat_element<0,1>(r,two*(bc-ad));
1143     write_mat_element<0,2>(r,two*(bd+ac));
1144     write_mat_element<1,0>(r,two*(bc+ad));
1145     write_mat_element<1,1>(r,one - two*(bb+dd));
1146     write_mat_element<1,2>(r,two*(cd-ab));
1147     write_mat_element<2,0>(r,two*(bd-ac));
1148     write_mat_element<2,1>(r,two*(cd+ab));
1149     write_mat_element<2,2>(r,one - two*(bb+cc));
1150     return r;
1151     }
1152 
1153 namespace
1154 sfinae
1155     {
1156     using ::boost::qvm::convert_to;
1157     }
1158 
1159 namespace
1160 qvm_detail
1161     {
1162     template <int R,int C>
1163     struct convert_to_m_defined;
1164 
1165     template <>
1166     struct
1167     convert_to_m_defined<3,3>
1168         {
1169         static bool const value=true;
1170         };
1171     }
1172 
1173 template <class R,class A>
1174 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1175 typename enable_if_c<
1176     mat_traits<R>::rows==3 && mat_traits<A>::rows==3 &&
1177     mat_traits<R>::cols==1 && mat_traits<A>::cols==1,
1178     R>::type
1179 convert_to( A const & a )
1180     {
1181     R r;
1182     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a));
1183     write_mat_element<1,0>(r,mat_traits<A>::template read_element<1,0>(a));
1184     write_mat_element<2,0>(r,mat_traits<A>::template read_element<2,0>(a));
1185     return r;
1186     }
1187 
1188 namespace
1189 sfinae
1190     {
1191     using ::boost::qvm::convert_to;
1192     }
1193 
1194 namespace
1195 qvm_detail
1196     {
1197     template <int R,int C>
1198     struct convert_to_m_defined;
1199 
1200     template <>
1201     struct
1202     convert_to_m_defined<3,1>
1203         {
1204         static bool const value=true;
1205         };
1206     }
1207 
1208 template <class R,class A>
1209 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1210 typename enable_if_c<
1211     mat_traits<R>::rows==1 && mat_traits<A>::rows==1 &&
1212     mat_traits<R>::cols==3 && mat_traits<A>::cols==3,
1213     R>::type
1214 convert_to( A const & a )
1215     {
1216     R r;
1217     write_mat_element<0,0>(r,mat_traits<A>::template read_element<0,0>(a));
1218     write_mat_element<0,1>(r,mat_traits<A>::template read_element<0,1>(a));
1219     write_mat_element<0,2>(r,mat_traits<A>::template read_element<0,2>(a));
1220     return r;
1221     }
1222 
1223 namespace
1224 sfinae
1225     {
1226     using ::boost::qvm::convert_to;
1227     }
1228 
1229 namespace
1230 qvm_detail
1231     {
1232     template <int R,int C>
1233     struct convert_to_m_defined;
1234 
1235     template <>
1236     struct
1237     convert_to_m_defined<1,3>
1238         {
1239         static bool const value=true;
1240         };
1241     }
1242 
1243 template <class A,class B>
1244 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1245 typename enable_if_c<
1246     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
1247     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
1248     bool>::type
1249 operator==( A const & a, B const & b )
1250     {
1251     return
1252         mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
1253         mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) &&
1254         mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b) &&
1255         mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) &&
1256         mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b) &&
1257         mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b) &&
1258         mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b) &&
1259         mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b) &&
1260         mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b);
1261     }
1262 
1263 namespace
1264 sfinae
1265     {
1266     using ::boost::qvm::operator==;
1267     }
1268 
1269 namespace
1270 qvm_detail
1271     {
1272     template <int R,int C>
1273     struct eq_mm_defined;
1274 
1275     template <>
1276     struct
1277     eq_mm_defined<3,3>
1278         {
1279         static bool const value=true;
1280         };
1281     }
1282 
1283 template <class A,class B>
1284 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1285 typename enable_if_c<
1286     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
1287     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
1288     bool>::type
1289 operator==( A const & a, B const & b )
1290     {
1291     return
1292         mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
1293         mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) &&
1294         mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b);
1295     }
1296 
1297 namespace
1298 sfinae
1299     {
1300     using ::boost::qvm::operator==;
1301     }
1302 
1303 namespace
1304 qvm_detail
1305     {
1306     template <int R,int C>
1307     struct eq_mm_defined;
1308 
1309     template <>
1310     struct
1311     eq_mm_defined<3,1>
1312         {
1313         static bool const value=true;
1314         };
1315     }
1316 
1317 template <class A,class B>
1318 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1319 typename enable_if_c<
1320     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
1321     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
1322     bool>::type
1323 operator==( A const & a, B const & b )
1324     {
1325     return
1326         mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
1327         mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) &&
1328         mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b);
1329     }
1330 
1331 namespace
1332 sfinae
1333     {
1334     using ::boost::qvm::operator==;
1335     }
1336 
1337 namespace
1338 qvm_detail
1339     {
1340     template <int R,int C>
1341     struct eq_mm_defined;
1342 
1343     template <>
1344     struct
1345     eq_mm_defined<1,3>
1346         {
1347         static bool const value=true;
1348         };
1349     }
1350 
1351 template <class A,class B>
1352 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1353 typename enable_if_c<
1354     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
1355     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
1356     bool>::type
1357 operator!=( A const & a, B const & b )
1358     {
1359     return
1360         !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
1361         !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) ||
1362         !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b)) ||
1363         !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) ||
1364         !(mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b)) ||
1365         !(mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b)) ||
1366         !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b)) ||
1367         !(mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b)) ||
1368         !(mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b));
1369     }
1370 
1371 namespace
1372 sfinae
1373     {
1374     using ::boost::qvm::operator!=;
1375     }
1376 
1377 namespace
1378 qvm_detail
1379     {
1380     template <int R,int C>
1381     struct neq_mm_defined;
1382 
1383     template <>
1384     struct
1385     neq_mm_defined<3,3>
1386         {
1387         static bool const value=true;
1388         };
1389     }
1390 
1391 template <class A,class B>
1392 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1393 typename enable_if_c<
1394     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
1395     mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
1396     bool>::type
1397 operator!=( A const & a, B const & b )
1398     {
1399     return
1400         !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
1401         !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) ||
1402         !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b));
1403     }
1404 
1405 namespace
1406 sfinae
1407     {
1408     using ::boost::qvm::operator!=;
1409     }
1410 
1411 namespace
1412 qvm_detail
1413     {
1414     template <int R,int C>
1415     struct neq_mm_defined;
1416 
1417     template <>
1418     struct
1419     neq_mm_defined<3,1>
1420         {
1421         static bool const value=true;
1422         };
1423     }
1424 
1425 template <class A,class B>
1426 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1427 typename enable_if_c<
1428     mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
1429     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
1430     bool>::type
1431 operator!=( A const & a, B const & b )
1432     {
1433     return
1434         !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
1435         !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) ||
1436         !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b));
1437     }
1438 
1439 namespace
1440 sfinae
1441     {
1442     using ::boost::qvm::operator!=;
1443     }
1444 
1445 namespace
1446 qvm_detail
1447     {
1448     template <int R,int C>
1449     struct neq_mm_defined;
1450 
1451     template <>
1452     struct
1453     neq_mm_defined<1,3>
1454         {
1455         static bool const value=true;
1456         };
1457     }
1458 
1459 template <class A>
1460 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1461 typename lazy_enable_if_c<
1462     mat_traits<A>::rows==3 && mat_traits<A>::cols==3,
1463     deduce_mat<A> >::type
1464 operator-( A const & a )
1465     {
1466     typedef typename deduce_mat<A>::type R;
1467     R r;
1468     write_mat_element<0,0>(r,-mat_traits<A>::template read_element<0,0>(a));
1469     write_mat_element<0,1>(r,-mat_traits<A>::template read_element<0,1>(a));
1470     write_mat_element<0,2>(r,-mat_traits<A>::template read_element<0,2>(a));
1471     write_mat_element<1,0>(r,-mat_traits<A>::template read_element<1,0>(a));
1472     write_mat_element<1,1>(r,-mat_traits<A>::template read_element<1,1>(a));
1473     write_mat_element<1,2>(r,-mat_traits<A>::template read_element<1,2>(a));
1474     write_mat_element<2,0>(r,-mat_traits<A>::template read_element<2,0>(a));
1475     write_mat_element<2,1>(r,-mat_traits<A>::template read_element<2,1>(a));
1476     write_mat_element<2,2>(r,-mat_traits<A>::template read_element<2,2>(a));
1477     return r;
1478     }
1479 
1480 namespace
1481 sfinae
1482     {
1483     using ::boost::qvm::operator-;
1484     }
1485 
1486 namespace
1487 qvm_detail
1488     {
1489     template <int R,int C>
1490     struct minus_m_defined;
1491 
1492     template <>
1493     struct
1494     minus_m_defined<3,3>
1495         {
1496         static bool const value=true;
1497         };
1498     }
1499 
1500 template <class A>
1501 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1502 typename lazy_enable_if_c<
1503     mat_traits<A>::rows==3 && mat_traits<A>::cols==1,
1504     deduce_mat<A> >::type
1505 operator-( A const & a )
1506     {
1507     typedef typename deduce_mat<A>::type R;
1508     R r;
1509     write_mat_element<0,0>(r,-mat_traits<A>::template read_element<0,0>(a));
1510     write_mat_element<1,0>(r,-mat_traits<A>::template read_element<1,0>(a));
1511     write_mat_element<2,0>(r,-mat_traits<A>::template read_element<2,0>(a));
1512     return r;
1513     }
1514 
1515 namespace
1516 sfinae
1517     {
1518     using ::boost::qvm::operator-;
1519     }
1520 
1521 namespace
1522 qvm_detail
1523     {
1524     template <int R,int C>
1525     struct minus_m_defined;
1526 
1527     template <>
1528     struct
1529     minus_m_defined<3,1>
1530         {
1531         static bool const value=true;
1532         };
1533     }
1534 
1535 template <class A>
1536 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1537 typename lazy_enable_if_c<
1538     mat_traits<A>::rows==1 && mat_traits<A>::cols==3,
1539     deduce_mat<A> >::type
1540 operator-( A const & a )
1541     {
1542     typedef typename deduce_mat<A>::type R;
1543     R r;
1544     write_mat_element<0,0>(r,-mat_traits<A>::template read_element<0,0>(a));
1545     write_mat_element<0,1>(r,-mat_traits<A>::template read_element<0,1>(a));
1546     write_mat_element<0,2>(r,-mat_traits<A>::template read_element<0,2>(a));
1547     return r;
1548     }
1549 
1550 namespace
1551 sfinae
1552     {
1553     using ::boost::qvm::operator-;
1554     }
1555 
1556 namespace
1557 qvm_detail
1558     {
1559     template <int R,int C>
1560     struct minus_m_defined;
1561 
1562     template <>
1563     struct
1564     minus_m_defined<1,3>
1565         {
1566         static bool const value=true;
1567         };
1568     }
1569 
1570 template <class A>
1571 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1572 typename enable_if_c<
1573     mat_traits<A>::rows==3 && mat_traits<A>::cols==3,
1574     typename mat_traits<A>::scalar_type>::type
1575 determinant( A const & a )
1576     {
1577     typedef typename mat_traits<A>::scalar_type T;
1578     T const a00=mat_traits<A>::template read_element<0,0>(a);
1579     T const a01=mat_traits<A>::template read_element<0,1>(a);
1580     T const a02=mat_traits<A>::template read_element<0,2>(a);
1581     T const a10=mat_traits<A>::template read_element<1,0>(a);
1582     T const a11=mat_traits<A>::template read_element<1,1>(a);
1583     T const a12=mat_traits<A>::template read_element<1,2>(a);
1584     T const a20=mat_traits<A>::template read_element<2,0>(a);
1585     T const a21=mat_traits<A>::template read_element<2,1>(a);
1586     T const a22=mat_traits<A>::template read_element<2,2>(a);
1587     T det=(a00*(a11*a22-a12*a21)-a01*(a10*a22-a12*a20)+a02*(a10*a21-a11*a20));
1588     return det;
1589     }
1590 
1591 namespace
1592 sfinae
1593     {
1594     using ::boost::qvm::determinant;
1595     }
1596 
1597 namespace
1598 qvm_detail
1599     {
1600     template <int D>
1601     struct determinant_defined;
1602 
1603     template <>
1604     struct
1605     determinant_defined<3>
1606         {
1607         static bool const value=true;
1608         };
1609     }
1610 
1611 template <class A,class B>
1612 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1613 typename lazy_enable_if_c<
1614     mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
1615     deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
1616 inverse( A const & a, B det )
1617     {
1618     typedef typename mat_traits<A>::scalar_type T;
1619     BOOST_QVM_ASSERT(det!=scalar_traits<B>::value(0));
1620     T const a00=mat_traits<A>::template read_element<0,0>(a);
1621     T const a01=mat_traits<A>::template read_element<0,1>(a);
1622     T const a02=mat_traits<A>::template read_element<0,2>(a);
1623     T const a10=mat_traits<A>::template read_element<1,0>(a);
1624     T const a11=mat_traits<A>::template read_element<1,1>(a);
1625     T const a12=mat_traits<A>::template read_element<1,2>(a);
1626     T const a20=mat_traits<A>::template read_element<2,0>(a);
1627     T const a21=mat_traits<A>::template read_element<2,1>(a);
1628     T const a22=mat_traits<A>::template read_element<2,2>(a);
1629     T const f=scalar_traits<T>::value(1)/det;
1630     typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
1631     R r;
1632     write_mat_element<0,0>(r, f*(a11*a22-a12*a21));
1633     write_mat_element<0,1>(r,-f*(a01*a22-a02*a21));
1634     write_mat_element<0,2>(r, f*(a01*a12-a02*a11));
1635     write_mat_element<1,0>(r,-f*(a10*a22-a12*a20));
1636     write_mat_element<1,1>(r, f*(a00*a22-a02*a20));
1637     write_mat_element<1,2>(r,-f*(a00*a12-a02*a10));
1638     write_mat_element<2,0>(r, f*(a10*a21-a11*a20));
1639     write_mat_element<2,1>(r,-f*(a00*a21-a01*a20));
1640     write_mat_element<2,2>(r, f*(a00*a11-a01*a10));
1641     return r;
1642     }
1643 
1644 template <class A>
1645 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1646 typename lazy_enable_if_c<
1647     mat_traits<A>::rows==3 && mat_traits<A>::cols==3,
1648     deduce_mat<A> >::type
1649 inverse( A const & a )
1650     {
1651     typedef typename mat_traits<A>::scalar_type T;
1652     T det=determinant(a);
1653     if( det==scalar_traits<T>::value(0) )
1654         BOOST_QVM_THROW_EXCEPTION(zero_determinant_error());
1655     return inverse(a,det);
1656     }
1657 
1658 namespace
1659 sfinae
1660     {
1661     using ::boost::qvm::inverse;
1662     }
1663 
1664 namespace
1665 qvm_detail
1666     {
1667     template <int D>
1668     struct inverse_m_defined;
1669 
1670     template <>
1671     struct
1672     inverse_m_defined<3>
1673         {
1674         static bool const value=true;
1675         };
1676     }
1677 
1678 template <class A,class B>
1679 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1680 typename lazy_enable_if_c<
1681     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
1682     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
1683     deduce_mat2<A,B,3,3> >::type
1684 operator*( A const & a, B const & b )
1685     {
1686     typedef typename mat_traits<A>::scalar_type Ta;
1687     typedef typename mat_traits<B>::scalar_type Tb;
1688     Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
1689     Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
1690     Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
1691     Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
1692     Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
1693     Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
1694     Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
1695     Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
1696     Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
1697     Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
1698     Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
1699     Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
1700     Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
1701     Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
1702     Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
1703     Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
1704     Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
1705     Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
1706     typedef typename deduce_mat2<A,B,3,3>::type R;
1707     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
1708     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
1709     R r;
1710     write_mat_element<0,0>(r,a00*b00+a01*b10+a02*b20);
1711     write_mat_element<0,1>(r,a00*b01+a01*b11+a02*b21);
1712     write_mat_element<0,2>(r,a00*b02+a01*b12+a02*b22);
1713     write_mat_element<1,0>(r,a10*b00+a11*b10+a12*b20);
1714     write_mat_element<1,1>(r,a10*b01+a11*b11+a12*b21);
1715     write_mat_element<1,2>(r,a10*b02+a11*b12+a12*b22);
1716     write_mat_element<2,0>(r,a20*b00+a21*b10+a22*b20);
1717     write_mat_element<2,1>(r,a20*b01+a21*b11+a22*b21);
1718     write_mat_element<2,2>(r,a20*b02+a21*b12+a22*b22);
1719     return r;
1720     }
1721 
1722 namespace
1723 sfinae
1724     {
1725     using ::boost::qvm::operator*;
1726     }
1727 
1728 namespace
1729 qvm_detail
1730     {
1731     template <int R,int /*CR*/,int C>
1732     struct mul_mm_defined;
1733 
1734     template <>
1735     struct
1736     mul_mm_defined<3,3,3>
1737         {
1738         static bool const value=true;
1739         };
1740     }
1741 
1742 template <class A,class B>
1743 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1744 typename enable_if_c<
1745     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
1746     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
1747     A &>::type
1748 operator*=( A & a, B const & b )
1749     {
1750     typedef typename mat_traits<A>::scalar_type Ta;
1751     typedef typename mat_traits<B>::scalar_type Tb;
1752     Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
1753     Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
1754     Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
1755     Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
1756     Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
1757     Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
1758     Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
1759     Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
1760     Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
1761     Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
1762     Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
1763     Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
1764     Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
1765     Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
1766     Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
1767     Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
1768     Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
1769     Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
1770     write_mat_element<0,0>(a,a00*b00+a01*b10+a02*b20);
1771     write_mat_element<0,1>(a,a00*b01+a01*b11+a02*b21);
1772     write_mat_element<0,2>(a,a00*b02+a01*b12+a02*b22);
1773     write_mat_element<1,0>(a,a10*b00+a11*b10+a12*b20);
1774     write_mat_element<1,1>(a,a10*b01+a11*b11+a12*b21);
1775     write_mat_element<1,2>(a,a10*b02+a11*b12+a12*b22);
1776     write_mat_element<2,0>(a,a20*b00+a21*b10+a22*b20);
1777     write_mat_element<2,1>(a,a20*b01+a21*b11+a22*b21);
1778     write_mat_element<2,2>(a,a20*b02+a21*b12+a22*b22);
1779     return a;
1780     }
1781 
1782 namespace
1783 sfinae
1784     {
1785     using ::boost::qvm::operator*=;
1786     }
1787 
1788 namespace
1789 qvm_detail
1790     {
1791     template <int D>
1792     struct mul_eq_mm_defined;
1793 
1794     template <>
1795     struct
1796     mul_eq_mm_defined<3>
1797         {
1798         static bool const value=true;
1799         };
1800     }
1801 
1802 template <class A,class B>
1803 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1804 typename lazy_enable_if_c<
1805     mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
1806     mat_traits<A>::cols==3 && mat_traits<B>::cols==1,
1807     deduce_mat2<A,B,3,1> >::type
1808 operator*( A const & a, B const & b )
1809     {
1810     typedef typename mat_traits<A>::scalar_type Ta;
1811     typedef typename mat_traits<B>::scalar_type Tb;
1812     Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
1813     Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
1814     Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
1815     Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
1816     Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
1817     Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
1818     Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
1819     Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
1820     Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
1821     Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
1822     Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
1823     Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
1824     typedef typename deduce_mat2<A,B,3,1>::type R;
1825     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
1826     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
1827     R r;
1828     write_mat_element<0,0>(r,a00*b00+a01*b10+a02*b20);
1829     write_mat_element<1,0>(r,a10*b00+a11*b10+a12*b20);
1830     write_mat_element<2,0>(r,a20*b00+a21*b10+a22*b20);
1831     return r;
1832     }
1833 
1834 namespace
1835 sfinae
1836     {
1837     using ::boost::qvm::operator*;
1838     }
1839 
1840 namespace
1841 qvm_detail
1842     {
1843     template <int R,int /*CR*/,int C>
1844     struct mul_mm_defined;
1845 
1846     template <>
1847     struct
1848     mul_mm_defined<3,3,1>
1849         {
1850         static bool const value=true;
1851         };
1852     }
1853 
1854 template <class A,class B>
1855 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1856 typename lazy_enable_if_c<
1857     mat_traits<A>::rows==1 && mat_traits<B>::rows==3 &&
1858     mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
1859     deduce_mat2<A,B,1,3> >::type
1860 operator*( A const & a, B const & b )
1861     {
1862     typedef typename mat_traits<A>::scalar_type Ta;
1863     typedef typename mat_traits<B>::scalar_type Tb;
1864     Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
1865     Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
1866     Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
1867     Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
1868     Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
1869     Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
1870     Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
1871     Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
1872     Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
1873     Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
1874     Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
1875     Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
1876     typedef typename deduce_mat2<A,B,1,3>::type R;
1877     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
1878     BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
1879     R r;
1880     write_mat_element<0,0>(r,a00*b00+a01*b10+a02*b20);
1881     write_mat_element<0,1>(r,a00*b01+a01*b11+a02*b21);
1882     write_mat_element<0,2>(r,a00*b02+a01*b12+a02*b22);
1883     return r;
1884     }
1885 
1886 namespace
1887 sfinae
1888     {
1889     using ::boost::qvm::operator*;
1890     }
1891 
1892 namespace
1893 qvm_detail
1894     {
1895     template <int R,int /*CR*/,int C>
1896     struct mul_mm_defined;
1897 
1898     template <>
1899     struct
1900     mul_mm_defined<1,3,3>
1901         {
1902         static bool const value=true;
1903         };
1904     }
1905 
1906 } }
1907 
1908 #endif