Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:03:39

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