File indexing completed on 2025-01-18 09:51:07
0001 #ifndef BOOST_QVM_QUAT_ACCESS_HPP_INCLUDED
0002 #define BOOST_QVM_QUAT_ACCESS_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/qvm/config.hpp>
0010 #include <boost/qvm/quat_traits.hpp>
0011 #include <boost/qvm/deduce_vec.hpp>
0012 #include <boost/qvm/static_assert.hpp>
0013 #include <boost/qvm/enable_if.hpp>
0014
0015 namespace boost { namespace qvm {
0016
0017 template <class Q> BOOST_QVM_CONSTEXPR 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); }
0018 template <class Q> BOOST_QVM_CONSTEXPR 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); }
0019 template <class Q> BOOST_QVM_CONSTEXPR 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); }
0020 template <class Q> BOOST_QVM_CONSTEXPR 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); }
0021
0022 namespace
0023 qvm_detail
0024 {
0025 template <int I,class Q>
0026 struct
0027 q_element_access
0028 {
0029 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0030 void
0031 operator=( typename quat_traits<Q>::scalar_type s )
0032 {
0033 quat_traits<Q>::template write_element<I>(*reinterpret_cast<Q *>(this), s);
0034 }
0035
0036 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0037 operator typename vec_traits<Q>::scalar_type() const
0038 {
0039 return quat_traits<Q>::template read_element<I>(*reinterpret_cast<Q const *>(this));
0040 }
0041 };
0042
0043 template <class Q>
0044 struct
0045 quat_v_
0046 {
0047 template <class R
0048 #if __cplusplus >= 201103L
0049 , class = typename enable_if<is_vec<R> >::type
0050 #endif
0051 >
0052 operator R() const
0053 {
0054 R r;
0055 assign(r,*this);
0056 return r;
0057 }
0058
0059 private:
0060
0061 quat_v_( quat_v_ const & );
0062 quat_v_ const & operator=( quat_v_ const & );
0063 ~quat_v_();
0064 };
0065
0066 template <class Q,bool WriteElementRef=quat_write_element_ref<Q>::value>
0067 struct quat_v_write_traits;
0068
0069 template <class Q>
0070 struct
0071 quat_v_write_traits<Q,true>
0072 {
0073 typedef qvm_detail::quat_v_<Q> this_vector;
0074 typedef typename quat_traits<Q>::scalar_type scalar_type;
0075 static int const dim=3;
0076
0077 template <int I>
0078 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0079 static
0080 scalar_type &
0081 write_element( this_vector & q )
0082 {
0083 BOOST_QVM_STATIC_ASSERT(I>=0);
0084 BOOST_QVM_STATIC_ASSERT(I<dim);
0085 return quat_traits<Q>::template write_element<I+1>( reinterpret_cast<Q &>(q) );
0086 }
0087 };
0088
0089 template <class Q>
0090 struct
0091 quat_v_write_traits<Q,false>
0092 {
0093 typedef qvm_detail::quat_v_<Q> this_vector;
0094 typedef typename quat_traits<Q>::scalar_type scalar_type;
0095 static int const dim=3;
0096
0097 template <int I>
0098 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0099 static
0100 void
0101 write_element( this_vector & q, scalar_type s )
0102 {
0103 BOOST_QVM_STATIC_ASSERT(I>=0);
0104 BOOST_QVM_STATIC_ASSERT(I<dim);
0105 quat_traits<Q>::template write_element<I+1>( reinterpret_cast<Q &>(q), s );
0106 }
0107 };
0108 }
0109
0110 template <class V>
0111 struct vec_traits;
0112
0113 template <class Q>
0114 struct
0115 vec_traits< qvm_detail::quat_v_<Q> >:
0116 qvm_detail::quat_v_write_traits<Q>
0117 {
0118 typedef qvm_detail::quat_v_<Q> this_vector;
0119 typedef typename quat_traits<Q>::scalar_type scalar_type;
0120 static int const dim=3;
0121
0122 template <int I>
0123 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0124 static
0125 scalar_type
0126 read_element( this_vector const & q )
0127 {
0128 BOOST_QVM_STATIC_ASSERT(I>=0);
0129 BOOST_QVM_STATIC_ASSERT(I<dim);
0130 return quat_traits<Q>::template read_element<I+1>( reinterpret_cast<Q const &>(q) );
0131 }
0132 };
0133
0134 template <class Q,int D>
0135 struct
0136 deduce_vec<qvm_detail::quat_v_<Q>,D>
0137 {
0138 typedef vec<typename quat_traits<Q>::scalar_type,D> type;
0139 };
0140
0141 template <class Q,int D>
0142 struct
0143 deduce_vec2<qvm_detail::quat_v_<Q>,qvm_detail::quat_v_<Q>,D>
0144 {
0145 typedef vec<typename quat_traits<Q>::scalar_type,D> type;
0146 };
0147
0148 template <class Q>
0149 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0150 typename enable_if_c<
0151 is_quat<Q>::value,
0152 qvm_detail::quat_v_<Q> const &>::type
0153 V( Q const & a )
0154 {
0155 return reinterpret_cast<qvm_detail::quat_v_<Q> const &>(a);
0156 }
0157
0158 template <class Q>
0159 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0160 typename enable_if_c<
0161 is_quat<Q>::value,
0162 qvm_detail::quat_v_<Q> &>::type
0163 V( Q & a )
0164 {
0165 return reinterpret_cast<qvm_detail::quat_v_<Q> &>(a);
0166 }
0167
0168 template <class Q> BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value && quat_write_element_ref<Q>::value,typename quat_traits<Q>::scalar_type &>::type S( Q & a ) { return quat_traits<Q>::template write_element<0>(a); }
0169 template <class Q> BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value && quat_write_element_ref<Q>::value,typename quat_traits<Q>::scalar_type &>::type X( Q & a ) { return quat_traits<Q>::template write_element<1>(a); }
0170 template <class Q> BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value && quat_write_element_ref<Q>::value,typename quat_traits<Q>::scalar_type &>::type Y( Q & a ) { return quat_traits<Q>::template write_element<2>(a); }
0171 template <class Q> BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value && quat_write_element_ref<Q>::value,typename quat_traits<Q>::scalar_type &>::type Z( Q & a ) { return quat_traits<Q>::template write_element<3>(a); }
0172
0173 template <class Q> BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value && !quat_write_element_ref<Q>::value,qvm_detail::q_element_access<0,Q> &>::type S( Q & a ) { return *reinterpret_cast<qvm_detail::q_element_access<0, Q> *>(&a); }
0174 template <class Q> BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value && !quat_write_element_ref<Q>::value,qvm_detail::q_element_access<1,Q> &>::type X( Q & a ) { return *reinterpret_cast<qvm_detail::q_element_access<1, Q> *>(&a); }
0175 template <class Q> BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value && !quat_write_element_ref<Q>::value,qvm_detail::q_element_access<2,Q> &>::type Y( Q & a ) { return *reinterpret_cast<qvm_detail::q_element_access<2, Q> *>(&a); }
0176 template <class Q> BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL typename enable_if_c<is_quat<Q>::value && !quat_write_element_ref<Q>::value,qvm_detail::q_element_access<3,Q> &>::type Z( Q & a ) { return *reinterpret_cast<qvm_detail::q_element_access<3, Q> *>(&a); }
0177
0178 } }
0179
0180 #endif