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