]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/qvm/include/boost/qvm/vec_operations.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / qvm / include / boost / qvm / vec_operations.hpp
CommitLineData
7c673cae
FG
1//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
2
3//Distributed under the Boost Software License, Version 1.0. (See accompanying
4//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef UUID_384AFF3AD23A11DFA80B754FE0D72085
7#define UUID_384AFF3AD23A11DFA80B754FE0D72085
8
9#include <boost/qvm/vec_operations2.hpp>
10#include <boost/qvm/vec_operations3.hpp>
11#include <boost/qvm/vec_operations4.hpp>
12#include <boost/qvm/assert.hpp>
13#include <boost/qvm/scalar_traits.hpp>
14#include <string>
15
16namespace
17boost
18 {
19 namespace
20 qvm
21 {
22 namespace
23 qvm_detail
24 {
25 BOOST_QVM_INLINE_CRITICAL
26 void const *
27 get_valid_ptr_vec_operations()
28 {
29 static int const obj=0;
30 return &obj;
31 }
32 }
33
34 ////////////////////////////////////////////////
35
36 namespace
37 qvm_to_string_detail
38 {
39 template <class T>
40 std::string to_string( T const & x );
41 }
42
43 namespace
44 qvm_detail
45 {
46 template <int D>
47 struct
48 to_string_v_defined
49 {
50 static bool const value=false;
51 };
52
53 template <int I,int DimMinusOne>
54 struct
55 to_string_vector_elements
56 {
57 template <class A>
58 static
59 std::string
60 f( A const & a )
61 {
62 using namespace qvm_to_string_detail;
63 return to_string(vec_traits<A>::template read_element<I>(a))+','+to_string_vector_elements<I+1,DimMinusOne>::f(a);
64 }
65 };
66
67 template <int DimMinusOne>
68 struct
69 to_string_vector_elements<DimMinusOne,DimMinusOne>
70 {
71 template <class A>
72 static
73 std::string
74 f( A const & a )
75 {
76 using namespace qvm_to_string_detail;
77 return to_string(vec_traits<A>::template read_element<DimMinusOne>(a));
78 }
79 };
80 }
81
82 template <class A>
83 inline
84 typename boost::enable_if_c<
85 is_vec<A>::value &&
86 !qvm_detail::to_string_v_defined<vec_traits<A>::dim>::value,
87 std::string>::type
88 to_string( A const & a )
89 {
90 return '('+qvm_detail::to_string_vector_elements<0,vec_traits<A>::dim-1>::f(a)+')';
91 }
92
93 ////////////////////////////////////////////////
94
95 namespace
96 qvm_detail
97 {
98 template <int D>
99 struct
100 assign_vv_defined
101 {
102 static bool const value=false;
103 };
104
105 template <int I,int N>
106 struct
107 copy_vector_elements
108 {
109 template <class A,class B>
110 static
111 void
112 f( A & a, B const & b )
113 {
114 vec_traits<A>::template write_element<I>(a)=vec_traits<B>::template read_element<I>(b);
115 copy_vector_elements<I+1,N>::f(a,b);
116 }
117 };
118
119 template <int N>
120 struct
121 copy_vector_elements<N,N>
122 {
123 template <class A,class B>
124 static
125 void
126 f( A &, B const & )
127 {
128 }
129 };
130 }
131
132 template <class A,class B>
133 inline
134 typename boost::enable_if_c<
135 is_vec<A>::value && is_vec<B>::value &&
136 vec_traits<A>::dim==vec_traits<B>::dim &&
137 !qvm_detail::assign_vv_defined<vec_traits<A>::dim>::value,
138 A &>::type
139 assign( A & a, B const & b )
140 {
141 qvm_detail::copy_vector_elements<0,vec_traits<A>::dim>::f(a,b);
142 return a;
143 }
144
145 ////////////////////////////////////////////////
146
147 namespace
148 qvm_detail
149 {
150 template <int D>
151 struct
152 convert_to_v_defined
153 {
154 static bool const value=false;
155 };
156 }
157
158 template <class R,class A>
159 BOOST_QVM_INLINE_TRIVIAL
160 typename enable_if_c<
161 is_vec<R>::value && is_vec<A>::value &&
162 vec_traits<R>::dim==vec_traits<A>::dim &&
163 !qvm_detail::convert_to_v_defined<vec_traits<R>::dim>::value,
164 R>::type
165 convert_to( A const & a )
166 {
167 R r; assign(r,a);
168 return r;
169 }
170
171 ////////////////////////////////////////////////
172
173 template <class A,class B>
174 BOOST_QVM_INLINE_OPERATIONS
175 typename lazy_enable_if_c<
176 is_vec<A>::value && is_vec<B>::value &&
177 vec_traits<A>::dim==3 && vec_traits<B>::dim==3,
178 deduce_vec2<A,B,3> >::type
179 cross( A const & a, B const & b )
180 {
181 typedef typename deduce_vec2<A,B,3>::type R;
182 R r;
183 vec_traits<R>::template write_element<0>(r)=
184 vec_traits<A>::template read_element<1>(a)*vec_traits<B>::template read_element<2>(b)-
185 vec_traits<A>::template read_element<2>(a)*vec_traits<B>::template read_element<1>(b);
186 vec_traits<R>::template write_element<1>(r)=
187 vec_traits<A>::template read_element<2>(a)*vec_traits<B>::template read_element<0>(b)-
188 vec_traits<A>::template read_element<0>(a)*vec_traits<B>::template read_element<2>(b);
189 vec_traits<R>::template write_element<2>(r)=
190 vec_traits<A>::template read_element<0>(a)*vec_traits<B>::template read_element<1>(b)-
191 vec_traits<A>::template read_element<1>(a)*vec_traits<B>::template read_element<0>(b);
192 return r;
193 }
194
195 ////////////////////////////////////////////////
196
197 template <class A,class B,class Cmp>
198 BOOST_QVM_INLINE_OPERATIONS
199 typename enable_if_c<
200 is_vec<A>::value && is_vec<B>::value &&
201 vec_traits<A>::dim==vec_traits<B>::dim,
202 bool>::type
203 cmp( A const & a, B const & b, Cmp f )
204 {
205 typedef typename deduce_scalar<
206 typename vec_traits<A>::scalar_type,
207 typename vec_traits<B>::scalar_type>::type T;
208 int const dim=vec_traits<A>::dim;
209 T v1[dim]; assign(v1,a);
210 T v2[dim]; assign(v2,b);
211 for( int i=0; i!=dim; ++i )
212 if( !f(v1[i],v2[i]) )
213 return false;
214 return true;
215 }
216
217 ////////////////////////////////////////////////
218
219 namespace
220 qvm_detail
221 {
222 template <class T,int Dim>
223 class
224 zero_vec_
225 {
226 zero_vec_( zero_vec_ const & );
227 zero_vec_ & operator=( zero_vec_ const & );
228 ~zero_vec_();
229
230 public:
231
232 template <class R>
233 BOOST_QVM_INLINE_TRIVIAL
234 operator R() const
235 {
236 R r;
237 assign(r,*this);
238 return r;
239 }
240 };
241 }
242
243 template <class V>
244 struct vec_traits;
245
246 template <class T,int Dim>
247 struct
248 vec_traits< qvm_detail::zero_vec_<T,Dim> >
249 {
250 typedef qvm_detail::zero_vec_<T,Dim> this_vector;
251 typedef T scalar_type;
252 static int const dim=Dim;
253
254 template <int I>
255 static
256 BOOST_QVM_INLINE_CRITICAL
257 scalar_type
258 read_element( this_vector const & x )
259 {
260 BOOST_QVM_STATIC_ASSERT(I>=0);
261 BOOST_QVM_STATIC_ASSERT(I<Dim);
262 return scalar_traits<scalar_type>::value(0);
263 }
264
265 static
266 BOOST_QVM_INLINE_CRITICAL
267 scalar_type
268 read_element_idx( int i, this_vector const & x )
269 {
270 BOOST_QVM_ASSERT(i>=0);
271 BOOST_QVM_ASSERT(i<Dim);
272 return scalar_traits<scalar_type>::value(0);
273 }
274 };
275
276 template <class T,int Dim,int D>
277 struct
278 deduce_vec<qvm_detail::zero_vec_<T,Dim>,D>
279 {
280 typedef vec<T,D> type;
281 };
282
283 template <class T,int Dim>
284 BOOST_QVM_INLINE_TRIVIAL
285 qvm_detail::zero_vec_<T,Dim> const &
286 zero_vec()
287 {
288 return *(qvm_detail::zero_vec_<T,Dim> const *)qvm_detail::get_valid_ptr_vec_operations();
289 }
290
291 template <class A>
292 BOOST_QVM_INLINE_OPERATIONS
293 typename enable_if_c<
294 is_vec<A>::value,
295 void>::type
296 set_zero( A & a )
297 {
298 assign(a,zero_vec<typename vec_traits<A>::scalar_type,vec_traits<A>::dim>());
299 }
300
301 ////////////////////////////////////////////////
302
303 namespace
304 qvm_detail
305 {
306 template <class OriginalType,class Scalar>
307 class
308 vector_scalar_cast_
309 {
310 vector_scalar_cast_( vector_scalar_cast_ const & );
311 vector_scalar_cast_ & operator=( vector_scalar_cast_ const & );
312 ~vector_scalar_cast_();
313
314 public:
315
316 template <class T>
317 BOOST_QVM_INLINE_TRIVIAL
318 vector_scalar_cast_ &
319 operator=( T const & x )
320 {
321 assign(*this,x);
322 return *this;
323 }
324
325 template <class R>
326 BOOST_QVM_INLINE_TRIVIAL
327 operator R() const
328 {
329 R r;
330 assign(r,*this);
331 return r;
332 }
333 };
334
335 template <bool> struct scalar_cast_vector_filter { };
336 template <> struct scalar_cast_vector_filter<true> { typedef int type; };
337 }
338
339 template <class OriginalType,class Scalar>
340 struct
341 vec_traits< qvm_detail::vector_scalar_cast_<OriginalType,Scalar> >
342 {
343 typedef Scalar scalar_type;
344 typedef qvm_detail::vector_scalar_cast_<OriginalType,Scalar> this_vector;
345 static int const dim=vec_traits<OriginalType>::dim;
346
347 template <int I>
348 static
349 BOOST_QVM_INLINE_CRITICAL
350 scalar_type
351 read_element( this_vector const & x )
352 {
353 BOOST_QVM_STATIC_ASSERT(I>=0);
354 BOOST_QVM_STATIC_ASSERT(I<dim);
355 return scalar_type(vec_traits<OriginalType>::template read_element<I>(reinterpret_cast<OriginalType const &>(x)));
356 }
357
358 static
359 BOOST_QVM_INLINE_CRITICAL
360 scalar_type
361 read_element_idx( int i, this_vector const & x )
362 {
363 BOOST_QVM_ASSERT(i>=0);
364 BOOST_QVM_ASSERT(i<dim);
365 return scalar_type(vec_traits<OriginalType>::read_element_idx(i,reinterpret_cast<OriginalType const &>(x)));
366 }
367 };
368
369 template <class OriginalType,class Scalar,int D>
370 struct
371 deduce_vec<qvm_detail::vector_scalar_cast_<OriginalType,Scalar>,D>
372 {
373 typedef vec<Scalar,D> type;
374 };
375
376 template <class Scalar,class T>
377 BOOST_QVM_INLINE_TRIVIAL
378 qvm_detail::vector_scalar_cast_<T,Scalar> const &
379 scalar_cast( T const & x, typename qvm_detail::scalar_cast_vector_filter<is_vec<T>::value>::type=0 )
380 {
381 return reinterpret_cast<qvm_detail::vector_scalar_cast_<T,Scalar> const &>(x);
382 }
383
384 ////////////////////////////////////////////////
385
386 namespace
387 qvm_detail
388 {
389 template <int D>
390 struct
391 div_eq_vs_defined
392 {
393 static bool const value=false;
394 };
395 }
396
397 template <class A,class B>
398 BOOST_QVM_INLINE_OPERATIONS
399 typename enable_if_c<
400 is_vec<A>::value && is_scalar<B>::value &&
401 !qvm_detail::div_eq_vs_defined<vec_traits<A>::dim>::value,
402 A &>::type
403 operator/=( A & a, B b )
404 {
405 for( int i=0; i!=vec_traits<A>::dim; ++i )
406 vec_traits<A>::write_element_idx(i,a)/=b;
407 return a;
408 }
409
410 ////////////////////////////////////////////////
411
412 namespace
413 qvm_detail
414 {
415 template <int D>
416 struct
417 div_vs_defined
418 {
419 static bool const value=false;
420 };
421 }
422
423 template <class A,class B>
424 BOOST_QVM_INLINE_OPERATIONS
425 typename lazy_enable_if_c<
426 is_vec<A>::value && is_scalar<B>::value &&
427 !qvm_detail::div_vs_defined<vec_traits<A>::dim>::value,
428 deduce_vec<A> >::type
429 operator/( A const & a, B b )
430 {
431 typedef typename deduce_vec<A>::type R;
432 R r;
433 for( int i=0; i!=vec_traits<A>::dim; ++i )
434 vec_traits<R>::write_element_idx(i,r)=vec_traits<A>::read_element_idx(i,a)/b;
435 return r;
436 }
437
438 ////////////////////////////////////////////////
439
440 namespace
441 qvm_detail
442 {
443 template <int D>
444 struct
445 dot_vv_defined
446 {
447 static bool const value=false;
448 };
449 }
450
451 template <class A,class B>
452 BOOST_QVM_INLINE_OPERATIONS
453 typename lazy_enable_if_c<
454 is_vec<A>::value && is_vec<B>::value &&
455 vec_traits<A>::dim==vec_traits<B>::dim &&
456 !qvm_detail::dot_vv_defined<vec_traits<A>::dim>::value,
457 deduce_scalar<typename vec_traits<A>::scalar_type,typename vec_traits<B>::scalar_type> >::type
458 dot( A const & a, B const & b )
459 {
460 typedef typename deduce_scalar<typename vec_traits<A>::scalar_type,typename vec_traits<B>::scalar_type>::type T;
461 T m(scalar_traits<T>::value(0));
462 for( int i=0; i!=vec_traits<A>::dim; ++i )
463 m+=vec_traits<A>::read_element_idx(i,a)*vec_traits<B>::read_element_idx(i,b);
464 return m;
465 }
466
467 ////////////////////////////////////////////////
468
469 namespace
470 qvm_detail
471 {
472 template <int D>
473 struct
474 eq_vv_defined
475 {
476 static bool const value=false;
477 };
478 }
479
480 template <class A,class B>
481 BOOST_QVM_INLINE_OPERATIONS
482 typename enable_if_c<
483 is_vec<A>::value && is_vec<B>::value &&
484 vec_traits<A>::dim==vec_traits<B>::dim &&
485 !qvm_detail::eq_vv_defined<vec_traits<A>::dim>::value,
486 bool>::type
487 operator==( A const & a, B const & b )
488 {
489 for( int i=0; i!=vec_traits<A>::dim; ++i )
490 if( vec_traits<A>::read_element_idx(i,a)!=vec_traits<B>::read_element_idx(i,b) )
491 return false;
492 return true;
493 }
494
495 ////////////////////////////////////////////////
496
497 namespace
498 qvm_detail
499 {
500 template <int D>
501 struct
502 mag_sqr_v_defined
503 {
504 static bool const value=false;
505 };
506 }
507
508 template <class A>
509 BOOST_QVM_INLINE_OPERATIONS
510 typename enable_if_c<
511 is_vec<A>::value &&
512 !qvm_detail::mag_sqr_v_defined<vec_traits<A>::dim>::value,
513 typename vec_traits<A>::scalar_type>::type
514 mag_sqr( A const & a )
515 {
516 typedef typename vec_traits<A>::scalar_type T;
517 T m(scalar_traits<T>::value(0));
518 for( int i=0; i!=vec_traits<A>::dim; ++i )
519 {
520 T x=vec_traits<A>::read_element_idx(i,a);
521 m+=x*x;
522 }
523 return m;
524 }
525
526 ////////////////////////////////////////////////
527
528 namespace
529 qvm_detail
530 {
531 template <int D>
532 struct
533 mag_v_defined
534 {
535 static bool const value=false;
536 };
537 }
538
539 template <class A>
540 BOOST_QVM_INLINE_OPERATIONS
541 typename enable_if_c<
542 is_vec<A>::value &&
543 !qvm_detail::mag_v_defined<vec_traits<A>::dim>::value,
544 typename vec_traits<A>::scalar_type>::type
545 mag( A const & a )
546 {
547 typedef typename vec_traits<A>::scalar_type T;
548 T m(scalar_traits<T>::value(0));
549 for( int i=0; i!=vec_traits<A>::dim; ++i )
550 {
551 T x=vec_traits<A>::read_element_idx(i,a);
552 m+=x*x;
553 }
554 return sqrt<T>(m);
555 }
556
557 ////////////////////////////////////////////////
558
559 namespace
560 qvm_detail
561 {
562 template <int D>
563 struct
564 minus_eq_vv_defined
565 {
566 static bool const value=false;
567 };
568 }
569
570 template <class A,class B>
571 BOOST_QVM_INLINE_OPERATIONS
572 typename enable_if_c<
573 is_vec<A>::value && is_vec<B>::value &&
574 vec_traits<A>::dim==vec_traits<B>::dim &&
575 !qvm_detail::minus_eq_vv_defined<vec_traits<A>::dim>::value,
576 A &>::type
577 operator-=( A & a, B const & b )
578 {
579 for( int i=0; i!=vec_traits<A>::dim; ++i )
580 vec_traits<A>::write_element_idx(i,a)-=vec_traits<B>::read_element_idx(i,b);
581 return a;
582 }
583
584 ////////////////////////////////////////////////
585
586 namespace
587 qvm_detail
588 {
589 template <int D>
590 struct
591 minus_v_defined
592 {
593 static bool const value=false;
594 };
595 }
596
597 template <class A>
598 BOOST_QVM_INLINE_OPERATIONS
599 typename lazy_enable_if_c<
600 is_vec<A>::value &&
601 !qvm_detail::minus_v_defined<vec_traits<A>::dim>::value,
602 deduce_vec<A> >::type
603 operator-( A const & a )
604 {
605 typedef typename deduce_vec<A>::type R;
606 R r;
607 for( int i=0; i!=vec_traits<A>::dim; ++i )
608 vec_traits<R>::write_element_idx(i,r)=-vec_traits<A>::read_element_idx(i,a);
609 return r;
610 }
611
612 ////////////////////////////////////////////////
613
614 namespace
615 qvm_detail
616 {
617 template <int D>
618 struct
619 minus_vv_defined
620 {
621 static bool const value=false;
622 };
623 }
624
625 template <class A,class B>
626 BOOST_QVM_INLINE_OPERATIONS
627 typename lazy_enable_if_c<
628 is_vec<A>::value && is_vec<B>::value &&
629 vec_traits<A>::dim==vec_traits<B>::dim &&
630 !qvm_detail::minus_vv_defined<vec_traits<A>::dim>::value,
631 deduce_vec2<A,B,vec_traits<A>::dim> >::type
632 operator-( A const & a, B const & b )
633 {
634 typedef typename deduce_vec2<A,B,vec_traits<A>::dim>::type R;
635 R r;
636 for( int i=0; i!=vec_traits<A>::dim; ++i )
637 vec_traits<R>::write_element_idx(i,r)=vec_traits<A>::read_element_idx(i,a)-vec_traits<B>::read_element_idx(i,b);
638 return r;
639 }
640
641 ////////////////////////////////////////////////
642
643 namespace
644 qvm_detail
645 {
646 template <int D>
647 struct
648 mul_eq_vs_defined
649 {
650 static bool const value=false;
651 };
652 }
653
654 template <class A,class B>
655 BOOST_QVM_INLINE_OPERATIONS
656 typename enable_if_c<
657 is_vec<A>::value && is_scalar<B>::value &&
658 !qvm_detail::mul_eq_vs_defined<vec_traits<A>::dim>::value,
659 A &>::type
660 operator*=( A & a, B b )
661 {
662 for( int i=0; i!=vec_traits<A>::dim; ++i )
663 vec_traits<A>::write_element_idx(i,a)*=b;
664 return a;
665 }
666
667 ////////////////////////////////////////////////
668
669 namespace
670 qvm_detail
671 {
672 template <int D>
673 struct
674 mul_vs_defined
675 {
676 static bool const value=false;
677 };
678 }
679
680 template <class A,class B>
681 BOOST_QVM_INLINE_OPERATIONS
682 typename lazy_enable_if_c<
683 is_vec<A>::value && is_scalar<B>::value &&
684 !qvm_detail::mul_vs_defined<vec_traits<A>::dim>::value,
685 deduce_vec<A> >::type
686 operator*( A const & a, B b )
687 {
688 typedef typename deduce_vec<A>::type R;
689 R r;
690 for( int i=0; i!=vec_traits<A>::dim; ++i )
691 vec_traits<R>::write_element_idx(i,r)=vec_traits<A>::read_element_idx(i,a)*b;
692 return r;
693 }
694
695 ////////////////////////////////////////////////
696
697 namespace
698 qvm_detail
699 {
700 template <int D>
701 struct
702 neq_vv_defined
703 {
704 static bool const value=false;
705 };
706 }
707
708 template <class A,class B>
709 BOOST_QVM_INLINE_OPERATIONS
710 typename enable_if_c<
711 is_vec<A>::value && is_vec<B>::value &&
712 vec_traits<A>::dim==vec_traits<B>::dim &&
713 !qvm_detail::neq_vv_defined<vec_traits<A>::dim>::value,
714 bool>::type
715 operator!=( A const & a, B const & b )
716 {
717 for( int i=0; i!=vec_traits<A>::dim; ++i )
718 if( vec_traits<A>::read_element_idx(i,a)!=vec_traits<B>::read_element_idx(i,b) )
719 return true;
720 return false;
721 }
722
723 ////////////////////////////////////////////////
724
725 namespace
726 qvm_detail
727 {
728 template <int D>
729 struct
730 normalize_v_defined
731 {
732 static bool const value=false;
733 };
734 }
735
736 template <class A>
737 BOOST_QVM_INLINE_OPERATIONS
738 typename lazy_enable_if_c<
739 is_vec<A>::value &&
740 !qvm_detail::normalize_v_defined<vec_traits<A>::dim>::value,
741 deduce_vec<A> >::type
742 normalized( A const & a )
743 {
744 typedef typename vec_traits<A>::scalar_type T;
745 T m(scalar_traits<T>::value(0));
746 for( int i=0; i!=vec_traits<A>::dim; ++i )
747 {
748 T x=vec_traits<A>::read_element_idx(i,a);
749 m+=x*x;
750 }
751 if( m==scalar_traits<T>::value(0) )
752 BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());
753 T rm=scalar_traits<T>::value(1)/sqrt<T>(m);
754 typedef typename deduce_vec<A>::type R;
755 R r;
756 for( int i=0; i!=vec_traits<A>::dim; ++i )
757 vec_traits<R>::write_element_idx(i,r)=vec_traits<A>::read_element_idx(i,a)*rm;
758 return r;
759 }
760
761 template <class A>
762 BOOST_QVM_INLINE_OPERATIONS
763 typename enable_if_c<
764 is_vec<A>::value &&
765 !qvm_detail::normalize_v_defined<vec_traits<A>::dim>::value,
766 void>::type
767 normalize( A & a )
768 {
769 typedef typename vec_traits<A>::scalar_type T;
770 T m(scalar_traits<T>::value(0));
771 for( int i=0; i!=vec_traits<A>::dim; ++i )
772 {
773 T x=vec_traits<A>::read_element_idx(i,a);
774 m+=x*x;
775 }
776 if( m==scalar_traits<T>::value(0) )
777 BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());
778 T rm=scalar_traits<T>::value(1)/sqrt<T>(m);
779 for( int i=0; i!=vec_traits<A>::dim; ++i )
780 vec_traits<A>::write_element_idx(i,a)*=rm;
781 }
782
783 ////////////////////////////////////////////////
784
785 namespace
786 qvm_detail
787 {
788 template <int D>
789 struct
790 plus_eq_vv_defined
791 {
792 static bool const value=false;
793 };
794 }
795
796 template <class A,class B>
797 BOOST_QVM_INLINE_OPERATIONS
798 typename enable_if_c<
799 is_vec<A>::value && is_vec<B>::value &&
800 vec_traits<A>::dim==vec_traits<B>::dim &&
801 !qvm_detail::plus_eq_vv_defined<vec_traits<A>::dim>::value,
802 A &>::type
803 operator+=( A & a, B const & b )
804 {
805 for( int i=0; i!=vec_traits<A>::dim; ++i )
806 vec_traits<A>::write_element_idx(i,a)+=vec_traits<B>::read_element_idx(i,b);
807 return a;
808 }
809
810 ////////////////////////////////////////////////
811
812 namespace
813 qvm_detail
814 {
815 template <int D>
816 struct
817 plus_vv_defined
818 {
819 static bool const value=false;
820 };
821 }
822
823 template <class A,class B>
824 BOOST_QVM_INLINE_OPERATIONS
825 typename lazy_enable_if_c<
826 is_vec<A>::value && is_vec<B>::value &&
827 vec_traits<A>::dim==vec_traits<B>::dim &&
828 !qvm_detail::plus_vv_defined<vec_traits<A>::dim>::value,
829 deduce_vec2<A,B,vec_traits<A>::dim> >::type
830 operator+( A const & a, B const & b )
831 {
832 typedef typename deduce_vec2<A,B,vec_traits<A>::dim>::type R;
833 R r;
834 for( int i=0; i!=vec_traits<A>::dim; ++i )
835 vec_traits<R>::write_element_idx(i,r)=vec_traits<A>::read_element_idx(i,a)+vec_traits<B>::read_element_idx(i,b);
836 return r;
837 }
838
839 ////////////////////////////////////////////////
840
841 namespace
842 qvm_detail
843 {
844 template <class T>
845 class
846 vref_
847 {
848 vref_( vref_ const & );
849 vref_ & operator=( vref_ const & );
850 ~vref_();
851
852 public:
853
854 template <class R>
855 BOOST_QVM_INLINE_TRIVIAL
856 vref_ &
857 operator=( R const & x )
858 {
859 assign(*this,x);
860 return *this;
861 }
862
863 template <class R>
864 BOOST_QVM_INLINE_TRIVIAL
865 operator R() const
866 {
867 R r;
868 assign(r,*this);
869 return r;
870 }
871 };
872 }
873
874 template <class V>
875 struct
876 vec_traits< qvm_detail::vref_<V> >
877 {
878 typedef typename vec_traits<V>::scalar_type scalar_type;
879 typedef qvm_detail::vref_<V> this_vector;
880 static int const dim=vec_traits<V>::dim;
881
882 template <int I>
883 static
884 BOOST_QVM_INLINE_CRITICAL
885 scalar_type
886 read_element( this_vector const & x )
887 {
888 BOOST_QVM_STATIC_ASSERT(I>=0);
889 BOOST_QVM_STATIC_ASSERT(I<dim);
890 return vec_traits<V>::template read_element<I>(reinterpret_cast<V const &>(x));
891 }
892
893 template <int I>
894 static
895 BOOST_QVM_INLINE_CRITICAL
896 scalar_type &
897 write_element( this_vector & x )
898 {
899 BOOST_QVM_STATIC_ASSERT(I>=0);
900 BOOST_QVM_STATIC_ASSERT(I<dim);
901 return vec_traits<V>::template write_element<I>(reinterpret_cast<V &>(x));
902 }
903
904 static
905 BOOST_QVM_INLINE_CRITICAL
906 scalar_type
907 read_element_idx( int i, this_vector const & x )
908 {
909 BOOST_QVM_ASSERT(i>=0);
910 BOOST_QVM_ASSERT(i<dim);
911 return vec_traits<V>::read_element_idx(i,reinterpret_cast<V const &>(x));
912 }
913
914 static
915 BOOST_QVM_INLINE_CRITICAL
916 scalar_type &
917 write_element_idx( int i, this_vector & x )
918 {
919 BOOST_QVM_ASSERT(i>=0);
920 BOOST_QVM_ASSERT(i<dim);
921 return vec_traits<V>::write_element_idx(i,reinterpret_cast<V &>(x));
922 }
923 };
924
925 template <class V,int D>
926 struct
927 deduce_vec<qvm_detail::vref_<V>,D>
928 {
929 typedef vec<typename vec_traits<V>::scalar_type,D> type;
930 };
931
932 template <class V>
933 BOOST_QVM_INLINE_TRIVIAL
934 typename enable_if_c<
935 is_vec<V>::value,
936 qvm_detail::vref_<V> const &>::type
937 vref( V const & a )
938 {
939 return reinterpret_cast<qvm_detail::vref_<V> const &>(a);
940 }
941
942 template <class V>
943 BOOST_QVM_INLINE_TRIVIAL
944 typename enable_if_c<
945 is_vec<V>::value,
946 qvm_detail::vref_<V> &>::type
947 vref( V & a )
948 {
949 return reinterpret_cast<qvm_detail::vref_<V> &>(a);
950 }
951
952 ////////////////////////////////////////////////
953
954 namespace
955 sfinae
956 {
957 using ::boost::qvm::to_string;
958 using ::boost::qvm::assign;
959 using ::boost::qvm::convert_to;
960 using ::boost::qvm::cross;
961 using ::boost::qvm::cmp;
962 using ::boost::qvm::set_zero;
963 using ::boost::qvm::scalar_cast;
964 using ::boost::qvm::operator/=;
965 using ::boost::qvm::operator/;
966 using ::boost::qvm::dot;
967 using ::boost::qvm::operator==;
968 using ::boost::qvm::mag_sqr;
969 using ::boost::qvm::mag;
970 using ::boost::qvm::operator-=;
971 using ::boost::qvm::operator-;
972 using ::boost::qvm::operator*=;
973 using ::boost::qvm::operator*;
974 using ::boost::qvm::operator!=;
975 using ::boost::qvm::normalized;
976 using ::boost::qvm::normalize;
977 using ::boost::qvm::operator+=;
978 using ::boost::qvm::operator+;
979 using ::boost::qvm::vref;
980 }
981
982 ////////////////////////////////////////////////
983 }
984 }
985
986#endif