File indexing completed on 2025-09-17 08:49:46
0001 #ifndef BOOST_QVM_GEN_VEC_OPERATIONS3_HPP_INCLUDED
0002 #define BOOST_QVM_GEN_VEC_OPERATIONS3_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/qvm/deduce_scalar.hpp>
0010 #include <boost/qvm/deduce_vec.hpp>
0011 #include <boost/qvm/error.hpp>
0012 #include <boost/qvm/gen/vec_assign3.hpp>
0013 #include <boost/qvm/math.hpp>
0014 #include <boost/qvm/static_assert.hpp>
0015 #include <boost/qvm/throw_exception.hpp>
0016
0017 namespace boost { namespace qvm {
0018
0019 template <class A,class B>
0020 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0021 typename lazy_enable_if_c<
0022 vec_traits<A>::dim==3 && vec_traits<B>::dim==3,
0023 deduce_vec2<A,B,3> >::type
0024 operator+( A const & a, B const & b )
0025 {
0026 typedef typename deduce_vec2<A,B,3>::type R;
0027 BOOST_QVM_STATIC_ASSERT(vec_traits<R>::dim==3);
0028 R r;
0029 write_vec_element<0>(r,vec_traits<A>::template read_element<0>(a)+vec_traits<B>::template read_element<0>(b));
0030 write_vec_element<1>(r,vec_traits<A>::template read_element<1>(a)+vec_traits<B>::template read_element<1>(b));
0031 write_vec_element<2>(r,vec_traits<A>::template read_element<2>(a)+vec_traits<B>::template read_element<2>(b));
0032 return r;
0033 }
0034
0035 namespace
0036 sfinae
0037 {
0038 using ::boost::qvm::operator+;
0039 }
0040
0041 namespace
0042 qvm_detail
0043 {
0044 template <int D>
0045 struct plus_vv_defined;
0046
0047 template <>
0048 struct
0049 plus_vv_defined<3>
0050 {
0051 static bool const value=true;
0052 };
0053 }
0054
0055 template <class A,class B>
0056 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0057 typename lazy_enable_if_c<
0058 vec_traits<A>::dim==3 && vec_traits<B>::dim==3,
0059 deduce_vec2<A,B,3> >::type
0060 operator-( A const & a, B const & b )
0061 {
0062 typedef typename deduce_vec2<A,B,3>::type R;
0063 BOOST_QVM_STATIC_ASSERT(vec_traits<R>::dim==3);
0064 R r;
0065 write_vec_element<0>(r,vec_traits<A>::template read_element<0>(a)-vec_traits<B>::template read_element<0>(b));
0066 write_vec_element<1>(r,vec_traits<A>::template read_element<1>(a)-vec_traits<B>::template read_element<1>(b));
0067 write_vec_element<2>(r,vec_traits<A>::template read_element<2>(a)-vec_traits<B>::template read_element<2>(b));
0068 return r;
0069 }
0070
0071 namespace
0072 sfinae
0073 {
0074 using ::boost::qvm::operator-;
0075 }
0076
0077 namespace
0078 qvm_detail
0079 {
0080 template <int D>
0081 struct minus_vv_defined;
0082
0083 template <>
0084 struct
0085 minus_vv_defined<3>
0086 {
0087 static bool const value=true;
0088 };
0089 }
0090
0091 template <class A,class B>
0092 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0093 typename enable_if_c<
0094 vec_traits<A>::dim==3 && vec_traits<B>::dim==3,
0095 A &>::type
0096 operator+=( A & a, B const & b )
0097 {
0098 write_vec_element<0>(a,vec_traits<A>::template read_element<0>(a)+vec_traits<B>::template read_element<0>(b));
0099 write_vec_element<1>(a,vec_traits<A>::template read_element<1>(a)+vec_traits<B>::template read_element<1>(b));
0100 write_vec_element<2>(a,vec_traits<A>::template read_element<2>(a)+vec_traits<B>::template read_element<2>(b));
0101 return a;
0102 }
0103
0104 namespace
0105 sfinae
0106 {
0107 using ::boost::qvm::operator+=;
0108 }
0109
0110 namespace
0111 qvm_detail
0112 {
0113 template <int D>
0114 struct plus_eq_vv_defined;
0115
0116 template <>
0117 struct
0118 plus_eq_vv_defined<3>
0119 {
0120 static bool const value=true;
0121 };
0122 }
0123
0124 template <class A,class B>
0125 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0126 typename enable_if_c<
0127 vec_traits<A>::dim==3 && vec_traits<B>::dim==3,
0128 A &>::type
0129 operator-=( A & a, B const & b )
0130 {
0131 write_vec_element<0>(a,vec_traits<A>::template read_element<0>(a)-vec_traits<B>::template read_element<0>(b));
0132 write_vec_element<1>(a,vec_traits<A>::template read_element<1>(a)-vec_traits<B>::template read_element<1>(b));
0133 write_vec_element<2>(a,vec_traits<A>::template read_element<2>(a)-vec_traits<B>::template read_element<2>(b));
0134 return a;
0135 }
0136
0137 namespace
0138 sfinae
0139 {
0140 using ::boost::qvm::operator-=;
0141 }
0142
0143 namespace
0144 qvm_detail
0145 {
0146 template <int D>
0147 struct minus_eq_vv_defined;
0148
0149 template <>
0150 struct
0151 minus_eq_vv_defined<3>
0152 {
0153 static bool const value=true;
0154 };
0155 }
0156
0157 template <class A,class B>
0158 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0159 typename lazy_enable_if_c<
0160 vec_traits<A>::dim==3 && is_scalar<B>::value,
0161 deduce_vec2<A,B,vec_traits<A>::dim> >::type
0162 operator*( A const & a, B b )
0163 {
0164 typedef typename deduce_vec2<A,B,vec_traits<A>::dim>::type R;
0165 R r;
0166 write_vec_element<0>(r,vec_traits<A>::template read_element<0>(a)*b);
0167 write_vec_element<1>(r,vec_traits<A>::template read_element<1>(a)*b);
0168 write_vec_element<2>(r,vec_traits<A>::template read_element<2>(a)*b);
0169 return r;
0170 }
0171
0172 namespace
0173 sfinae
0174 {
0175 using ::boost::qvm::operator*;
0176 }
0177
0178 namespace
0179 qvm_detail
0180 {
0181 template <int D>
0182 struct mul_vs_defined;
0183
0184 template <>
0185 struct
0186 mul_vs_defined<3>
0187 {
0188 static bool const value=true;
0189 };
0190 }
0191
0192 template <class A,class B>
0193 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0194 typename lazy_enable_if_c<
0195 is_scalar<A>::value && vec_traits<B>::dim==3,
0196 deduce_vec2<A,B,vec_traits<B>::dim> >::type
0197 operator*( A a, B const & b )
0198 {
0199 typedef typename deduce_vec2<A,B,vec_traits<B>::dim>::type R;
0200 R r;
0201 write_vec_element<0>(r,a*vec_traits<B>::template read_element<0>(b));
0202 write_vec_element<1>(r,a*vec_traits<B>::template read_element<1>(b));
0203 write_vec_element<2>(r,a*vec_traits<B>::template read_element<2>(b));
0204 return r;
0205 }
0206
0207 namespace
0208 sfinae
0209 {
0210 using ::boost::qvm::operator*;
0211 }
0212
0213 namespace
0214 qvm_detail
0215 {
0216 template <int D>
0217 struct mul_sv_defined;
0218
0219 template <>
0220 struct
0221 mul_sv_defined<3>
0222 {
0223 static bool const value=true;
0224 };
0225 }
0226
0227 template <class A,class B>
0228 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0229 typename enable_if_c<
0230 vec_traits<A>::dim==3 && is_scalar<B>::value,
0231 A &>::type
0232 operator*=( A & a, B b )
0233 {
0234 write_vec_element<0>(a, vec_traits<A>::template read_element<0>(a)*b);
0235 write_vec_element<1>(a, vec_traits<A>::template read_element<1>(a)*b);
0236 write_vec_element<2>(a, vec_traits<A>::template read_element<2>(a)*b);
0237 return a;
0238 }
0239
0240 namespace
0241 sfinae
0242 {
0243 using ::boost::qvm::operator*=;
0244 }
0245
0246 namespace
0247 qvm_detail
0248 {
0249 template <int D>
0250 struct mul_eq_vs_defined;
0251
0252 template <>
0253 struct
0254 mul_eq_vs_defined<3>
0255 {
0256 static bool const value=true;
0257 };
0258 }
0259
0260 template <class A,class B>
0261 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0262 typename lazy_enable_if_c<
0263 vec_traits<A>::dim==3 && is_scalar<B>::value,
0264 deduce_vec2<A,B,vec_traits<A>::dim> >::type
0265 operator/( A const & a, B b )
0266 {
0267 typedef typename deduce_vec2<A,B,vec_traits<A>::dim>::type R;
0268 R r;
0269 write_vec_element<0>(r,vec_traits<A>::template read_element<0>(a)/b);
0270 write_vec_element<1>(r,vec_traits<A>::template read_element<1>(a)/b);
0271 write_vec_element<2>(r,vec_traits<A>::template read_element<2>(a)/b);
0272 return r;
0273 }
0274
0275 namespace
0276 sfinae
0277 {
0278 using ::boost::qvm::operator/;
0279 }
0280
0281 namespace
0282 qvm_detail
0283 {
0284 template <int D>
0285 struct div_vs_defined;
0286
0287 template <>
0288 struct
0289 div_vs_defined<3>
0290 {
0291 static bool const value=true;
0292 };
0293 }
0294
0295 template <class A,class B>
0296 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0297 typename enable_if_c<
0298 vec_traits<A>::dim==3 && is_scalar<B>::value,
0299 A &>::type
0300 operator/=( A & a, B b )
0301 {
0302 write_vec_element<0>(a, vec_traits<A>::template read_element<0>(a)/b);
0303 write_vec_element<1>(a, vec_traits<A>::template read_element<1>(a)/b);
0304 write_vec_element<2>(a, vec_traits<A>::template read_element<2>(a)/b);
0305 return a;
0306 }
0307
0308 namespace
0309 sfinae
0310 {
0311 using ::boost::qvm::operator/=;
0312 }
0313
0314 namespace
0315 qvm_detail
0316 {
0317 template <int D>
0318 struct div_eq_vs_defined;
0319
0320 template <>
0321 struct
0322 div_eq_vs_defined<3>
0323 {
0324 static bool const value=true;
0325 };
0326 }
0327
0328 template <class R,class A>
0329 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0330 typename enable_if_c<
0331 is_vec<A>::value &&
0332 vec_traits<R>::dim==3 && vec_traits<A>::dim==3,
0333 R>::type
0334 convert_to( A const & a )
0335 {
0336 R r;
0337 write_vec_element<0>(r,vec_traits<A>::template read_element<0>(a));
0338 write_vec_element<1>(r,vec_traits<A>::template read_element<1>(a));
0339 write_vec_element<2>(r,vec_traits<A>::template read_element<2>(a));
0340 return r;
0341 }
0342
0343 namespace
0344 sfinae
0345 {
0346 using ::boost::qvm::convert_to;
0347 }
0348
0349 namespace
0350 qvm_detail
0351 {
0352 template <int D>
0353 struct convert_to_v_defined;
0354
0355 template <>
0356 struct
0357 convert_to_v_defined<3>
0358 {
0359 static bool const value=true;
0360 };
0361 }
0362
0363 template <class A,class B>
0364 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0365 typename enable_if_c<
0366 vec_traits<A>::dim==3 && vec_traits<B>::dim==3,
0367 bool>::type
0368 operator==( A const & a, B const & b )
0369 {
0370 return
0371 vec_traits<A>::template read_element<0>(a)==vec_traits<B>::template read_element<0>(b) &&
0372 vec_traits<A>::template read_element<1>(a)==vec_traits<B>::template read_element<1>(b) &&
0373 vec_traits<A>::template read_element<2>(a)==vec_traits<B>::template read_element<2>(b);
0374 }
0375
0376 namespace
0377 sfinae
0378 {
0379 using ::boost::qvm::operator==;
0380 }
0381
0382 namespace
0383 qvm_detail
0384 {
0385 template <int D>
0386 struct eq_vv_defined;
0387
0388 template <>
0389 struct
0390 eq_vv_defined<3>
0391 {
0392 static bool const value=true;
0393 };
0394 }
0395
0396 template <class A,class B>
0397 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0398 typename enable_if_c<
0399 vec_traits<A>::dim==3 && vec_traits<B>::dim==3,
0400 bool>::type
0401 operator!=( A const & a, B const & b )
0402 {
0403 return
0404 !(vec_traits<A>::template read_element<0>(a)==vec_traits<B>::template read_element<0>(b)) ||
0405 !(vec_traits<A>::template read_element<1>(a)==vec_traits<B>::template read_element<1>(b)) ||
0406 !(vec_traits<A>::template read_element<2>(a)==vec_traits<B>::template read_element<2>(b));
0407 }
0408
0409 namespace
0410 sfinae
0411 {
0412 using ::boost::qvm::operator!=;
0413 }
0414
0415 namespace
0416 qvm_detail
0417 {
0418 template <int D>
0419 struct neq_vv_defined;
0420
0421 template <>
0422 struct
0423 neq_vv_defined<3>
0424 {
0425 static bool const value=true;
0426 };
0427 }
0428
0429 template <class A>
0430 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0431 typename lazy_enable_if_c<
0432 vec_traits<A>::dim==3,
0433 deduce_vec<A> >::type
0434 operator-( A const & a )
0435 {
0436 typedef typename deduce_vec<A>::type R;
0437 R r;
0438 write_vec_element<0>(r,-vec_traits<A>::template read_element<0>(a));
0439 write_vec_element<1>(r,-vec_traits<A>::template read_element<1>(a));
0440 write_vec_element<2>(r,-vec_traits<A>::template read_element<2>(a));
0441 return r;
0442 }
0443
0444 namespace
0445 sfinae
0446 {
0447 using ::boost::qvm::operator-;
0448 }
0449
0450 namespace
0451 qvm_detail
0452 {
0453 template <int D>
0454 struct minus_v_defined;
0455
0456 template <>
0457 struct
0458 minus_v_defined<3>
0459 {
0460 static bool const value=true;
0461 };
0462 }
0463
0464 template <class A>
0465 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0466 typename enable_if_c<
0467 is_vec<A>::value && vec_traits<A>::dim==3,
0468 typename vec_traits<A>::scalar_type>::type
0469 mag( A const & a )
0470 {
0471 typedef typename vec_traits<A>::scalar_type T;
0472 T const a0=vec_traits<A>::template read_element<0>(a);
0473 T const a1=vec_traits<A>::template read_element<1>(a);
0474 T const a2=vec_traits<A>::template read_element<2>(a);
0475 T const m2=a0*a0+a1*a1+a2*a2;
0476 T const mag=sqrt(m2);
0477 return mag;
0478 }
0479
0480 namespace
0481 sfinae
0482 {
0483 using ::boost::qvm::mag;
0484 }
0485
0486 namespace
0487 qvm_detail
0488 {
0489 template <int D>
0490 struct mag_v_defined;
0491
0492 template <>
0493 struct
0494 mag_v_defined<3>
0495 {
0496 static bool const value=true;
0497 };
0498 }
0499
0500 template <class A>
0501 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0502 typename enable_if_c<
0503 is_vec<A>::value && vec_traits<A>::dim==3,
0504 typename vec_traits<A>::scalar_type>::type
0505 mag_sqr( A const & a )
0506 {
0507 typedef typename vec_traits<A>::scalar_type T;
0508 T const a0=vec_traits<A>::template read_element<0>(a);
0509 T const a1=vec_traits<A>::template read_element<1>(a);
0510 T const a2=vec_traits<A>::template read_element<2>(a);
0511 T const m2=a0*a0+a1*a1+a2*a2;
0512 return m2;
0513 }
0514
0515 namespace
0516 sfinae
0517 {
0518 using ::boost::qvm::mag_sqr;
0519 }
0520
0521 namespace
0522 qvm_detail
0523 {
0524 template <int D>
0525 struct mag_sqr_v_defined;
0526
0527 template <>
0528 struct
0529 mag_sqr_v_defined<3>
0530 {
0531 static bool const value=true;
0532 };
0533 }
0534
0535 template <class A>
0536 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0537 typename lazy_enable_if_c<
0538 vec_traits<A>::dim==3,
0539 deduce_vec<A> >::type
0540 normalized( A const & a )
0541 {
0542 typedef typename vec_traits<A>::scalar_type T;
0543 T const a0=vec_traits<A>::template read_element<0>(a);
0544 T const a1=vec_traits<A>::template read_element<1>(a);
0545 T const a2=vec_traits<A>::template read_element<2>(a);
0546 T const m2=a0*a0+a1*a1+a2*a2;
0547 if( m2==scalar_traits<typename vec_traits<A>::scalar_type>::value(0) )
0548 BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());
0549 T const rm=scalar_traits<T>::value(1)/sqrt(m2);
0550 typedef typename deduce_vec<A>::type R;
0551 R r;
0552 write_vec_element<0>(r,a0*rm);
0553 write_vec_element<1>(r,a1*rm);
0554 write_vec_element<2>(r,a2*rm);
0555 return r;
0556 }
0557
0558 namespace
0559 sfinae
0560 {
0561 using ::boost::qvm::normalized;
0562 }
0563
0564 template <class A>
0565 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0566 typename enable_if_c<
0567 vec_traits<A>::dim==3,
0568 void>::type
0569 normalize( A & a )
0570 {
0571 typedef typename vec_traits<A>::scalar_type T;
0572 T const a0=vec_traits<A>::template read_element<0>(a);
0573 T const a1=vec_traits<A>::template read_element<1>(a);
0574 T const a2=vec_traits<A>::template read_element<2>(a);
0575 T const m2=a0*a0+a1*a1+a2*a2;
0576 if( m2==scalar_traits<typename vec_traits<A>::scalar_type>::value(0) )
0577 BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());
0578 T const rm=scalar_traits<T>::value(1)/sqrt(m2);
0579 write_vec_element<0>(a,vec_traits<A>::template read_element<0>(a)*rm);
0580 write_vec_element<1>(a,vec_traits<A>::template read_element<1>(a)*rm);
0581 write_vec_element<2>(a,vec_traits<A>::template read_element<2>(a)*rm);
0582 }
0583
0584 namespace
0585 sfinae
0586 {
0587 using ::boost::qvm::normalize;
0588 }
0589
0590 namespace
0591 qvm_detail
0592 {
0593 template <int D>
0594 struct normalize_v_defined;
0595
0596 template <>
0597 struct
0598 normalize_v_defined<3>
0599 {
0600 static bool const value=true;
0601 };
0602 }
0603
0604 template <class A,class B>
0605 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0606 typename lazy_enable_if_c<
0607 vec_traits<A>::dim==3 && vec_traits<B>::dim==3,
0608 deduce_scalar<typename vec_traits<A>::scalar_type,typename vec_traits<B>::scalar_type> >::type
0609 dot( A const & a, B const & b )
0610 {
0611 typedef typename vec_traits<A>::scalar_type Ta;
0612 typedef typename vec_traits<B>::scalar_type Tb;
0613 typedef typename deduce_scalar<Ta,Tb>::type Tr;
0614 Ta const a0=vec_traits<A>::template read_element<0>(a);
0615 Ta const a1=vec_traits<A>::template read_element<1>(a);
0616 Ta const a2=vec_traits<A>::template read_element<2>(a);
0617 Tb const b0=vec_traits<B>::template read_element<0>(b);
0618 Tb const b1=vec_traits<B>::template read_element<1>(b);
0619 Tb const b2=vec_traits<B>::template read_element<2>(b);
0620 Tr const dot=a0*b0+a1*b1+a2*b2;
0621 return dot;
0622 }
0623
0624 namespace
0625 sfinae
0626 {
0627 using ::boost::qvm::dot;
0628 }
0629
0630 namespace
0631 qvm_detail
0632 {
0633 template <int D>
0634 struct dot_vv_defined;
0635
0636 template <>
0637 struct
0638 dot_vv_defined<3>
0639 {
0640 static bool const value=true;
0641 };
0642 }
0643
0644 } }
0645
0646 #endif