size.hpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /**
  2. * \file size.hpp
  3. *
  4. * \brief The family of \c size operations.
  5. *
  6. * Copyright (c) 2009-2010, Marco Guazzone
  7. *
  8. * Distributed under the Boost Software License, Version 1.0. (See
  9. * accompanying file LICENSE_1_0.txt or copy at
  10. * http://www.boost.org/LICENSE_1_0.txt)
  11. *
  12. * \author Marco Guazzone, marco.guazzone@gmail.com
  13. */
  14. #ifndef BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
  15. #define BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
  16. #include <boost/mpl/has_xxx.hpp>
  17. #include <boost/mpl/if.hpp>
  18. #include <boost/numeric/ublas/detail/config.hpp>
  19. #include <boost/numeric/ublas/expression_types.hpp>
  20. #include <boost/numeric/ublas/fwd.hpp>
  21. #include <boost/numeric/ublas/tags.hpp>
  22. #include <boost/numeric/ublas/traits.hpp>
  23. #include <boost/utility/enable_if.hpp>
  24. #include <cstddef>
  25. namespace boost { namespace numeric { namespace ublas {
  26. namespace detail { namespace /*<unnamed>*/ {
  27. /// Define a \c has_size_type trait class.
  28. BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
  29. /**
  30. * \brief Wrapper type-traits used in \c boost::lazy_enabled_if for getting the
  31. * size type (see below).
  32. * \tparam VectorT A vector type.
  33. */
  34. template <typename VectorT>
  35. struct vector_size_type
  36. {
  37. /// The size type.
  38. typedef typename vector_traits<VectorT>::size_type type;
  39. };
  40. /**
  41. * \brief Wrapper type-traits used in \c boost::lazy_enabled_if for getting the
  42. * size type (see below).
  43. * \tparam MatrixT A matrix type.
  44. */
  45. template <typename MatrixT>
  46. struct matrix_size_type
  47. {
  48. /// The size type.
  49. typedef typename matrix_traits<MatrixT>::size_type type;
  50. };
  51. /**
  52. * \brief Auxiliary class for computing the size of the given dimension for
  53. * a container of the given category.
  54. * \tparam Dim The dimension number (starting from 1).
  55. * \tparam CategoryT The category type (e.g., vector_tag).
  56. */
  57. template <std::size_t Dim, typename CategoryT>
  58. struct size_by_dim_impl;
  59. /**
  60. * \brief Auxiliary class for computing the size of the given dimension for
  61. * a container of the given category and with the given orientation.
  62. * \tparam Dim The dimension number (starting from 1).
  63. * \tparam CategoryT The category type (e.g., vector_tag).
  64. * \tparam OrientationT The orientation category type (e.g., row_major_tag).
  65. */
  66. template <typename TagT, typename CategoryT, typename OrientationT>
  67. struct size_by_tag_impl;
  68. /**
  69. * \brief Specialization of \c size_by_dim_impl for computing the size of a
  70. * vector.
  71. */
  72. template <>
  73. struct size_by_dim_impl<1, vector_tag>
  74. {
  75. /**
  76. * \brief Compute the size of the given vector.
  77. * \tparam ExprT A vector expression type.
  78. * \pre ExprT must be a model of VectorExpression.
  79. */
  80. template <typename ExprT>
  81. BOOST_UBLAS_INLINE
  82. static typename vector_traits<ExprT>::size_type apply(vector_expression<ExprT> const& ve)
  83. {
  84. return ve().size();
  85. }
  86. };
  87. /**
  88. * \brief Specialization of \c size_by_dim_impl for computing the number of
  89. * rows of a matrix
  90. */
  91. template <>
  92. struct size_by_dim_impl<1, matrix_tag>
  93. {
  94. /**
  95. * \brief Compute the number of rows of the given matrix.
  96. * \tparam ExprT A matrix expression type.
  97. * \pre ExprT must be a model of MatrixExpression.
  98. */
  99. template <typename ExprT>
  100. BOOST_UBLAS_INLINE
  101. static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
  102. {
  103. return me().size1();
  104. }
  105. };
  106. /**
  107. * \brief Specialization of \c size_by_dim_impl for computing the number of
  108. * columns of a matrix
  109. */
  110. template <>
  111. struct size_by_dim_impl<2, matrix_tag>
  112. {
  113. /**
  114. * \brief Compute the number of columns of the given matrix.
  115. * \tparam ExprT A matrix expression type.
  116. * \pre ExprT must be a model of MatrixExpression.
  117. */
  118. template <typename ExprT>
  119. BOOST_UBLAS_INLINE
  120. static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
  121. {
  122. return me().size2();
  123. }
  124. };
  125. /**
  126. * \brief Specialization of \c size_by_tag_impl for computing the size of the
  127. * major dimension of a row-major oriented matrix.
  128. */
  129. template <>
  130. struct size_by_tag_impl<tag::major, matrix_tag, row_major_tag>
  131. {
  132. /**
  133. * \brief Compute the number of rows of the given matrix.
  134. * \tparam ExprT A matrix expression type.
  135. * \pre ExprT must be a model of MatrixExpression.
  136. */
  137. template <typename ExprT>
  138. BOOST_UBLAS_INLINE
  139. static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
  140. {
  141. return me().size1();
  142. }
  143. };
  144. /**
  145. * \brief Specialization of \c size_by_tag_impl for computing the size of the
  146. * minor dimension of a row-major oriented matrix.
  147. */
  148. template <>
  149. struct size_by_tag_impl<tag::minor, matrix_tag, row_major_tag>
  150. {
  151. /**
  152. * \brief Compute the number of columns of the given matrix.
  153. * \tparam ExprT A matrix expression type.
  154. * \pre ExprT must be a model of MatrixExpression.
  155. */
  156. template <typename ExprT>
  157. BOOST_UBLAS_INLINE
  158. static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
  159. {
  160. return me().size2();
  161. }
  162. };
  163. /**
  164. * \brief Specialization of \c size_by_tag_impl for computing the size of the
  165. * leading dimension of a row-major oriented matrix.
  166. */
  167. template <>
  168. struct size_by_tag_impl<tag::leading, matrix_tag, row_major_tag>
  169. {
  170. /**
  171. * \brief Compute the number of columns of the given matrix.
  172. * \tparam ExprT A matrix expression type.
  173. * \pre ExprT must be a model of MatrixExpression.
  174. */
  175. template <typename ExprT>
  176. BOOST_UBLAS_INLINE
  177. static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
  178. {
  179. return me().size2();
  180. }
  181. };
  182. /// \brief Specialization of \c size_by_tag_impl for computing the size of the
  183. /// major dimension of a column-major oriented matrix.
  184. template <>
  185. struct size_by_tag_impl<tag::major, matrix_tag, column_major_tag>
  186. {
  187. /**
  188. * \brief Compute the number of columns of the given matrix.
  189. * \tparam ExprT A matrix expression type.
  190. * \pre ExprT must be a model of MatrixExpression.
  191. */
  192. template <typename ExprT>
  193. BOOST_UBLAS_INLINE
  194. static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
  195. {
  196. return me().size2();
  197. }
  198. };
  199. /// \brief Specialization of \c size_by_tag_impl for computing the size of the
  200. /// minor dimension of a column-major oriented matrix.
  201. template <>
  202. struct size_by_tag_impl<tag::minor, matrix_tag, column_major_tag>
  203. {
  204. /**
  205. * \brief Compute the number of rows of the given matrix.
  206. * \tparam ExprT A matrix expression type.
  207. * \pre ExprT must be a model of MatrixExpression.
  208. */
  209. template <typename ExprT>
  210. BOOST_UBLAS_INLINE
  211. static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
  212. {
  213. return me().size1();
  214. }
  215. };
  216. /// \brief Specialization of \c size_by_tag_impl for computing the size of the
  217. /// leading dimension of a column-major oriented matrix.
  218. template <>
  219. struct size_by_tag_impl<tag::leading, matrix_tag, column_major_tag>
  220. {
  221. /**
  222. * \brief Compute the number of rows of the given matrix.
  223. * \tparam ExprT A matrix expression type.
  224. * \pre ExprT must be a model of MatrixExpression.
  225. */
  226. template <typename ExprT>
  227. BOOST_UBLAS_INLINE
  228. static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
  229. {
  230. return me().size1();
  231. }
  232. };
  233. /// \brief Specialization of \c size_by_tag_impl for computing the size of the
  234. /// given dimension of a unknown oriented expression.
  235. template <typename TagT, typename CategoryT>
  236. struct size_by_tag_impl<TagT, CategoryT, unknown_orientation_tag>: size_by_tag_impl<TagT, CategoryT, row_major_tag>
  237. {
  238. // Empty
  239. };
  240. }} // Namespace detail::<unnamed>
  241. /**
  242. * \brief Return the number of columns.
  243. * \tparam VectorExprT A type which models the vector expression concept.
  244. * \param ve A vector expression.
  245. * \return The length of the input vector expression.
  246. */
  247. template <typename VectorExprT>
  248. BOOST_UBLAS_INLINE
  249. typename ::boost::lazy_enable_if_c<
  250. detail::has_size_type<VectorExprT>::value,
  251. detail::vector_size_type<VectorExprT>
  252. >::type size(vector_expression<VectorExprT> const& ve)
  253. {
  254. return ve().size();
  255. }
  256. /**
  257. * \brief Return the size of the given dimension for the given vector
  258. * expression.
  259. * \tparam Dim The dimension number (starting from 1).
  260. * \tparam VectorExprT A vector expression type.
  261. * \param ve A vector expression.
  262. * \return The length of the input vector expression.
  263. */
  264. template <std::size_t Dim, typename VectorExprT>
  265. BOOST_UBLAS_INLINE
  266. typename vector_traits<VectorExprT>::size_type size(vector_expression<VectorExprT> const& ve)
  267. {
  268. return detail::size_by_dim_impl<Dim, vector_tag>::apply(ve);
  269. }
  270. /**
  271. * \brief Return the size of the given dimension for the given matrix
  272. * expression.
  273. * \tparam Dim The dimension number (starting from 1).
  274. * \tparam MatrixExprT A matrix expression type.
  275. * \param e A matrix expression.
  276. * \return The size of the input matrix expression associated to the dimension
  277. * \a Dim.
  278. */
  279. template <std::size_t Dim, typename MatrixExprT>
  280. BOOST_UBLAS_INLINE
  281. typename matrix_traits<MatrixExprT>::size_type size(matrix_expression<MatrixExprT> const& me)
  282. {
  283. return detail::size_by_dim_impl<Dim, matrix_tag>::apply(me);
  284. }
  285. /**
  286. * \brief Return the size of the given dimension tag for the given matrix
  287. * expression.
  288. * \tparam TagT The dimension tag type (e.g., tag::major).
  289. * \tparam MatrixExprT A matrix expression type.
  290. * \param e A matrix expression.
  291. * \return The size of the input matrix expression associated to the dimension
  292. * tag \a TagT.
  293. */
  294. template <typename TagT, typename MatrixExprT>
  295. BOOST_UBLAS_INLINE
  296. typename ::boost::lazy_enable_if_c<
  297. detail::has_size_type<MatrixExprT>::value,
  298. detail::matrix_size_type<MatrixExprT>
  299. >::type size(matrix_expression<MatrixExprT> const& me)
  300. {
  301. return detail::size_by_tag_impl<TagT, matrix_tag, typename matrix_traits<MatrixExprT>::orientation_category>::apply(me);
  302. }
  303. }}} // Namespace boost::numeric::ublas
  304. #endif // BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP