namespace Eigen {

/** \page TopicClassHierarchy The class hierarchy

This page explains the design of the core classes in Eigen's class hierarchy and how they fit together. Casual
users probably need not concern themselves with these details, but it may be useful for both advanced users
and Eigen developers.

\eigenAutoToc


\section TopicClassHierarchyPrinciples Principles

Eigen's class hierarchy is designed so that virtual functions are avoided where their overhead would
significantly impair performance. Instead, Eigen achieves polymorphism with the Curiously Recurring Template
Pattern (CRTP). In this pattern, the base class (for instance, \c MatrixBase) is in fact a template class, and
the derived class (for instance, \c Matrix) inherits the base class with the derived class itself as a
template argument (in this case, \c Matrix inherits from \c MatrixBase&lt;Matrix&gt;). This allows Eigen to
resolve the polymorphic function calls at compile time.

In addition, the design avoids multiple inheritance. One reason for this is that in our experience, some
compilers (like MSVC) fail to perform empty base class optimization, which is crucial for our fixed-size
types.


\section TopicClassHierarchyCoreClasses The core classes

These are the classes that you need to know about if you want to write functions that accept or return Eigen
objects.

  - Matrix means plain dense matrix. If \c m is a \c %Matrix, then, for instance, \c m+m is no longer a 
    \c %Matrix, it is a "matrix expression".
  - MatrixBase means dense matrix expression. This means that a \c %MatrixBase is something that can be
    added, matrix-multiplied, LU-decomposed, QR-decomposed... All matrix expression classes, including 
    \c %Matrix itself, inherit \c %MatrixBase.
  - Array means plain dense array. If \c x is an \c %Array, then, for instance, \c x+x is no longer an 
    \c %Array, it is an "array expression".
  - ArrayBase means dense array expression. This means that an \c %ArrayBase is something that can be
    added, array-multiplied, and on which you can perform all sorts of array operations... All array
    expression classes, including \c %Array itself, inherit \c %ArrayBase.
  - DenseBase means dense (matrix or array) expression. Both \c %ArrayBase and \c %MatrixBase inherit
    \c %DenseBase. \c %DenseBase is where all the methods go that apply to dense expressions regardless of
    whether they are matrix or array expressions. For example, the \link DenseBase::block() block(...) \endlink
    methods are in \c %DenseBase.

\section TopicClassHierarchyBaseClasses Base classes

These classes serve as base classes for the five core classes mentioned above. They are more internal and so
less interesting for users of the Eigen library.

  - PlainObjectBase means dense (matrix or array) plain object, i.e. something that stores its own dense
    array of coefficients. This is where, for instance, the \link PlainObjectBase::resize() resize() \endlink
    methods go. \c %PlainObjectBase is inherited by \c %Matrix and by \c %Array. But above, we said that 
    \c %Matrix inherits \c %MatrixBase and \c %Array inherits \c %ArrayBase. So does that mean multiple
    inheritance? No, because \c %PlainObjectBase \e itself inherits \c %MatrixBase or \c %ArrayBase depending
    on whether we are in the matrix or array case. When we said above that \c %Matrix inherited 
    \c %MatrixBase, we omitted to say it does so indirectly via \c %PlainObjectBase. Same for \c %Array.
  - DenseCoeffsBase means something that has dense coefficient accessors. It is a base class for
    \c %DenseBase. The reason for \c %DenseCoeffsBase to exist is that the set of available coefficient
    accessors is very different depending on whether a dense expression has direct memory access or not (the
    \c DirectAccessBit flag). For example, if \c x is a plain matrix, then \c x has direct access, and 
    \c x.transpose() and \c x.block(...) also have direct access, because their coefficients can be read right
    off memory, but for example, \c x+x does not have direct memory access, because obtaining any of its
    coefficients requires a computation (an addition), it can't be just read off memory.
  - EigenBase means anything that can be evaluated into a plain dense matrix or array (even if that would
    be a bad idea). \c %EigenBase is really the absolute base class for anything that remotely looks like a
    matrix or array. It is a base class for \c %DenseCoeffsBase, so it sits below all our dense class
    hierarchy, but it is not limited to dense expressions. For example, \c %EigenBase is also inherited by
    diagonal matrices, sparse matrices, etc...


\section TopicClassHierarchyInheritanceDiagrams Inheritance diagrams

The inheritance diagram for Matrix looks as follows:

<pre>
EigenBase&lt;%Matrix&gt;
  <-- DenseCoeffsBase&lt;%Matrix&gt;    (direct access case)
    <-- DenseBase&lt;%Matrix&gt;
      <-- MatrixBase&lt;%Matrix&gt;
        <-- PlainObjectBase&lt;%Matrix&gt;    (matrix case)
          <-- Matrix
</pre>

The inheritance diagram for Array looks as follows:

<pre>
EigenBase&lt;%Array&gt;
  <-- DenseCoeffsBase&lt;%Array&gt;    (direct access case)
    <-- DenseBase&lt;%Array&gt;
      <-- ArrayBase&lt;%Array&gt;
        <-- PlainObjectBase&lt;%Array&gt;    (array case)
          <-- Array
</pre>

The inheritance diagram for some other matrix expression class, here denoted by \c SomeMatrixXpr, looks as
follows:

<pre>
EigenBase&lt;SomeMatrixXpr&gt;
  <-- DenseCoeffsBase&lt;SomeMatrixXpr&gt;    (direct access or no direct access case)
    <-- DenseBase&lt;SomeMatrixXpr&gt;
      <-- MatrixBase&lt;SomeMatrixXpr&gt;
        <-- SomeMatrixXpr
</pre>

The inheritance diagram for some other array expression class, here denoted by \c SomeArrayXpr, looks as
follows:

<pre>
EigenBase&lt;SomeArrayXpr&gt;
  <-- DenseCoeffsBase&lt;SomeArrayXpr&gt;    (direct access or no direct access case)
    <-- DenseBase&lt;SomeArrayXpr&gt;
      <-- ArrayBase&lt;SomeArrayXpr&gt;
        <-- SomeArrayXpr
</pre>

Finally, consider an example of something that is not a dense expression, for instance a diagonal matrix. The
corresponding inheritance diagram is:

<pre>
EigenBase&lt;%DiagonalMatrix&gt;
  <-- DiagonalBase&lt;%DiagonalMatrix&gt;
    <-- DiagonalMatrix
</pre>


*/
}
