Get rid of a nasty const_cast by introducing a MatrixConstRef class.

Remove the __restrict__'s for now.
This commit is contained in:
Benoit Jacob 2007-09-29 17:27:20 +00:00
parent ee63e15e2c
commit 7d41ad9d90
10 changed files with 89 additions and 39 deletions

View File

@ -34,6 +34,7 @@ template<typename MatrixType> class EiBlock
typedef typename MatrixType::Ref MatRef; typedef typename MatrixType::Ref MatRef;
friend class EiObject<Scalar, EiBlock<MatrixType> >; friend class EiObject<Scalar, EiBlock<MatrixType> >;
typedef EiBlock Ref; typedef EiBlock Ref;
typedef EiBlock ConstRef;
static const int RowsAtCompileTime = EiDynamic, static const int RowsAtCompileTime = EiDynamic,
ColsAtCompileTime = EiDynamic; ColsAtCompileTime = EiDynamic;
@ -55,7 +56,8 @@ template<typename MatrixType> class EiBlock
EI_INHERIT_ASSIGNMENT_OPERATORS(EiBlock) EI_INHERIT_ASSIGNMENT_OPERATORS(EiBlock)
private: private:
const Ref& _ref() const { return *this; } Ref& _ref() { return *this; }
const Ref& _constRef() const { return *this; }
int _rows() const { return m_endRow - m_startRow + 1; } int _rows() const { return m_endRow - m_startRow + 1; }
int _cols() const { return m_endCol - m_startCol + 1; } int _cols() const { return m_endCol - m_startCol + 1; }

View File

