4 * \brief The family of \c size operations.
6 * Copyright (c) 2009-2010, Marco Guazzone
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)
12 * \author Marco Guazzone, marco.guazzone@gmail.com
15 #ifndef BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
16 #define BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
19 #include <boost/mpl/has_xxx.hpp>
20 #include <boost/mpl/if.hpp>
21 #include <boost/numeric/ublas/detail/config.hpp>
22 #include <boost/numeric/ublas/expression_types.hpp>
23 #include <boost/numeric/ublas/fwd.hpp>
24 #include <boost/numeric/ublas/tags.hpp>
25 #include <boost/numeric/ublas/traits.hpp>
26 #include <boost/utility/enable_if.hpp>
30 namespace boost { namespace numeric { namespace ublas {
32 namespace detail { namespace /*<unnamed>*/ {
34 /// Define a \c has_size_type trait class.
35 BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
39 * \brief Wrapper type-traits used in \c boost::lazy_enabled_if for getting the
40 * size type (see below).
41 * \tparam VectorT A vector type.
43 template <typename VectorT>
44 struct vector_size_type
47 typedef typename vector_traits<VectorT>::size_type type;
51 * \brief Wrapper type-traits used in \c boost::lazy_enabled_if for getting the
52 * size type (see below).
53 * \tparam MatrixT A matrix type.
55 template <typename MatrixT>
56 struct matrix_size_type
59 typedef typename matrix_traits<MatrixT>::size_type type;
64 * \brief Auxiliary class for computing the size of the given dimension for
65 * a container of the given category.
66 * \tparam Dim The dimension number (starting from 1).
67 * \tparam CategoryT The category type (e.g., vector_tag).
69 template <std::size_t Dim, typename CategoryT>
70 struct size_by_dim_impl;
74 * \brief Auxiliary class for computing the size of the given dimension for
75 * a container of the given category and with the given orientation.
76 * \tparam Dim The dimension number (starting from 1).
77 * \tparam CategoryT The category type (e.g., vector_tag).
78 * \tparam OrientationT The orientation category type (e.g., row_major_tag).
80 template <typename TagT, typename CategoryT, typename OrientationT>
81 struct size_by_tag_impl;
85 * \brief Specialization of \c size_by_dim_impl for computing the size of a
89 struct size_by_dim_impl<1, vector_tag>
92 * \brief Compute the size of the given vector.
93 * \tparam ExprT A vector expression type.
94 * \pre ExprT must be a model of VectorExpression.
96 template <typename ExprT>
98 static typename vector_traits<ExprT>::size_type apply(vector_expression<ExprT> const& ve)
106 * \brief Specialization of \c size_by_dim_impl for computing the number of
110 struct size_by_dim_impl<1, matrix_tag>
113 * \brief Compute the number of rows of the given matrix.
114 * \tparam ExprT A matrix expression type.
115 * \pre ExprT must be a model of MatrixExpression.
117 template <typename ExprT>
119 static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
127 * \brief Specialization of \c size_by_dim_impl for computing the number of
128 * columns of a matrix
131 struct size_by_dim_impl<2, matrix_tag>
134 * \brief Compute the number of columns of the given matrix.
135 * \tparam ExprT A matrix expression type.
136 * \pre ExprT must be a model of MatrixExpression.
138 template <typename ExprT>
140 static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
148 * \brief Specialization of \c size_by_tag_impl for computing the size of the
149 * major dimension of a row-major oriented matrix.
152 struct size_by_tag_impl<tag::major, matrix_tag, row_major_tag>
155 * \brief Compute the number of rows of the given matrix.
156 * \tparam ExprT A matrix expression type.
157 * \pre ExprT must be a model of MatrixExpression.
159 template <typename ExprT>
161 static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
169 * \brief Specialization of \c size_by_tag_impl for computing the size of the
170 * minor dimension of a row-major oriented matrix.
173 struct size_by_tag_impl<tag::minor, matrix_tag, row_major_tag>
176 * \brief Compute the number of columns of the given matrix.
177 * \tparam ExprT A matrix expression type.
178 * \pre ExprT must be a model of MatrixExpression.
180 template <typename ExprT>
182 static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
190 * \brief Specialization of \c size_by_tag_impl for computing the size of the
191 * leading dimension of a row-major oriented matrix.
194 struct size_by_tag_impl<tag::leading, matrix_tag, row_major_tag>
197 * \brief Compute the number of columns of the given matrix.
198 * \tparam ExprT A matrix expression type.
199 * \pre ExprT must be a model of MatrixExpression.
201 template <typename ExprT>
203 static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
210 /// \brief Specialization of \c size_by_tag_impl for computing the size of the
211 /// major dimension of a column-major oriented matrix.
213 struct size_by_tag_impl<tag::major, matrix_tag, column_major_tag>
216 * \brief Compute the number of columns of the given matrix.
217 * \tparam ExprT A matrix expression type.
218 * \pre ExprT must be a model of MatrixExpression.
220 template <typename ExprT>
222 static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
229 /// \brief Specialization of \c size_by_tag_impl for computing the size of the
230 /// minor dimension of a column-major oriented matrix.
232 struct size_by_tag_impl<tag::minor, matrix_tag, column_major_tag>
235 * \brief Compute the number of rows of the given matrix.
236 * \tparam ExprT A matrix expression type.
237 * \pre ExprT must be a model of MatrixExpression.
239 template <typename ExprT>
241 static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
248 /// \brief Specialization of \c size_by_tag_impl for computing the size of the
249 /// leading dimension of a column-major oriented matrix.
251 struct size_by_tag_impl<tag::leading, matrix_tag, column_major_tag>
254 * \brief Compute the number of rows of the given matrix.
255 * \tparam ExprT A matrix expression type.
256 * \pre ExprT must be a model of MatrixExpression.
258 template <typename ExprT>
260 static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
267 /// \brief Specialization of \c size_by_tag_impl for computing the size of the
268 /// given dimension of a unknown oriented expression.
269 template <typename TagT, typename CategoryT>
270 struct size_by_tag_impl<TagT, CategoryT, unknown_orientation_tag>: size_by_tag_impl<TagT, CategoryT, row_major_tag>
275 }} // Namespace detail::<unnamed>
279 * \brief Return the number of columns.
280 * \tparam VectorExprT A type which models the vector expression concept.
281 * \param ve A vector expression.
282 * \return The length of the input vector expression.
284 template <typename VectorExprT>
286 typename ::boost::lazy_enable_if_c<
287 detail::has_size_type<VectorExprT>::value,
288 detail::vector_size_type<VectorExprT>
289 >::type size(vector_expression<VectorExprT> const& ve)
296 * \brief Return the size of the given dimension for the given vector
298 * \tparam Dim The dimension number (starting from 1).
299 * \tparam VectorExprT A vector expression type.
300 * \param ve A vector expression.
301 * \return The length of the input vector expression.
303 template <std::size_t Dim, typename VectorExprT>
305 typename vector_traits<VectorExprT>::size_type size(vector_expression<VectorExprT> const& ve)
307 return detail::size_by_dim_impl<Dim, vector_tag>::apply(ve);
312 * \brief Return the size of the given dimension for the given matrix
314 * \tparam Dim The dimension number (starting from 1).
315 * \tparam MatrixExprT A matrix expression type.
316 * \param e A matrix expression.
317 * \return The size of the input matrix expression associated to the dimension
320 template <std::size_t Dim, typename MatrixExprT>
322 typename matrix_traits<MatrixExprT>::size_type size(matrix_expression<MatrixExprT> const& me)
324 return detail::size_by_dim_impl<Dim, matrix_tag>::apply(me);
329 * \brief Return the size of the given dimension tag for the given matrix
331 * \tparam TagT The dimension tag type (e.g., tag::major).
332 * \tparam MatrixExprT A matrix expression type.
333 * \param e A matrix expression.
334 * \return The size of the input matrix expression associated to the dimension
337 template <typename TagT, typename MatrixExprT>
339 typename ::boost::lazy_enable_if_c<
340 detail::has_size_type<MatrixExprT>::value,
341 detail::matrix_size_type<MatrixExprT>
342 >::type size(matrix_expression<MatrixExprT> const& me)
344 return detail::size_by_tag_impl<TagT, matrix_tag, typename matrix_traits<MatrixExprT>::orientation_category>::apply(me);
347 }}} // Namespace boost::numeric::ublas
350 #endif // BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP