Ticket #4399: size-allow_expr.patch

File size-allow_expr.patch, 18.7 KB (added by Marco Guazzone <marco.guazzone@…>, 12 years ago)

Patch for size.hpp which is back compatible.

  • boost/numeric/ublas/operation/size.hpp

    diff -Naur /old/boost/numeric/ublas/operation/size.hpp /new/boost/numeric/ublas/operation/size.hpp
    old new  
    11/**
    2  * -*- c++ -*-
    3  *
    42 * \file size.hpp
    53 *
    6  * \brief The \c size operation.
     4 * \brief The family of \c size operations.
    75 *
    8  * Copyright (c) 2009, Marco Guazzone
     6 * Copyright (c) 2009-2010, Marco Guazzone
    97 *
    108 * Distributed under the Boost Software License, Version 1.0. (See
    119 * accompanying file LICENSE_1_0.txt or copy at
     
    1816#define BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
    1917
    2018
     19#include <boost/mpl/has_xxx.hpp>
     20#include <boost/mpl/if.hpp>
    2121#include <boost/numeric/ublas/detail/config.hpp>
    2222#include <boost/numeric/ublas/expression_types.hpp>
    2323#include <boost/numeric/ublas/fwd.hpp>
    2424#include <boost/numeric/ublas/tags.hpp>
     25#include <boost/numeric/ublas/traits.hpp>
     26#include <boost/utility/enable_if.hpp>
    2527#include <cstddef>
    2628
    2729
    2830namespace boost { namespace numeric { namespace ublas {
    2931
    30     namespace detail {
     32namespace detail { namespace /*<unnamed>*/ {
     33
     34/// Define a \c has_size_type trait class.
     35BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
     36
     37
     38/**
     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.
     42 */
     43template <typename VectorT>
     44struct vector_size_type
     45{
     46    /// The size type.
     47    typedef typename vector_traits<VectorT>::size_type type;
     48};
     49
     50/**
     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.
     54 */
     55template <typename MatrixT>
     56struct matrix_size_type
     57{
     58    /// The size type.
     59    typedef typename matrix_traits<MatrixT>::size_type type;
     60};
     61
     62
     63/**
     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).
     68 */
     69template <std::size_t Dim, typename CategoryT>
     70struct size_by_dim_impl;
     71
     72
     73/**
     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).
     79 */
     80template <typename TagT, typename CategoryT, typename OrientationT>
     81struct size_by_tag_impl;
     82
     83
     84/**
     85 * \brief Specialization of \c size_by_dim_impl for computing the size of a
     86 *  vector.
     87 */
     88template <>
     89struct size_by_dim_impl<1, vector_tag>
     90{
     91    /**
     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.
     95     */
     96    template <typename ExprT>
     97    BOOST_UBLAS_INLINE
     98    static typename vector_traits<ExprT>::size_type apply(vector_expression<ExprT> const& ve)
     99    {
     100        return ve().size();
     101    }
     102};
     103
     104
     105/**
     106 * \brief Specialization of \c size_by_dim_impl for computing the number of
     107 *  rows of a matrix
     108 */
     109template <>
     110struct size_by_dim_impl<1, matrix_tag>
     111{
     112    /**
     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.
     116     */
     117    template <typename ExprT>
     118    BOOST_UBLAS_INLINE
     119    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
     120    {
     121        return me().size1();
     122    }
     123};
     124
     125
     126/**
     127 * \brief Specialization of \c size_by_dim_impl for computing the number of
     128 *  columns of a matrix
     129 */
     130template <>
     131struct size_by_dim_impl<2, matrix_tag>
     132{
     133    /**
     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.
     137     */
     138    template <typename ExprT>
     139    BOOST_UBLAS_INLINE
     140    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
     141    {
     142        return me().size2();
     143    }
     144};
     145
     146
     147/**
     148 * \brief Specialization of \c size_by_tag_impl for computing the size of the
     149 *  major dimension of a row-major oriented matrix.
     150 */
     151template <>
     152struct size_by_tag_impl<tag::major, matrix_tag, row_major_tag>
     153{
     154    /**
     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.
     158     */
     159    template <typename ExprT>
     160    BOOST_UBLAS_INLINE
     161    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
     162    {
     163        return me().size1();
     164    }
     165};
     166
     167
     168/**
     169 * \brief Specialization of \c size_by_tag_impl for computing the size of the
     170 *  minor dimension of a row-major oriented matrix.
     171 */
     172template <>
     173struct size_by_tag_impl<tag::minor, matrix_tag, row_major_tag>
     174{
     175    /**
     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.
     179     */
     180    template <typename ExprT>
     181    BOOST_UBLAS_INLINE
     182    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
     183    {
     184        return me().size2();
     185    }
     186};
    31187
    32         /**
    33          * \brief Auxiliary class for computing the size of the given dimension for
    34          *  a container of the given category..
    35          * \tparam Dim The dimension number (starting from 1).
    36          * \tparam CategoryT The category type (e.g., vector_tag).
    37          */
    38         template <size_t Dim, typename CategoryT>
    39         struct size_by_dim_impl;
    40 
    41 
    42         /// \brief Specialization of \c size_by_dim_impl for computing the size of a
    43         ///  vector
    44         template <>
    45         struct size_by_dim_impl<1, vector_tag>
    46         {
    47             /**
    48              * \brief Compute the size of the given vector.
    49              * \tparam ExprT A vector expression type.
    50              * \pre ExprT must be a model of VectorExpression.
    51              */
    52             template <typename ExprT>
    53             BOOST_UBLAS_INLINE
    54             static typename ExprT::size_type apply(ExprT const& e)
    55             {
    56                 return e.size();
    57             }
    58         };
    59 
    60 
    61         /// \brief Specialization of \c size_by_dim_impl for computing the number of
    62         ///  rows of a matrix
    63         template <>
    64         struct size_by_dim_impl<1, matrix_tag>
    65         {
    66             /**
    67              * \brief Compute the number of rows of the given matrix.
    68              * \tparam ExprT A matrix expression type.
    69              * \pre ExprT must be a model of MatrixExpression.
    70              */
    71             template <typename ExprT>
    72             BOOST_UBLAS_INLINE
    73             static typename ExprT::size_type apply(ExprT const& e)
    74             {
    75                 return e.size1();
    76             }
    77         };
    78 
    79 
    80         /// \brief Specialization of \c size_by_dim_impl for computing the number of
    81         ///  columns of a matrix
    82         template <>
    83         struct size_by_dim_impl<2, matrix_tag>
    84         {
    85             /**
    86              * \brief Compute the number of columns of the given matrix.
    87              * \tparam ExprT A matrix expression type.
    88              * \pre ExprT must be a model of MatrixExpression.
    89              */
    90             template <typename ExprT>
    91             BOOST_UBLAS_INLINE
    92             static typename ExprT::size_type apply(ExprT const& e)
    93             {
    94                 return e.size2();
    95             }
    96         };
    97 
    98 
    99         /**
    100          * \brief Auxiliary class for computing the size of the given dimension for
    101          *  a container of the given category and with the given orientation..
    102          * \tparam Dim The dimension number (starting from 1).
    103          * \tparam CategoryT The category type (e.g., vector_tag).
    104          * \tparam OrientationT The orientation category type (e.g., row_major_tag).
    105          */
    106         template <typename TagT, typename CategoryT, typename OrientationT>
    107         struct size_by_tag_impl;
    108 
    109 
    110         /// \brief Specialization of \c size_by_tag_impl for computing the size of the
    111         ///  major dimension of a row-major oriented matrix.
    112         template <>
    113         struct size_by_tag_impl<tag::major, matrix_tag, row_major_tag>
    114         {
    115             /**
    116              * \brief Compute the number of rows of the given matrix.
    117              * \tparam ExprT A matrix expression type.
    118              * \pre ExprT must be a model of MatrixExpression.
    119              */
    120             template <typename ExprT>
    121             BOOST_UBLAS_INLINE
    122             static typename ExprT::size_type apply(ExprT const& e)
    123             {
    124                 return e.size1();
    125             }
    126         };
    127 
    128 
    129         /// \brief Specialization of \c size_by_tag_impl for computing the size of the
    130         ///  minor dimension of a row-major oriented matrix.
    131         template <>
    132         struct size_by_tag_impl<tag::minor, matrix_tag, row_major_tag>
    133         {
    134             /**
    135              * \brief Compute the number of columns of the given matrix.
    136              * \tparam ExprT A matrix expression type.
    137              * \pre ExprT must be a model of MatrixExpression.
    138              */
    139             template <typename ExprT>
    140             BOOST_UBLAS_INLINE
    141             static typename ExprT::size_type apply(ExprT const& e)
    142             {
    143                 return e.size2();
    144             }
    145         };
    146 
    147 
    148         /// \brief Specialization of \c size_by_tag_impl for computing the size of the
    149         ///  leading dimension of a row-major oriented matrix.
    150         template <>
    151         struct size_by_tag_impl<tag::leading, matrix_tag, row_major_tag>
    152         {
    153             /**
    154              * \brief Compute the number of columns of the given matrix.
    155              * \tparam ExprT A matrix expression type.
    156              * \pre ExprT must be a model of MatrixExpression.
    157              */
    158             template <typename ExprT>
    159             BOOST_UBLAS_INLINE
    160             static typename ExprT::size_type apply(ExprT const& e)
    161             {
    162                 return e.size2();
    163             }
    164         };
    165 
    166 
    167         /// \brief Specialization of \c size_by_tag_impl for computing the size of the
    168         ///  major dimension of a column-major oriented matrix.
    169         template <>
    170         struct size_by_tag_impl<tag::major, matrix_tag, column_major_tag>
    171         {
    172             /**
    173              * \brief Compute the number of columns of the given matrix.
    174              * \tparam ExprT A matrix expression type.
    175              * \pre ExprT must be a model of MatrixExpression.
    176              */
    177             template <typename ExprT>
    178             BOOST_UBLAS_INLINE
    179             static typename ExprT::size_type apply(ExprT const& e)
    180             {
    181                 return e.size2();
    182             }
    183         };
    184 
    185 
    186         /// \brief Specialization of \c size_by_tag_impl for computing the size of the
    187         ///  minor dimension of a column-major oriented matrix.
    188         template <>
    189         struct size_by_tag_impl<tag::minor, matrix_tag, column_major_tag>
    190         {
    191             /**
    192              * \brief Compute the number of rows of the given matrix.
    193              * \tparam ExprT A matrix expression type.
    194              * \pre ExprT must be a model of MatrixExpression.
    195              */
    196             template <typename ExprT>
    197             BOOST_UBLAS_INLINE
    198             static typename ExprT::size_type apply(ExprT const& e)
    199             {
    200                 return e.size1();
    201             }
    202         };
    203 
    204 
    205         /// \brief Specialization of \c size_by_tag_impl for computing the size of the
    206         ///  leading dimension of a column-major oriented matrix.
    207         template <>
    208         struct size_by_tag_impl<tag::leading, matrix_tag, column_major_tag>
    209         {
    210             /**
    211              * \brief Compute the number of rows of the given matrix.
    212              * \tparam ExprT A matrix expression type.
    213              * \pre ExprT must be a model of MatrixExpression.
    214              */
    215             template <typename ExprT>
    216             BOOST_UBLAS_INLINE
    217             static typename ExprT::size_type apply(ExprT const& e)
    218             {
    219                 return e.size1();
    220             }
    221         };
    222188
    223     } // Namespace detail
     189/**
     190 * \brief Specialization of \c size_by_tag_impl for computing the size of the
     191 *  leading dimension of a row-major oriented matrix.
     192 */
     193template <>
     194struct size_by_tag_impl<tag::leading, matrix_tag, row_major_tag>
     195{
     196    /**
     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.
     200     */
     201    template <typename ExprT>
     202    BOOST_UBLAS_INLINE
     203    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
     204    {
     205        return me().size2();
     206    }
     207};
    224208
    225209
     210/// \brief Specialization of \c size_by_tag_impl for computing the size of the
     211///  major dimension of a column-major oriented matrix.
     212template <>
     213struct size_by_tag_impl<tag::major, matrix_tag, column_major_tag>
     214{
    226215    /**
    227      * \brief Return the number of columns.
    228      * \tparam MatrixExprT A type which models the matrix expression concept.
    229      * \param m A matrix expression.
    230      * \return The number of columns.
     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.
    231219     */
    232     template <typename VectorExprT>
     220    template <typename ExprT>
    233221    BOOST_UBLAS_INLINE
    234     typename VectorExprT::size_type size(VectorExprT const& v)
     222    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
    235223    {
    236         return v.size();
     224        return me().size2();
    237225    }
     226};
    238227
    239228
     229/// \brief Specialization of \c size_by_tag_impl for computing the size of the
     230///  minor dimension of a column-major oriented matrix.
     231template <>
     232struct size_by_tag_impl<tag::minor, matrix_tag, column_major_tag>
     233{
    240234    /**
    241      * \brief Return the size of the given dimension for the given expression.
    242      * \tparam Dim The dimension number (starting from 1).
    243      * \tparam ExprT An expression type.
    244      * \param e An expression.
    245      * \return The number of columns.
    246      * \return The size associated to the dimension \a Dim.
     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.
    247238     */
    248     template <std::size_t Dim, typename ExprT>
     239    template <typename ExprT>
    249240    BOOST_UBLAS_INLINE
    250     typename ExprT::size_type size(ExprT const& e)
     241    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
    251242    {
    252         return detail::size_by_dim_impl<Dim, typename ExprT::type_category>::apply(e);
     243        return me().size1();
    253244    }
     245};
    254246
    255247
     248/// \brief Specialization of \c size_by_tag_impl for computing the size of the
     249///  leading dimension of a column-major oriented matrix.
     250template <>
     251struct size_by_tag_impl<tag::leading, matrix_tag, column_major_tag>
     252{
    256253    /**
    257      * \brief Return the size of the given dimension tag for the given expression.
    258      * \tparam TagT The dimension tag type (e.g., tag::major).
    259      * \tparam ExprT An expression type.
    260      * \param e An expression.
    261      * \return The size associated to the dimension tag \a TagT.
     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.
    262257     */
    263     template <typename TagT, typename ExprT>
     258    template <typename ExprT>
    264259    BOOST_UBLAS_INLINE
    265     typename ExprT::size_type size(ExprT const& e)
     260    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
    266261    {
    267         return detail::size_by_tag_impl<TagT, typename ExprT::type_category, typename ExprT::orientation_category>::apply(e);
     262        return me().size1();
    268263    }
     264};
     265
     266
     267/// \brief Specialization of \c size_by_tag_impl for computing the size of the
     268///  given dimension of a unknown oriented expression.
     269template <typename TagT, typename CategoryT>
     270struct size_by_tag_impl<TagT, CategoryT, unknown_orientation_tag>: size_by_tag_impl<TagT, CategoryT, row_major_tag>
     271{
     272    // Empty
     273};
     274
     275}} // Namespace detail::<unnamed>
     276
     277
     278/**
     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.
     283 */
     284template <typename VectorExprT>
     285BOOST_UBLAS_INLINE
     286typename ::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)
     290{
     291    return ve().size();
     292}
     293
     294
     295/**
     296 * \brief Return the size of the given dimension for the given vector
     297 *  expression.
     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.
     302 */
     303template <std::size_t Dim, typename VectorExprT>
     304BOOST_UBLAS_INLINE
     305typename vector_traits<VectorExprT>::size_type size(vector_expression<VectorExprT> const& ve)
     306{
     307    return detail::size_by_dim_impl<Dim, vector_tag>::template apply(ve);
     308}
     309
     310
     311/**
     312 * \brief Return the size of the given dimension for the given matrix
     313 *  expression.
     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
     318 *  \a Dim.
     319 */
     320template <std::size_t Dim, typename MatrixExprT>
     321BOOST_UBLAS_INLINE
     322typename matrix_traits<MatrixExprT>::size_type size(matrix_expression<MatrixExprT> const& me)
     323{
     324    return detail::size_by_dim_impl<Dim, matrix_tag>::template apply(me);
     325}
     326
     327
     328/**
     329 * \brief Return the size of the given dimension tag for the given matrix
     330 *  expression.
     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
     335 *  tag \a TagT.
     336 */
     337template <typename TagT, typename MatrixExprT>
     338BOOST_UBLAS_INLINE
     339typename ::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)
     343{
     344    return detail::size_by_tag_impl<TagT, matrix_tag, typename matrix_traits<MatrixExprT>::orientation_category>::template apply(me);
     345}
    269346
    270347}}} // Namespace boost::numeric::ublas
    271348