@ -41,25 +41,29 @@ class EiMatrix : public EiObject<_Scalar, EiMatrix<_Scalar, _Rows, _Cols> >,
typedef EiMatrixStorage<_Scalar, _Rows, _Cols> Storage; typedef EiMatrixStorage<_Scalar, _Rows, _Cols> Storage;
typedef _Scalar Scalar; typedef _Scalar Scalar;
typedef EiMatrixRef<EiMatrix> Ref; typedef EiMatrixRef<EiMatrix> Ref;
typedef EiMatrixConstRef<EiMatrix> ConstRef;
friend class EiMatrixRef<EiMatrix>;
friend class EiMatrixConstRef<EiMatrix>;
static const int RowsAtCompileTime = _Rows, ColsAtCompileTime = _Cols; static const int RowsAtCompileTime = _Rows, ColsAtCompileTime = _Cols;
const Scalar* EI_RESTRICT array() const const Scalar* array() const
{ return Storage::m_array; } { return Storage::m_array; }
Scalar* EI_RESTRICT array() Scalar* array()
{ return Storage::m_array; } { return Storage::m_array; }
private: private:
Ref _ref() const { return Ref(*const_cast<EiMatrix*>(this)); } Ref _ref() { return Ref(*this); }
ConstRef _constRef() const { return ConstRef(*this); }
const Scalar& EI_RESTRICT _read(int row, int col = 0) const
const Scalar& _read(int row, int col = 0) const
{ {
EI_CHECK_RANGES(*this, row, col); EI_CHECK_RANGES(*this, row, col);
return array()[row + col * Storage::_rows()]; return array()[row + col * Storage::_rows()];
} }
Scalar& EI_RESTRICT _write(int row, int col = 0) Scalar& _write(int row, int col = 0)
{ {
EI_CHECK_RANGES(*this, row, col); EI_CHECK_RANGES(*this, row, col);
return array()[row + col * Storage::_rows()]; return array()[row + col * Storage::_rows()];

View File

@ -31,15 +31,16 @@ template<typename Lhs, typename Rhs> class EiSum
{ {
public: public:
typedef typename Lhs::Scalar Scalar; typedef typename Lhs::Scalar Scalar;
typedef typename Lhs::Ref LhsRef; typedef typename Lhs::ConstRef LhsRef;
typedef typename Rhs::Ref RhsRef; typedef typename Rhs::ConstRef RhsRef;
friend class EiObject<Scalar, EiSum>; friend class EiObject<Scalar, EiSum>;
typedef EiSum Ref; typedef EiSum Ref;
typedef EiSum ConstRef;
static const int RowsAtCompileTime = Lhs::RowsAtCompileTime, static const int RowsAtCompileTime = Lhs::RowsAtCompileTime,
ColsAtCompileTime = Rhs::ColsAtCompileTime; ColsAtCompileTime = Rhs::ColsAtCompileTime;
EiSum(const LhsRef& EI_RESTRICT lhs, const RhsRef& EI_RESTRICT rhs) EiSum(const LhsRef& lhs, const RhsRef& rhs)
: m_lhs(lhs), m_rhs(rhs) : m_lhs(lhs), m_rhs(rhs)
{ {
assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols()); assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
@ -53,6 +54,7 @@ template<typename Lhs, typename Rhs> class EiSum
private: private:
const Ref& _ref() const { return *this; } const Ref& _ref() const { return *this; }
const ConstRef& _constRef() const { return *this; }
int _rows() const { return m_lhs.rows(); } int _rows() const { return m_lhs.rows(); }
int _cols() const { return m_lhs.cols(); } int _cols() const { return m_lhs.cols(); }
@ -71,15 +73,16 @@ template<typename Lhs, typename Rhs> class EiDifference
{ {
public: public:
typedef typename Lhs::Scalar Scalar; typedef typename Lhs::Scalar Scalar;
typedef typename Lhs::Ref LhsRef; typedef typename Lhs::ConstRef LhsRef;
typedef typename Rhs::Ref RhsRef; typedef typename Rhs::ConstRef RhsRef;
friend class EiObject<Scalar, EiDifference>; friend class EiObject<Scalar, EiDifference>;
typedef EiDifference Ref; typedef EiDifference Ref;
typedef EiDifference ConstRef;
static const int RowsAtCompileTime = Lhs::RowsAtCompileTime, static const int RowsAtCompileTime = Lhs::RowsAtCompileTime,
ColsAtCompileTime = Rhs::ColsAtCompileTime; ColsAtCompileTime = Rhs::ColsAtCompileTime;
EiDifference(const LhsRef& EI_RESTRICT lhs, const RhsRef& EI_RESTRICT rhs) EiDifference(const LhsRef& lhs, const RhsRef& rhs)
: m_lhs(lhs), m_rhs(rhs) : m_lhs(lhs), m_rhs(rhs)
{ {
assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols()); assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
@ -92,6 +95,7 @@ template<typename Lhs, typename Rhs> class EiDifference
private: private:
const Ref& _ref() const { return *this; } const Ref& _ref() const { return *this; }
const Ref& _constRef() const { return *this; }
int _rows() const { return m_lhs.rows(); } int _rows() const { return m_lhs.rows(); }
int _cols() const { return m_lhs.cols(); } int _cols() const { return m_lhs.cols(); }
@ -110,15 +114,16 @@ template<typename Lhs, typename Rhs> class EiMatrixProduct
{ {
public: public:
typedef typename Lhs::Scalar Scalar; typedef typename Lhs::Scalar Scalar;
typedef typename Lhs::Ref LhsRef; typedef typename Lhs::ConstRef LhsRef;
typedef typename Rhs::Ref RhsRef; typedef typename Rhs::ConstRef RhsRef;
friend class EiObject<Scalar, EiMatrixProduct>; friend class EiObject<Scalar, EiMatrixProduct>;
typedef EiMatrixProduct Ref; typedef EiMatrixProduct Ref;
typedef EiMatrixProduct ConstRef;
static const int RowsAtCompileTime = Lhs::RowsAtCompileTime, static const int RowsAtCompileTime = Lhs::RowsAtCompileTime,
ColsAtCompileTime = Rhs::ColsAtCompileTime; ColsAtCompileTime = Rhs::ColsAtCompileTime;
EiMatrixProduct(const LhsRef& EI_RESTRICT lhs, const RhsRef& EI_RESTRICT rhs) EiMatrixProduct(const LhsRef& lhs, const RhsRef& rhs)
: m_lhs(lhs), m_rhs(rhs) : m_lhs(lhs), m_rhs(rhs)
{ {
assert(lhs.cols() == rhs.rows()); assert(lhs.cols() == rhs.rows());
@ -131,6 +136,7 @@ template<typename Lhs, typename Rhs> class EiMatrixProduct
private: private:
const Ref& _ref() const { return *this; } const Ref& _ref() const { return *this; }
const Ref& _constRef() const { return *this; }
int _rows() const { return m_lhs.rows(); } int _rows() const { return m_lhs.rows(); }
int _cols() const { return m_rhs.cols(); } int _cols() const { return m_rhs.cols(); }
@ -158,14 +164,14 @@ template<typename Scalar, typename Derived1, typename Derived2>
EiSum<Derived1, Derived2> EiSum<Derived1, Derived2>
operator+(const EiObject<Scalar, Derived1> &mat1, const EiObject<Scalar, Derived2> &mat2) operator+(const EiObject<Scalar, Derived1> &mat1, const EiObject<Scalar, Derived2> &mat2)
{ {
return EiSum<Derived1, Derived2>(mat1.ref(), mat2.ref()); return EiSum<Derived1, Derived2>(mat1.constRef(), mat2.constRef());
} }
template<typename Scalar, typename Derived1, typename Derived2> template<typename Scalar, typename Derived1, typename Derived2>
EiDifference<Derived1, Derived2> EiDifference<Derived1, Derived2>
operator-(const EiObject<Scalar, Derived1> &mat1, const EiObject<Scalar, Derived2> &mat2) operator-(const EiObject<Scalar, Derived1> &mat1, const EiObject<Scalar, Derived2> &mat2)
{ {
return EiDifference<Derived1, Derived2>(mat1.ref(), mat2.ref()); return EiDifference<Derived1, Derived2>(mat1.constRef(), mat2.constRef());
} }
template<typename Scalar, typename Derived> template<typename Scalar, typename Derived>
@ -173,7 +179,7 @@ template<typename OtherDerived>
EiMatrixProduct<Derived, OtherDerived> EiMatrixProduct<Derived, OtherDerived>
EiObject<Scalar, Derived>::lazyMul(const EiObject<Scalar, OtherDerived> &other) const EiObject<Scalar, Derived>::lazyMul(const EiObject<Scalar, OtherDerived> &other) const
{ {
return EiMatrixProduct<Derived, OtherDerived>(ref(), other.ref()); return EiMatrixProduct<Derived, OtherDerived>(constRef(), other.constRef());
} }
template<typename Scalar, typename Derived1, typename Derived2> template<typename Scalar, typename Derived1, typename Derived2>

View File

@ -26,6 +26,32 @@
#ifndef EI_MATRIXREF_H #ifndef EI_MATRIXREF_H
#define EI_MATRIXREF_H #define EI_MATRIXREF_H
template<typename MatrixType> class EiMatrixConstRef
: public EiObject<typename MatrixType::Scalar, EiMatrixConstRef<MatrixType> >
{
public:
typedef typename MatrixType::Scalar Scalar;
friend class EiObject<Scalar, EiMatrixConstRef>;
EiMatrixConstRef(const MatrixType& matrix) : m_matrix(matrix) {}
EiMatrixConstRef(const EiMatrixConstRef& other) : m_matrix(other.m_matrix) {}
~EiMatrixConstRef() {}
EI_INHERIT_ASSIGNMENT_OPERATORS(EiMatrixConstRef)
private:
int _rows() const { return m_matrix.rows(); }
int _cols() const { return m_matrix.cols(); }
const Scalar& _read(int row, int col) const
{
return m_matrix._read(row, col);
}
protected:
const MatrixType& m_matrix;
};
template<typename MatrixType> class EiMatrixRef template<typename MatrixType> class EiMatrixRef
: public EiObject<typename MatrixType::Scalar, EiMatrixRef<MatrixType> > : public EiObject<typename MatrixType::Scalar, EiMatrixRef<MatrixType> >
{ {
@ -43,9 +69,9 @@ template<typename MatrixType> class EiMatrixRef
int _rows() const { return m_matrix.rows(); } int _rows() const { return m_matrix.rows(); }
int _cols() const { return m_matrix.cols(); } int _cols() const { return m_matrix.cols(); }
Scalar _read(int row, int col) const const Scalar& _read(int row, int col) const
{ {
return m_matrix.read(row, col); return m_matrix._read(row, col);
} }
Scalar& _write(int row, int col) Scalar& _write(int row, int col)

View File

@ -32,7 +32,7 @@ template<typename Scalar,
class EiMatrixStorage class EiMatrixStorage
{ {
protected: protected:
Scalar EI_RESTRICT m_array[RowsAtCompileTime * RowsAtCompileTime]; Scalar m_array[RowsAtCompileTime * RowsAtCompileTime];
void resize(int rows, int cols) void resize(int rows, int cols)
{ assert(rows == RowsAtCompileTime && cols == ColsAtCompileTime); } { assert(rows == RowsAtCompileTime && cols == ColsAtCompileTime); }
@ -59,7 +59,7 @@ class EiMatrixStorage<Scalar, EiDynamic, ColsAtCompileTime>
{ {
protected: protected:
int m_rows; int m_rows;
Scalar* EI_RESTRICT m_array; Scalar* m_array;
void resize(int rows, int cols) void resize(int rows, int cols)
{ {
@ -94,7 +94,7 @@ class EiMatrixStorage<Scalar, RowsAtCompileTime, EiDynamic>
{ {
protected: protected:
int m_cols; int m_cols;
Scalar* EI_RESTRICT m_array; Scalar* m_array;
void resize(int rows, int cols) void resize(int rows, int cols)
{ {
@ -129,7 +129,7 @@ class EiMatrixStorage<Scalar, EiDynamic, EiDynamic>
{ {
protected: protected:
int m_rows, m_cols; int m_rows, m_cols;
Scalar* EI_RESTRICT m_array; Scalar* m_array;
void resize(int rows, int cols) void resize(int rows, int cols)
{ {

View File

@ -34,6 +34,7 @@ template<typename MatrixType> class EiMinor
typedef typename MatrixType::Ref MatRef; typedef typename MatrixType::Ref MatRef;
friend class EiObject<Scalar, EiMinor<MatrixType> >; friend class EiObject<Scalar, EiMinor<MatrixType> >;
typedef EiMinor Ref; typedef EiMinor Ref;
typedef EiMinor ConstRef;
static const int RowsAtCompileTime = MatrixType::RowsAtCompileTime - 1, static const int RowsAtCompileTime = MatrixType::RowsAtCompileTime - 1,
ColsAtCompileTime = MatrixType::ColsAtCompileTime - 1; ColsAtCompileTime = MatrixType::ColsAtCompileTime - 1;
@ -51,7 +52,8 @@ template<typename MatrixType> class EiMinor
EI_INHERIT_ASSIGNMENT_OPERATORS(EiMinor) EI_INHERIT_ASSIGNMENT_OPERATORS(EiMinor)
private: private:
const Ref& _ref() const { return *this; } Ref& _ref() { return *this; }
const ConstRef& _constRef() const { return *this; }
int _rows() const { return m_matrix.rows() - 1; } int _rows() const { return m_matrix.rows() - 1; }
int _cols() const { return m_matrix.cols() - 1; } int _cols() const { return m_matrix.cols() - 1; }

View File

@ -56,6 +56,7 @@ template<typename Scalar, typename Derived> class EiObject
public: public:
typedef typename EiForwardDecl<Derived>::Ref Ref; typedef typename EiForwardDecl<Derived>::Ref Ref;
typedef typename EiForwardDecl<Derived>::ConstRef ConstRef;
int rows() const { return static_cast<const Derived *>(this)->_rows(); } int rows() const { return static_cast<const Derived *>(this)->_rows(); }
int cols() const { return static_cast<const Derived *>(this)->_cols(); } int cols() const { return static_cast<const Derived *>(this)->_cols(); }
@ -64,10 +65,10 @@ template<typename Scalar, typename Derived> class EiObject
Ref ref() Ref ref()
{ return static_cast<Derived *>(this)->_ref(); } { return static_cast<Derived *>(this)->_ref(); }
Ref ref() const ConstRef constRef() const
{ return static_cast<const Derived *>(this)->_ref(); } { return static_cast<const Derived *>(this)->_constRef(); }
Scalar& EI_RESTRICT write(int row, int col) Scalar& write(int row, int col)
{ {
return static_cast<Derived *>(this)->_write(row, col); return static_cast<Derived *>(this)->_write(row, col);
} }
@ -127,7 +128,7 @@ template<typename Scalar, typename Derived> class EiObject
Scalar operator()(int row, int col = 0) const Scalar operator()(int row, int col = 0) const
{ return read(row, col); } { return read(row, col); }
Scalar& EI_RESTRICT operator()(int row, int col = 0) Scalar& operator()(int row, int col = 0)
{ return write(row, col); } { return write(row, col); }
EiEval<Derived> eval() const EI_ALWAYS_INLINE; EiEval<Derived> eval() const EI_ALWAYS_INLINE;

View File

@ -34,6 +34,7 @@ template<typename MatrixType> class EiRow
typedef typename MatrixType::Ref MatRef; typedef typename MatrixType::Ref MatRef;
friend class EiObject<Scalar, EiRow<MatrixType> >; friend class EiObject<Scalar, EiRow<MatrixType> >;
typedef EiRow Ref; typedef EiRow Ref;
typedef EiRow ConstRef;
static const int RowsAtCompileTime = MatrixType::ColsAtCompileTime, static const int RowsAtCompileTime = MatrixType::ColsAtCompileTime,
ColsAtCompileTime = 1; ColsAtCompileTime = 1;
@ -56,7 +57,8 @@ template<typename MatrixType> class EiRow
EI_INHERIT_ASSIGNMENT_OPERATORS(EiRow) EI_INHERIT_ASSIGNMENT_OPERATORS(EiRow)
private: private:
const Ref& _ref() const { return *this; } Ref& _ref() { return *this; }
const ConstRef& _constRef() const { return *this; }
int _rows() const { return m_matrix.cols(); } int _rows() const { return m_matrix.cols(); }
int _cols() const { return 1; } int _cols() const { return 1; }
@ -88,6 +90,7 @@ template<typename MatrixType> class EiColumn
typedef typename MatrixType::Ref MatRef; typedef typename MatrixType::Ref MatRef;
friend class EiObject<Scalar, EiColumn<MatrixType> >; friend class EiObject<Scalar, EiColumn<MatrixType> >;
typedef EiColumn Ref; typedef EiColumn Ref;
typedef EiColumn ConstRef;
static const int RowsAtCompileTime = MatrixType::RowsAtCompileTime, static const int RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = 1; ColsAtCompileTime = 1;
@ -104,7 +107,8 @@ template<typename MatrixType> class EiColumn
EI_INHERIT_ASSIGNMENT_OPERATORS(EiColumn) EI_INHERIT_ASSIGNMENT_OPERATORS(EiColumn)
private: private:
const Ref& _ref() const { return *this; } Ref& _ref() { return *this; }
const ConstRef& _constRef() const { return *this; }
int _rows() const { return m_matrix.rows(); } int _rows() const { return m_matrix.rows(); }
int _cols() const { return 1; } int _cols() const { return 1; }

View File

@ -31,8 +31,9 @@ template<typename MatrixType> class EiScalarProduct
{ {
public: public:
typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef; typedef typename MatrixType::ConstRef MatRef;
typedef EiScalarProduct Ref; typedef EiScalarProduct Ref;
typedef EiScalarProduct ConstRef;
friend class EiObject<typename MatrixType::Scalar, EiScalarProduct<MatrixType> >; friend class EiObject<typename MatrixType::Scalar, EiScalarProduct<MatrixType> >;
static const int RowsAtCompileTime = MatrixType::RowsAtCompileTime, static const int RowsAtCompileTime = MatrixType::RowsAtCompileTime,
@ -48,6 +49,7 @@ template<typename MatrixType> class EiScalarProduct
private: private:
const Ref& _ref() const { return *this; } const Ref& _ref() const { return *this; }
const ConstRef& _constRef() const { return *this; }
int _rows() const { return m_matrix.rows(); } int _rows() const { return m_matrix.rows(); }
int _cols() const { return m_matrix.cols(); } int _cols() const { return m_matrix.cols(); }
@ -61,13 +63,13 @@ template<typename MatrixType> class EiScalarProduct
const Scalar m_scalar; const Scalar m_scalar;
}; };
#define EI_MAKE_SCALAR_OPS(OtherScalar) \ #define EI_MAKE_SCALAR_OPS(OtherScalar) \
template<typename Scalar, typename Derived> \ template<typename Scalar, typename Derived> \
EiScalarProduct<Derived> \ EiScalarProduct<Derived> \
operator*(const EiObject<Scalar, Derived>& matrix, \ operator*(const EiObject<Scalar, Derived>& matrix, \
OtherScalar scalar) \ OtherScalar scalar) \
{ \ { \
return EiScalarProduct<Derived>(matrix.ref(), scalar); \ return EiScalarProduct<Derived>(matrix.constRef(), scalar); \
} \ } \
\ \
template<typename Scalar, typename Derived> \ template<typename Scalar, typename Derived> \
@ -75,7 +77,7 @@ EiScalarProduct<Derived> \
operator*(OtherScalar scalar, \ operator*(OtherScalar scalar, \
const EiObject<Scalar, Derived>& matrix) \ const EiObject<Scalar, Derived>& matrix) \
{ \ { \
return EiScalarProduct<Derived>(matrix.ref(), scalar); \ return EiScalarProduct<Derived>(matrix.constRef(), scalar); \
} \ } \
\ \
template<typename Scalar, typename Derived> \ template<typename Scalar, typename Derived> \
@ -88,7 +90,7 @@ operator/(const EiObject<Scalar, Derived>& matrix, \
\ \
template<typename Scalar, typename Derived> \ template<typename Scalar, typename Derived> \
Derived & \ Derived & \
EiObject<Scalar, Derived>::operator*=(const OtherScalar &other) \ EiObject<Scalar, Derived>::operator*=(const OtherScalar &other) \
{ \ { \
*this = *this * other; \ *this = *this * other; \
return *static_cast<Derived*>(this); \ return *static_cast<Derived*>(this); \
@ -96,7 +98,7 @@ EiObject<Scalar, Derived>::operator*=(const OtherScalar &other) \
\ \
template<typename Scalar, typename Derived> \ template<typename Scalar, typename Derived> \
Derived & \ Derived & \
EiObject<Scalar, Derived>::operator/=(const OtherScalar &other) \ EiObject<Scalar, Derived>::operator/=(const OtherScalar &other) \
{ \ { \
*this = *this / other; \ *this = *this / other; \
return *static_cast<Derived*>(this); \ return *static_cast<Derived*>(this); \

View File

@ -43,6 +43,7 @@
//forward declarations //forward declarations
template<typename _Scalar, int _Rows, int _Cols> class EiMatrix; template<typename _Scalar, int _Rows, int _Cols> class EiMatrix;
template<typename MatrixType> class EiMatrixRef; template<typename MatrixType> class EiMatrixRef;
template<typename MatrixType> class EiMatrixConstRef;
template<typename MatrixType> class EiRow; template<typename MatrixType> class EiRow;
template<typename MatrixType> class EiColumn; template<typename MatrixType> class EiColumn;
template<typename MatrixType> class EiMinor; template<typename MatrixType> class EiMinor;
@ -56,12 +57,14 @@ template<typename ExpressionType> class EiEval;
template<typename T> struct EiForwardDecl template<typename T> struct EiForwardDecl
{ {
typedef T Ref; typedef T Ref;
typedef T ConstRef;
}; };
template<typename _Scalar, int _Rows, int _Cols> template<typename _Scalar, int _Rows, int _Cols>
struct EiForwardDecl<EiMatrix<_Scalar, _Rows, _Cols> > struct EiForwardDecl<EiMatrix<_Scalar, _Rows, _Cols> >
{ {
typedef EiMatrixRef<EiMatrix<_Scalar, _Rows, _Cols> > Ref; typedef EiMatrixRef<EiMatrix<_Scalar, _Rows, _Cols> > Ref;
typedef EiMatrixConstRef<EiMatrix<_Scalar, _Rows, _Cols> > ConstRef;
}; };
const int EiDynamic = -1; const int EiDynamic = -1;
@ -70,7 +73,7 @@ const int EiDynamic = -1;
#ifdef __GNUC__ #ifdef __GNUC__
# define EI_ALWAYS_INLINE __attribute__((always_inline)) # define EI_ALWAYS_INLINE __attribute__((always_inline))
# define EI_RESTRICT __restrict__ # define EI_RESTRICT /*__restrict__*/
#else #else
# define EI_ALWAYS_INLINE # define EI_ALWAYS_INLINE
# define EI_RESTRICT # define EI_RESTRICT