quat_access.hpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #ifndef BOOST_QVM_QUAT_ACCESS_HPP_INCLUDED
  2. #define BOOST_QVM_QUAT_ACCESS_HPP_INCLUDED
  3. // Copyright 2008-2022 Emil Dotchevski and Reverge Studios, Inc.
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/qvm/config.hpp>
  7. #include <boost/qvm/quat_traits.hpp>
  8. #include <boost/qvm/deduce_vec.hpp>
  9. #include <boost/qvm/static_assert.hpp>
  10. #include <boost/qvm/enable_if.hpp>
  11. namespace boost { namespace qvm {
  12. 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); }
  13. 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); }
  14. 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); }
  15. 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); }
  16. namespace
  17. qvm_detail
  18. {
  19. template <int I,class Q>
  20. struct
  21. q_element_access
  22. {
  23. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  24. void
  25. operator=( typename quat_traits<Q>::scalar_type s )
  26. {
  27. quat_traits<Q>::template write_element<I>(*reinterpret_cast<Q *>(this), s);
  28. }
  29. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  30. operator typename vec_traits<Q>::scalar_type() const
  31. {
  32. return quat_traits<Q>::template read_element<I>(*reinterpret_cast<Q const *>(this));
  33. }
  34. };
  35. template <class Q>
  36. struct
  37. quat_v_
  38. {
  39. template <class R
  40. #if __cplusplus >= 201103L
  41. , class = typename enable_if<is_vec<R> >::type
  42. #endif
  43. >
  44. operator R() const
  45. {
  46. R r;
  47. assign(r,*this);
  48. return r;
  49. }
  50. private:
  51. quat_v_( quat_v_ const & );
  52. quat_v_ const & operator=( quat_v_ const & );
  53. ~quat_v_();
  54. };
  55. template <class Q,bool WriteElementRef=quat_write_element_ref<Q>::value>
  56. struct quat_v_write_traits;
  57. template <class Q>
  58. struct
  59. quat_v_write_traits<Q,true>
  60. {
  61. typedef qvm_detail::quat_v_<Q> this_vector;
  62. typedef typename quat_traits<Q>::scalar_type scalar_type;
  63. static int const dim=3;
  64. template <int I>
  65. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  66. static
  67. scalar_type &
  68. write_element( this_vector & q )
  69. {
  70. BOOST_QVM_STATIC_ASSERT(I>=0);
  71. BOOST_QVM_STATIC_ASSERT(I<dim);
  72. return quat_traits<Q>::template write_element<I+1>( reinterpret_cast<Q &>(q) );
  73. }
  74. };
  75. template <class Q>
  76. struct
  77. quat_v_write_traits<Q,false>
  78. {
  79. typedef qvm_detail::quat_v_<Q> this_vector;
  80. typedef typename quat_traits<Q>::scalar_type scalar_type;
  81. static int const dim=3;
  82. template <int I>
  83. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  84. static
  85. void
  86. write_element( this_vector & q, scalar_type s )
  87. {
  88. BOOST_QVM_STATIC_ASSERT(I>=0);
  89. BOOST_QVM_STATIC_ASSERT(I<dim);
  90. quat_traits<Q>::template write_element<I+1>( reinterpret_cast<Q &>(q), s );
  91. }
  92. };
  93. }
  94. template <class V>
  95. struct vec_traits;
  96. template <class Q>
  97. struct
  98. vec_traits< qvm_detail::quat_v_<Q> >:
  99. qvm_detail::quat_v_write_traits<Q>
  100. {
  101. typedef qvm_detail::quat_v_<Q> this_vector;
  102. typedef typename quat_traits<Q>::scalar_type scalar_type;
  103. static int const dim=3;
  104. template <int I>
  105. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  106. static
  107. scalar_type
  108. read_element( this_vector const & q )
  109. {
  110. BOOST_QVM_STATIC_ASSERT(I>=0);
  111. BOOST_QVM_STATIC_ASSERT(I<dim);
  112. return quat_traits<Q>::template read_element<I+1>( reinterpret_cast<Q const &>(q) );
  113. }
  114. };
  115. template <class Q,int D>
  116. struct
  117. deduce_vec<qvm_detail::quat_v_<Q>,D>
  118. {
  119. typedef vec<typename quat_traits<Q>::scalar_type,D> type;
  120. };
  121. template <class Q,int D>
  122. struct
  123. deduce_vec2<qvm_detail::quat_v_<Q>,qvm_detail::quat_v_<Q>,D>
  124. {
  125. typedef vec<typename quat_traits<Q>::scalar_type,D> type;
  126. };
  127. template <class Q>
  128. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  129. typename enable_if_c<
  130. is_quat<Q>::value,
  131. qvm_detail::quat_v_<Q> const &>::type
  132. V( Q const & a )
  133. {
  134. return reinterpret_cast<qvm_detail::quat_v_<Q> const &>(a);
  135. }
  136. template <class Q>
  137. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
  138. typename enable_if_c<
  139. is_quat<Q>::value,
  140. qvm_detail::quat_v_<Q> &>::type
  141. V( Q & a )
  142. {
  143. return reinterpret_cast<qvm_detail::quat_v_<Q> &>(a);
  144. }
  145. 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); }
  146. 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); }
  147. 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); }
  148. 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); }
  149. 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); }
  150. 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); }
  151. 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); }
  152. 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); }
  153. } }
  154. #endif