mat_traits_array.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #ifndef BOOST_QVM_MAT_TRAITS_ARRAY_HPP_INCLUDED
  2. #define BOOST_QVM_MAT_TRAITS_ARRAY_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/deduce_mat.hpp>
  8. #include <boost/qvm/assert.hpp>
  9. #if __cplusplus > 199711L
  10. #include <array>
  11. namespace boost { namespace qvm {
  12. template <class T,std::size_t R,std::size_t Q,std::size_t C>
  13. struct
  14. mat_traits<std::array<std::array<std::array<T,R>,Q>,C> >
  15. {
  16. static int const rows=0;
  17. static int const cols=0;
  18. typedef void scalar_type;
  19. };
  20. template <class T,std::size_t Rows,std::size_t Cols>
  21. struct
  22. mat_traits<std::array<std::array<T,Rows>,Cols> >
  23. {
  24. typedef std::array<std::array<T,Rows>,Cols> this_matrix;
  25. typedef T scalar_type;
  26. static int const rows=Rows;
  27. static int const cols=Cols;
  28. template <int Row,int Col>
  29. static
  30. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  31. scalar_type
  32. read_element( this_matrix const & x )
  33. {
  34. BOOST_QVM_STATIC_ASSERT(Row>=0);
  35. BOOST_QVM_STATIC_ASSERT(Row<rows);
  36. BOOST_QVM_STATIC_ASSERT(Col>=0);
  37. BOOST_QVM_STATIC_ASSERT(Col<cols);
  38. return x[Row][Col];
  39. }
  40. template <int Row,int Col>
  41. static
  42. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  43. scalar_type &
  44. write_element( this_matrix & x )
  45. {
  46. BOOST_QVM_STATIC_ASSERT(Row>=0);
  47. BOOST_QVM_STATIC_ASSERT(Row<rows);
  48. BOOST_QVM_STATIC_ASSERT(Col>=0);
  49. BOOST_QVM_STATIC_ASSERT(Col<cols);
  50. return x[Row][Col];
  51. }
  52. static
  53. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  54. scalar_type
  55. read_element_idx( int row, int col, this_matrix const & x )
  56. {
  57. BOOST_QVM_ASSERT(row>=0);
  58. BOOST_QVM_ASSERT(row<rows);
  59. BOOST_QVM_ASSERT(col>=0);
  60. BOOST_QVM_ASSERT(col<cols);
  61. return x[row][col];
  62. }
  63. static
  64. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  65. scalar_type &
  66. write_element_idx( int row, int col, this_matrix & x )
  67. {
  68. BOOST_QVM_ASSERT(row>=0);
  69. BOOST_QVM_ASSERT(row<rows);
  70. BOOST_QVM_ASSERT(col>=0);
  71. BOOST_QVM_ASSERT(col<cols);
  72. return x[row][col];
  73. }
  74. };
  75. template <class T,std::size_t Rows,std::size_t Cols>
  76. struct
  77. mat_traits<std::array<std::array<T,Rows>,Cols> const>
  78. {
  79. typedef std::array<std::array<T,Rows>,Cols> const this_matrix;
  80. typedef T scalar_type;
  81. static int const rows=Rows;
  82. static int const cols=Cols;
  83. template <int Row,int Col>
  84. static
  85. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  86. scalar_type
  87. read_element( this_matrix & x )
  88. {
  89. BOOST_QVM_STATIC_ASSERT(Row>=0);
  90. BOOST_QVM_STATIC_ASSERT(Row<rows);
  91. BOOST_QVM_STATIC_ASSERT(Col>=0);
  92. BOOST_QVM_STATIC_ASSERT(Col<cols);
  93. return x[Row][Col];
  94. }
  95. static
  96. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  97. scalar_type
  98. read_element_idx( int row, int col, this_matrix & x )
  99. {
  100. BOOST_QVM_ASSERT(row>=0);
  101. BOOST_QVM_ASSERT(row<rows);
  102. BOOST_QVM_ASSERT(col>=0);
  103. BOOST_QVM_ASSERT(col<cols);
  104. return x[row][col];
  105. }
  106. };
  107. template <class T,std::size_t Rows,std::size_t Cols,int R,int C>
  108. struct
  109. deduce_mat<std::array<std::array<T,Rows>,Cols>,R,C>
  110. {
  111. typedef mat<T,R,C> type;
  112. };
  113. template <class T,std::size_t Rows,std::size_t Cols,int R,int C>
  114. struct
  115. deduce_mat<std::array<std::array<T,Rows>,Cols> const,R,C>
  116. {
  117. typedef mat<T,R,C> type;
  118. };
  119. template <class T1,class T2,std::size_t Rows,std::size_t Cols,int R,int C>
  120. struct
  121. deduce_mat2<std::array<std::array<T1,Rows>,Cols>,std::array<std::array<T2,Rows>,Cols>,R,C>
  122. {
  123. typedef mat<typename deduce_scalar<T1,T2>::type,R,C> type;
  124. };
  125. template <class T1,class T2,std::size_t Rows,std::size_t Cols,int R,int C>
  126. struct
  127. deduce_mat2<std::array<std::array<T1,Rows>,Cols> const,std::array<std::array<T2,Rows>,Cols>,R,C>
  128. {
  129. typedef mat<typename deduce_scalar<T1,T2>::type,R,C> type;
  130. };
  131. template <class T1,class T2,std::size_t Rows,std::size_t Cols,int R,int C>
  132. struct
  133. deduce_mat2<std::array<std::array<T1,Rows>,Cols>,std::array<std::array<T2,Rows> const,Cols>,R,C>
  134. {
  135. typedef mat<typename deduce_scalar<T1,T2>::type,R,C> type;
  136. };
  137. template <class T1,class T2,std::size_t Rows,std::size_t Cols,int R,int C>
  138. struct
  139. deduce_mat2<std::array<std::array<T1,Rows>,Cols> const,std::array<std::array<T2,Rows>,Cols> const,R,C>
  140. {
  141. typedef mat<typename deduce_scalar<T1,T2>::type,R,C> type;
  142. };
  143. } }
  144. #endif
  145. namespace boost { namespace qvm {
  146. template <class T,int R,int Q,int C>
  147. struct
  148. mat_traits<T[R][Q][C]>
  149. {
  150. static int const rows=0;
  151. static int const cols=0;
  152. typedef void scalar_type;
  153. };
  154. template <class T,int Rows,int Cols>
  155. struct
  156. mat_traits<T[Rows][Cols]>
  157. {
  158. typedef T this_matrix[Rows][Cols];
  159. typedef T scalar_type;
  160. static int const rows=Rows;
  161. static int const cols=Cols;
  162. template <int Row,int Col>
  163. static
  164. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  165. scalar_type
  166. read_element( this_matrix const & x )
  167. {
  168. BOOST_QVM_STATIC_ASSERT(Row>=0);
  169. BOOST_QVM_STATIC_ASSERT(Row<rows);
  170. BOOST_QVM_STATIC_ASSERT(Col>=0);
  171. BOOST_QVM_STATIC_ASSERT(Col<cols);
  172. return x[Row][Col];
  173. }
  174. template <int Row,int Col>
  175. static
  176. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  177. scalar_type &
  178. write_element( this_matrix & x )
  179. {
  180. BOOST_QVM_STATIC_ASSERT(Row>=0);
  181. BOOST_QVM_STATIC_ASSERT(Row<rows);
  182. BOOST_QVM_STATIC_ASSERT(Col>=0);
  183. BOOST_QVM_STATIC_ASSERT(Col<cols);
  184. return x[Row][Col];
  185. }
  186. static
  187. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  188. scalar_type
  189. read_element_idx( int row, int col, this_matrix const & x )
  190. {
  191. BOOST_QVM_ASSERT(row>=0);
  192. BOOST_QVM_ASSERT(row<Rows);
  193. BOOST_QVM_ASSERT(col>=0);
  194. BOOST_QVM_ASSERT(col<Cols);
  195. return x[row][col];
  196. }
  197. static
  198. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
  199. scalar_type &
  200. write_element_idx( int row, int col, this_matrix & x )
  201. {
  202. BOOST_QVM_ASSERT(row>=0);
  203. BOOST_QVM_ASSERT(row<Rows);
  204. BOOST_QVM_ASSERT(col>=0);
  205. BOOST_QVM_ASSERT(col<Cols);
  206. return x[row][col];
  207. }
  208. };
  209. template <class T,int Rows,int Cols,int R,int C>
  210. struct
  211. deduce_mat<T[Rows][Cols],R,C>
  212. {
  213. typedef mat<T,R,C> type;
  214. };
  215. template <class T,int Rows,int Cols,int R,int C>
  216. struct
  217. deduce_mat<T const[Rows][Cols],R,C>
  218. {
  219. typedef mat<T,R,C> type;
  220. };
  221. template <class T1,class T2,int Rows,int Cols,int R,int C>
  222. struct
  223. deduce_mat2<T1[Rows][Cols],T2[Rows][Cols],R,C>
  224. {
  225. typedef mat<typename deduce_scalar<T1,T2>::type,R,C> type;
  226. };
  227. template <int Rows,int Cols,class T>
  228. T (&ptr_mref( T * ptr ))[Rows][Cols]
  229. {
  230. return *reinterpret_cast<T (*)[Rows][Cols]>(ptr);
  231. }
  232. } }
  233. #endif