LCOV - code coverage report
Current view: top level - Core - CommaInitializer.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 42 42 100.0 %
Date: 1980-01-01 00:00:00 Functions: 47 47 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // This file is part of Eigen, a lightweight C++ template library
       2                 :            : // for linear algebra.
       3                 :            : //
       4                 :            : // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
       5                 :            : // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
       6                 :            : //
       7                 :            : // This Source Code Form is subject to the terms of the Mozilla
       8                 :            : // Public License v. 2.0. If a copy of the MPL was not distributed
       9                 :            : // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      10                 :            : 
      11                 :            : #ifndef EIGEN_COMMAINITIALIZER_H
      12                 :            : #define EIGEN_COMMAINITIALIZER_H
      13                 :            : 
      14                 :            : namespace Eigen { 
      15                 :            : 
      16                 :            : /** \class CommaInitializer
      17                 :            :   * \ingroup Core_Module
      18                 :            :   *
      19                 :            :   * \brief Helper class used by the comma initializer operator
      20                 :            :   *
      21                 :            :   * This class is internally used to implement the comma initializer feature. It is
      22                 :            :   * the return type of MatrixBase::operator<<, and most of the time this is the only
      23                 :            :   * way it is used.
      24                 :            :   *
      25                 :            :   * \sa \blank \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished()
      26                 :            :   */
      27                 :            : template<typename XprType>
      28                 :            : struct CommaInitializer
      29                 :            : {
      30                 :            :   typedef typename XprType::Scalar Scalar;
      31                 :            : 
      32                 :            :   EIGEN_DEVICE_FUNC
      33                 :      32088 :   inline CommaInitializer(XprType& xpr, const Scalar& s)
      34                 :      32088 :     : m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1)
      35                 :            :   {
      36                 :      32088 :     eigen_assert(m_xpr.rows() > 0 && m_xpr.cols() > 0
      37                 :            :       && "Cannot comma-initialize a 0x0 matrix (operator<<)");
      38                 :      32088 :     m_xpr.coeffRef(0,0) = s;
      39                 :      32088 :   }
      40                 :            : 
      41                 :            :   template<typename OtherDerived>
      42                 :            :   EIGEN_DEVICE_FUNC
      43                 :        306 :   inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
      44                 :        306 :     : m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
      45                 :            :   {
      46                 :        306 :     eigen_assert(m_xpr.rows() >= other.rows() && m_xpr.cols() >= other.cols()
      47                 :            :       && "Cannot comma-initialize a 0x0 matrix (operator<<)");
      48                 :        306 :     m_xpr.block(0, 0, other.rows(), other.cols()) = other;
      49                 :        306 :   }
      50                 :            : 
      51                 :            :   /* Copy/Move constructor which transfers ownership. This is crucial in 
      52                 :            :    * absence of return value optimization to avoid assertions during destruction. */
      53                 :            :   // FIXME in C++11 mode this could be replaced by a proper RValue constructor
      54                 :            :   EIGEN_DEVICE_FUNC
      55                 :            :   inline CommaInitializer(const CommaInitializer& o)
      56                 :            :   : m_xpr(o.m_xpr), m_row(o.m_row), m_col(o.m_col), m_currentBlockRows(o.m_currentBlockRows) {
      57                 :            :     // Mark original object as finished. In absence of R-value references we need to const_cast:
      58                 :            :     const_cast<CommaInitializer&>(o).m_row = m_xpr.rows();
      59                 :            :     const_cast<CommaInitializer&>(o).m_col = m_xpr.cols();
      60                 :            :     const_cast<CommaInitializer&>(o).m_currentBlockRows = 0;
      61                 :            :   }
      62                 :            : 
      63                 :            :   /* inserts a scalar value in the target matrix */
      64                 :            :   EIGEN_DEVICE_FUNC
      65                 :      80661 :   CommaInitializer& operator,(const Scalar& s)
      66                 :            :   {
      67                 :      80661 :     if (m_col==m_xpr.cols())
      68                 :            :     {
      69                 :      72217 :       m_row+=m_currentBlockRows;
      70                 :      72217 :       m_col = 0;
      71                 :      72217 :       m_currentBlockRows = 1;
      72                 :      72217 :       eigen_assert(m_row<m_xpr.rows()
      73                 :            :         && "Too many rows passed to comma initializer (operator<<)");
      74                 :            :     }
      75                 :      80661 :     eigen_assert(m_col<m_xpr.cols()
      76                 :            :       && "Too many coefficients passed to comma initializer (operator<<)");
      77                 :      80661 :     eigen_assert(m_currentBlockRows==1);
      78                 :      80661 :     m_xpr.coeffRef(m_row, m_col++) = s;
      79                 :      80661 :     return *this;
      80                 :            :   }
      81                 :            : 
      82                 :            :   /* inserts a matrix expression in the target matrix */
      83                 :            :   template<typename OtherDerived>
      84                 :            :   EIGEN_DEVICE_FUNC
      85                 :        306 :   CommaInitializer& operator,(const DenseBase<OtherDerived>& other)
      86                 :            :   {
      87                 :        306 :     if (m_col==m_xpr.cols() && (other.cols()!=0 || other.rows()!=m_currentBlockRows))
      88                 :            :     {
      89                 :        306 :       m_row+=m_currentBlockRows;
      90                 :        306 :       m_col = 0;
      91                 :        306 :       m_currentBlockRows = other.rows();
      92                 :        306 :       eigen_assert(m_row+m_currentBlockRows<=m_xpr.rows()
      93                 :            :         && "Too many rows passed to comma initializer (operator<<)");
      94                 :            :     }
      95                 :        306 :     eigen_assert((m_col + other.cols() <= m_xpr.cols())
      96                 :            :       && "Too many coefficients passed to comma initializer (operator<<)");
      97                 :        306 :     eigen_assert(m_currentBlockRows==other.rows());
      98                 :        306 :     m_xpr.template block<OtherDerived::RowsAtCompileTime, OtherDerived::ColsAtCompileTime>
      99                 :        306 :                     (m_row, m_col, other.rows(), other.cols()) = other;
     100                 :        306 :     m_col += other.cols();
     101                 :        306 :     return *this;
     102                 :            :   }
     103                 :            : 
     104                 :            :   EIGEN_DEVICE_FUNC
     105                 :      32394 :   inline ~CommaInitializer()
     106                 :            : #if defined VERIFY_RAISES_ASSERT && (!defined EIGEN_NO_ASSERTION_CHECKING) && defined EIGEN_EXCEPTIONS
     107                 :            :   EIGEN_EXCEPTION_SPEC(Eigen::eigen_assert_exception)
     108                 :            : #endif
     109                 :            :   {
     110                 :      32394 :     finished();
     111                 :      32394 :   }
     112                 :            : 
     113                 :            :   /** \returns the built matrix once all its coefficients have been set.
     114                 :            :     * Calling finished is 100% optional. Its purpose is to write expressions
     115                 :            :     * like this:
     116                 :            :     * \code
     117                 :            :     * quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished());
     118                 :            :     * \endcode
     119                 :            :     */
     120                 :            :   EIGEN_DEVICE_FUNC
     121                 :      35694 :   inline XprType& finished() {
     122                 :      35694 :       eigen_assert(((m_row+m_currentBlockRows) == m_xpr.rows() || m_xpr.cols() == 0)
     123                 :            :            && m_col == m_xpr.cols()
     124                 :            :            && "Too few coefficients passed to comma initializer (operator<<)");
     125                 :      35694 :       return m_xpr;
     126                 :            :   }
     127                 :            : 
     128                 :            :   XprType& m_xpr;           // target expression
     129                 :            :   Index m_row;              // current row id
     130                 :            :   Index m_col;              // current col id
     131                 :            :   Index m_currentBlockRows; // current block height
     132                 :            : };
     133                 :            : 
     134                 :            : /** \anchor MatrixBaseCommaInitRef
     135                 :            :   * Convenient operator to set the coefficients of a matrix.
     136                 :            :   *
     137                 :            :   * The coefficients must be provided in a row major order and exactly match
     138                 :            :   * the size of the matrix. Otherwise an assertion is raised.
     139                 :            :   *
     140                 :            :   * Example: \include MatrixBase_set.cpp
     141                 :            :   * Output: \verbinclude MatrixBase_set.out
     142                 :            :   * 
     143                 :            :   * \note According the c++ standard, the argument expressions of this comma initializer are evaluated in arbitrary order.
     144                 :            :   *
     145                 :            :   * \sa CommaInitializer::finished(), class CommaInitializer
     146                 :            :   */
     147                 :            : template<typename Derived>
     148                 :      32088 : EIGEN_DEVICE_FUNC inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s)
     149                 :            : {
     150                 :      32088 :   return CommaInitializer<Derived>(*static_cast<Derived*>(this), s);
     151                 :            : }
     152                 :            : 
     153                 :            : /** \sa operator<<(const Scalar&) */
     154                 :            : template<typename Derived>
     155                 :            : template<typename OtherDerived>
     156                 :            : EIGEN_DEVICE_FUNC inline CommaInitializer<Derived>
     157                 :        306 : DenseBase<Derived>::operator<<(const DenseBase<OtherDerived>& other)
     158                 :            : {
     159                 :        306 :   return CommaInitializer<Derived>(*static_cast<Derived *>(this), other);
     160                 :            : }
     161                 :            : 
     162                 :            : } // end namespace Eigen
     163                 :            : 
     164                 :            : #endif // EIGEN_COMMAINITIALIZER_H

Generated by: LCOV version 1.0