vec_register_impl.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
  2. //Copyright (c) 2018 agate-pris
  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. #ifndef BOOST_QVM_DETAIL_VEC_REGISTER_IMPL_HPP
  6. #define BOOST_QVM_DETAIL_VEC_REGISTER_IMPL_HPP
  7. #include <boost/qvm/assert.hpp>
  8. #include <boost/qvm/inline.hpp>
  9. #include <boost/qvm/static_assert.hpp>
  10. #include <boost/qvm/vec_traits.hpp>
  11. namespace boost { namespace qvm { namespace qvm_detail {
  12. template<class VecType, class ScalarType, int Dim>
  13. struct vec_register_common
  14. {
  15. typedef VecType vec_type;
  16. typedef ScalarType scalar_type;
  17. static int const dim = Dim;
  18. };
  19. template<class VecType, class ScalarType, int Dim>
  20. struct vec_register_read
  21. {
  22. template<int I> static ScalarType read_element(VecType const& v);
  23. template<int I, int N> struct read_element_idx_detail
  24. {
  25. static BOOST_QVM_INLINE_CRITICAL ScalarType impl(int const i, VecType const& v)
  26. {
  27. return I == i
  28. ? read_element<I>(v)
  29. : read_element_idx_detail<I + 1, N>::impl(i, v);
  30. }
  31. };
  32. template<int N> struct read_element_idx_detail<N, N>
  33. {
  34. static BOOST_QVM_INLINE_TRIVIAL ScalarType impl(int, VecType const& v)
  35. {
  36. BOOST_QVM_ASSERT(0);
  37. return read_element<0>(v);
  38. }
  39. };
  40. static BOOST_QVM_INLINE_CRITICAL ScalarType read_element_idx(int const i, VecType const& v)
  41. {
  42. return read_element_idx_detail<0, Dim>::impl(i, v);
  43. }
  44. };
  45. template<class VecType, class ScalarType, int Dim>
  46. struct vec_register_write
  47. {
  48. template<int I> static ScalarType& write_element(VecType& v);
  49. template<int I, int N> struct write_element_idx_detail
  50. {
  51. static BOOST_QVM_INLINE_CRITICAL ScalarType& impl(int const i, VecType& v)
  52. {
  53. return I == i
  54. ? write_element<I>(v)
  55. : write_element_idx_detail<I + 1, N>::impl(i, v);
  56. }
  57. };
  58. template<int N> struct write_element_idx_detail<N, N>
  59. {
  60. static BOOST_QVM_INLINE_TRIVIAL ScalarType& impl(int, VecType& v)
  61. {
  62. BOOST_QVM_ASSERT(0);
  63. return write_element<0>(v);
  64. }
  65. };
  66. static BOOST_QVM_INLINE_CRITICAL ScalarType& write_element_idx(int const i, VecType& v)
  67. {
  68. return write_element_idx_detail<0, Dim>::impl(i, v);
  69. }
  70. };
  71. }}}
  72. #define BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_READ(VecType, ScalarType, Dim, I, Read) \
  73. namespace boost { namespace qvm {namespace qvm_detail{ \
  74. template<> \
  75. template<> \
  76. BOOST_QVM_INLINE_CRITICAL \
  77. ScalarType vec_register_read<VecType, ScalarType, Dim>::read_element<I>(VecType const& v) \
  78. { \
  79. BOOST_QVM_STATIC_ASSERT(I>=0); \
  80. BOOST_QVM_STATIC_ASSERT(I<Dim); \
  81. return v. Read; \
  82. } \
  83. }}}
  84. #define BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_WRITE(VecType, ScalarType, Dim, I, Write) \
  85. namespace boost { namespace qvm {namespace qvm_detail{ \
  86. template<> \
  87. template<> \
  88. BOOST_QVM_INLINE_CRITICAL \
  89. ScalarType& vec_register_write<VecType, ScalarType, Dim>::write_element<I>(VecType& v) \
  90. { \
  91. BOOST_QVM_STATIC_ASSERT(I>=0); \
  92. BOOST_QVM_STATIC_ASSERT(I<Dim); \
  93. return v. Write; \
  94. }; \
  95. }}}
  96. #define BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_READ_WRITE(VecType, ScalarType, Dim, I, Read, Write)\
  97. BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_READ(VecType, ScalarType, Dim, I, Read) \
  98. BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_WRITE(VecType, ScalarType, Dim, I, Write)
  99. #define BOOST_QVM_DETAIL_REGISTER_VEC_SPECIALIZE_VEC_TRAITS_READ(VecType, ScalarType, Dim) \
  100. namespace boost { namespace qvm { \
  101. template<> \
  102. struct vec_traits<VecType> \
  103. : qvm_detail::vec_register_common<VecType, ScalarType, Dim> \
  104. , qvm_detail::vec_register_read<VecType, ScalarType, Dim> \
  105. { \
  106. }; \
  107. }}
  108. #define BOOST_QVM_DETAIL_REGISTER_VEC_SPECIALIZE_VEC_TRAITS_READ_WRITE(VecType, ScalarType, Dim)\
  109. namespace boost { namespace qvm { \
  110. template<> \
  111. struct vec_traits<VecType> \
  112. : qvm_detail::vec_register_common<VecType, ScalarType, Dim> \
  113. , qvm_detail::vec_register_read<VecType, ScalarType, Dim> \
  114. , qvm_detail::vec_register_write<VecType, ScalarType, Dim> \
  115. { \
  116. }; \
  117. }}
  118. #endif