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