Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / extern / Eigen2 / Eigen / src / Core / CommaInitializer.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25
26 #ifndef EIGEN_COMMAINITIALIZER_H
27 #define EIGEN_COMMAINITIALIZER_H
28
29 /** \class CommaInitializer
30   *
31   * \brief Helper class used by the comma initializer operator
32   *
33   * This class is internally used to implement the comma initializer feature. It is
34   * the return type of MatrixBase::operator<<, and most of the time this is the only
35   * way it is used.
36   *
37   * \sa \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished()
38   */
39 template<typename MatrixType>
40 struct CommaInitializer
41 {
42   typedef typename ei_traits<MatrixType>::Scalar Scalar;
43   inline CommaInitializer(MatrixType& mat, const Scalar& s)
44     : m_matrix(mat), m_row(0), m_col(1), m_currentBlockRows(1)
45   {
46     m_matrix.coeffRef(0,0) = s;
47   }
48
49   template<typename OtherDerived>
50   inline CommaInitializer(MatrixType& mat, const MatrixBase<OtherDerived>& other)
51     : m_matrix(mat), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
52   {
53     m_matrix.block(0, 0, other.rows(), other.cols()) = other;
54   }
55
56   /* inserts a scalar value in the target matrix */
57   CommaInitializer& operator,(const Scalar& s)
58   {
59     if (m_col==m_matrix.cols())
60     {
61       m_row+=m_currentBlockRows;
62       m_col = 0;
63       m_currentBlockRows = 1;
64       ei_assert(m_row<m_matrix.rows()
65         && "Too many rows passed to comma initializer (operator<<)");
66     }
67     ei_assert(m_col<m_matrix.cols()
68       && "Too many coefficients passed to comma initializer (operator<<)");
69     ei_assert(m_currentBlockRows==1);
70     m_matrix.coeffRef(m_row, m_col++) = s;
71     return *this;
72   }
73
74   /* inserts a matrix expression in the target matrix */
75   template<typename OtherDerived>
76   CommaInitializer& operator,(const MatrixBase<OtherDerived>& other)
77   {
78     if (m_col==m_matrix.cols())
79     {
80       m_row+=m_currentBlockRows;
81       m_col = 0;
82       m_currentBlockRows = other.rows();
83       ei_assert(m_row+m_currentBlockRows<=m_matrix.rows()
84         && "Too many rows passed to comma initializer (operator<<)");
85     }
86     ei_assert(m_col<m_matrix.cols()
87       && "Too many coefficients passed to comma initializer (operator<<)");
88     ei_assert(m_currentBlockRows==other.rows());
89     if (OtherDerived::SizeAtCompileTime != Dynamic)
90       m_matrix.template block<OtherDerived::RowsAtCompileTime != Dynamic ? OtherDerived::RowsAtCompileTime : 1,
91                               OtherDerived::ColsAtCompileTime != Dynamic ? OtherDerived::ColsAtCompileTime : 1>
92                     (m_row, m_col) = other;
93     else
94       m_matrix.block(m_row, m_col, other.rows(), other.cols()) = other;
95     m_col += other.cols();
96     return *this;
97   }
98
99   inline ~CommaInitializer()
100   {
101     ei_assert((m_row+m_currentBlockRows) == m_matrix.rows()
102          && m_col == m_matrix.cols()
103          && "Too few coefficients passed to comma initializer (operator<<)");
104   }
105
106   /** \returns the built matrix once all its coefficients have been set.
107     * Calling finished is 100% optional. Its purpose is to write expressions
108     * like this:
109     * \code
110     * quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished());
111     * \endcode
112     */
113   inline MatrixType& finished() { return m_matrix; }
114
115   MatrixType& m_matrix;   // target matrix
116   int m_row;              // current row id
117   int m_col;              // current col id
118   int m_currentBlockRows; // current block height
119 };
120
121 /** \anchor MatrixBaseCommaInitRef
122   * Convenient operator to set the coefficients of a matrix.
123   *
124   * The coefficients must be provided in a row major order and exactly match
125   * the size of the matrix. Otherwise an assertion is raised.
126   *
127   * \addexample CommaInit \label How to easily set all the coefficients of a matrix
128   *
129   * Example: \include MatrixBase_set.cpp
130   * Output: \verbinclude MatrixBase_set.out
131   *
132   * \sa CommaInitializer::finished(), class CommaInitializer
133   */
134 template<typename Derived>
135 inline CommaInitializer<Derived> MatrixBase<Derived>::operator<< (const Scalar& s)
136 {
137   return CommaInitializer<Derived>(*static_cast<Derived*>(this), s);
138 }
139
140 /** \sa operator<<(const Scalar&) */
141 template<typename Derived>
142 template<typename OtherDerived>
143 inline CommaInitializer<Derived>
144 MatrixBase<Derived>::operator<<(const MatrixBase<OtherDerived>& other)
145 {
146   return CommaInitializer<Derived>(*static_cast<Derived *>(this), other);
147 }
148
149 #endif // EIGEN_COMMAINITIALIZER_H