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