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_8AC84A2217C411E0A7AF3A1BDFD72085
7 #define UUID_8AC84A2217C411E0A7AF3A1BDFD72085
8 
9 #include <boost/qvm/inline.hpp>
10 #include <boost/qvm/quat_traits.hpp>
11 #include <boost/qvm/deduce_vec.hpp>
12 #include <boost/qvm/static_assert.hpp>
13 #include <boost/qvm/enable_if.hpp>
14 
15 namespace
16 boost
17     {
18     namespace
19     qvm
20         {
21         ////////////////////////////////////////////////
22 
23         namespace
24         qvm_detail
25             {
26             template <class Q>
27             struct
28             quat_v_
29                 {
30                 template <class R>
operator Rboost::qvm::qvm_detail::quat_v_31                 operator R() const
32                     {
33                     R r;
34                     assign(r,*this);
35                     return r;
36                     }
37 
38                 private:
39 
40                 quat_v_( quat_v_ const & );
41                 quat_v_ const & operator=( quat_v_ const & );
42                 ~quat_v_();
43                 };
44             }
45 
46         template <class V>
47         struct vec_traits;
48 
49         template <class Q>
50         struct
51         vec_traits< qvm_detail::quat_v_<Q> >
52             {
53             typedef qvm_detail::quat_v_<Q> this_vector;
54             typedef typename quat_traits<Q>::scalar_type scalar_type;
55             static int const dim=3;
56 
57             template <int I>
58             BOOST_QVM_INLINE_CRITICAL
59             static
60             scalar_type
read_elementboost::qvm::vec_traits61             read_element( this_vector const & q )
62                 {
63                 BOOST_QVM_STATIC_ASSERT(I>=0);
64                 BOOST_QVM_STATIC_ASSERT(I<dim);
65                 return quat_traits<Q>::template read_element<I+1>( reinterpret_cast<Q const &>(q) );
66                 }
67 
68             template <int I>
69             BOOST_QVM_INLINE_CRITICAL
70             static
71             scalar_type &
write_elementboost::qvm::vec_traits72             write_element( this_vector & q )
73                 {
74                 BOOST_QVM_STATIC_ASSERT(I>=0);
75                 BOOST_QVM_STATIC_ASSERT(I<dim);
76                 return quat_traits<Q>::template write_element<I+1>( reinterpret_cast<Q &>(q) );
77                 }
78             };
79 
80         template <class Q,int D>
81         struct
82         deduce_vec<qvm_detail::quat_v_<Q>,D>
83             {
84             typedef vec<typename quat_traits<Q>::scalar_type,D> type;
85             };
86 
87         template <class Q,int D>
88         struct
89         deduce_vec2<qvm_detail::quat_v_<Q>,qvm_detail::quat_v_<Q>,D>
90             {
91             typedef vec<typename quat_traits<Q>::scalar_type,D> type;
92             };
93 
94         template <class Q>
95         BOOST_QVM_INLINE_TRIVIAL
96         typename enable_if_c<
97             is_quat<Q>::value,
98             qvm_detail::quat_v_<Q> const &>::type
V(Q const & a)99         V( Q const & a )
100             {
101             return reinterpret_cast<qvm_detail::quat_v_<Q> const &>(a);
102             }
103 
104         template <class Q>
105         BOOST_QVM_INLINE_TRIVIAL
106         typename enable_if_c<
107             is_quat<Q>::value,
108             qvm_detail::quat_v_<Q> &>::type
V(Q & a)109         V( Q & a )
110             {
111             return reinterpret_cast<qvm_detail::quat_v_<Q> &>(a);
112             }
113 
S(Q const & a)114         template <class Q> BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value,typename quat_traits<Q>::scalar_type>::type S( Q const & a ) { return quat_traits<Q>::template read_element<0>(a); }
X(Q const & a)115         template <class Q> BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value,typename quat_traits<Q>::scalar_type>::type X( Q const & a ) { return quat_traits<Q>::template read_element<1>(a); }
Y(Q const & a)116         template <class Q> BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value,typename quat_traits<Q>::scalar_type>::type Y( Q const & a ) { return quat_traits<Q>::template read_element<2>(a); }
Z(Q const & a)117         template <class Q> BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value,typename quat_traits<Q>::scalar_type>::type Z( Q const & a ) { return quat_traits<Q>::template read_element<3>(a); }
118 
S(Q & a)119         template <class Q> BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value,typename quat_traits<Q>::scalar_type &>::type S( Q & a ) { return quat_traits<Q>::template write_element<0>(a); }
X(Q & a)120         template <class Q> BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value,typename quat_traits<Q>::scalar_type &>::type X( Q & a ) { return quat_traits<Q>::template write_element<1>(a); }
Y(Q & a)121         template <class Q> BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value,typename quat_traits<Q>::scalar_type &>::type Y( Q & a ) { return quat_traits<Q>::template write_element<2>(a); }
Z(Q & a)122         template <class Q> BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value,typename quat_traits<Q>::scalar_type &>::type Z( Q & a ) { return quat_traits<Q>::template write_element<3>(a); }
123 
124         ////////////////////////////////////////////////
125         }
126     }
127 
128 #endif
129