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