first approach including first tests
This commit is contained in:
@@ -8,4 +8,6 @@
|
||||
## 1 2 3 4 5 6 7 8
|
||||
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
|
||||
include_HEADERS = matrix.hxx
|
||||
|
||||
MAINTAINERCLEANFILES = makefile.in
|
||||
|
299
src/matrix.hxx
Normal file
299
src/matrix.hxx
Normal file
@@ -0,0 +1,299 @@
|
||||
/*! @file
|
||||
|
||||
@id $Id$
|
||||
*/
|
||||
// 1 2 3 4 5 6 7 8
|
||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
|
||||
#define LOG std::cout<<__PRETTY_FUNCTION__<<std::endl
|
||||
|
||||
template<typename T, size_t ROWS=0, size_t COLUMNS=0> class Matrix {
|
||||
|
||||
//........................................................const.variables
|
||||
protected:
|
||||
|
||||
static const size_t SIZE = ROWS*COLUMNS;
|
||||
static const size_t MEM_SIZE = ROWS*COLUMNS*sizeof(T);
|
||||
|
||||
//...............................................................typedefs
|
||||
public:
|
||||
|
||||
/// @name Auxiliary Classes
|
||||
///{
|
||||
|
||||
/// Return One Row as Vector, internally used for element access
|
||||
/** Only used to access values:
|
||||
|
||||
@code
|
||||
Matrix<int,4,4> m;
|
||||
m[2][2] = 1;
|
||||
@endcode */
|
||||
class RowVector {
|
||||
public:
|
||||
T& operator[](size_t column) {
|
||||
return _v[column];
|
||||
}
|
||||
protected:
|
||||
friend class Matrix;
|
||||
RowVector() = delete; // forbidden
|
||||
RowVector(T c[COLUMNS]): _v(c) {}
|
||||
T *_v;
|
||||
};
|
||||
|
||||
/// Same as RowVector, but in a constant environment.
|
||||
class ConstRowVector {
|
||||
public:
|
||||
const T& operator[](size_t column) const {
|
||||
return _v[column];
|
||||
}
|
||||
protected:
|
||||
friend class Matrix;
|
||||
ConstRowVector() = delete; // forbidden
|
||||
ConstRowVector(const T c[COLUMNS]): _v(c) {}
|
||||
const T *_v;
|
||||
};
|
||||
|
||||
///}
|
||||
|
||||
//................................................................methods
|
||||
public:
|
||||
|
||||
/// @name construction
|
||||
///{
|
||||
|
||||
Matrix() {
|
||||
LOG;
|
||||
memset(_c, 0, MEM_SIZE);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
Matrix(ARGS...t): _c{std::forward<T>(t)...} {
|
||||
LOG;
|
||||
static_assert(sizeof...(t)==SIZE, "variadic matrix initialisation requires correct array size");
|
||||
}
|
||||
|
||||
Matrix(const Matrix& o) {
|
||||
LOG;
|
||||
memcpy(_c, o._c, MEM_SIZE);
|
||||
}
|
||||
|
||||
///}
|
||||
|
||||
/// @name operators
|
||||
///{
|
||||
|
||||
Matrix& operator=(T oc[ROWS][COLUMNS]) {
|
||||
LOG;
|
||||
memcpy(_c, oc, MEM_SIZE);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix& operator=(const Matrix& o) {
|
||||
LOG;
|
||||
memcpy(_c, o._c, MEM_SIZE);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix& operator+=(const Matrix& o) {
|
||||
LOG;
|
||||
T *to((T*)(_c)+MEM_SIZE), *from((T*)(o._c)+MEM_SIZE);
|
||||
while (to>(T*)(_c)) *--to += *--from;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RowVector operator[](size_t row) {
|
||||
return RowVector(_c[row]);
|
||||
}
|
||||
|
||||
const ConstRowVector operator[](size_t row) const {
|
||||
return ConstRowVector(_c[row]);
|
||||
}
|
||||
|
||||
///}
|
||||
|
||||
//..............................................................variables
|
||||
protected:
|
||||
|
||||
T _c[ROWS][COLUMNS];
|
||||
|
||||
};
|
||||
|
||||
template<typename T> class Matrix<T, 0, 0> {
|
||||
|
||||
//..............................................................constants
|
||||
public:
|
||||
|
||||
const size_t ROWS;
|
||||
const size_t COLUMNS;
|
||||
const size_t SIZE;
|
||||
const size_t MEM_SIZE;
|
||||
|
||||
//...............................................................typedefs
|
||||
public:
|
||||
|
||||
/// @name Auxiliary Classes
|
||||
///{
|
||||
|
||||
/// Return One Row as Vector, internally used for element access
|
||||
/** Only used to access values:
|
||||
|
||||
@code
|
||||
Matrix<int,4,4> m;
|
||||
m[2][2] = 1;
|
||||
@endcode */
|
||||
class RowVector {
|
||||
public:
|
||||
T& operator[](size_t column) {
|
||||
assert(column<_m.COLUMNS);
|
||||
return _v[column];
|
||||
}
|
||||
protected:
|
||||
friend class Matrix;
|
||||
RowVector() = delete; // forbidden
|
||||
RowVector(const Matrix& m, T c[]): _m(m), _v(c) {}
|
||||
const Matrix& _m;
|
||||
T *_v;
|
||||
};
|
||||
|
||||
/// Same as RowVector, but in a constant environment.
|
||||
class ConstRowVector {
|
||||
public:
|
||||
const T& operator[](size_t column) const {
|
||||
assert(column<_m.COLUMNS);
|
||||
return _v[column];
|
||||
}
|
||||
protected:
|
||||
friend class Matrix;
|
||||
ConstRowVector() = delete; // forbidden
|
||||
ConstRowVector(const Matrix& m, const T c[]): _m(m), _v(c) {}
|
||||
const Matrix& _m;
|
||||
const T *_v;
|
||||
};
|
||||
|
||||
///}
|
||||
|
||||
//................................................................methods
|
||||
public:
|
||||
|
||||
/// @name construction
|
||||
///{
|
||||
|
||||
Matrix(size_t rows, size_t columns):
|
||||
ROWS(rows),
|
||||
COLUMNS(columns),
|
||||
SIZE(rows*columns),
|
||||
MEM_SIZE(rows*columns*sizeof(T)),
|
||||
_c(new T[rows*columns]) {
|
||||
LOG;
|
||||
memset(_c, 0, MEM_SIZE);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
Matrix(size_t rows, size_t columns, ARGS...t):
|
||||
Matrix(rows, columns) {
|
||||
LOG;
|
||||
assert(sizeof...(t)==SIZE);
|
||||
copy_args(_c, t...);
|
||||
}
|
||||
|
||||
Matrix(const Matrix& o): Matrix(o.ROWS, o.COLUMNS) {
|
||||
LOG;
|
||||
memcpy(_c, o._c, MEM_SIZE);
|
||||
}
|
||||
|
||||
///}
|
||||
|
||||
/// @name destruction
|
||||
///{
|
||||
|
||||
~Matrix() {
|
||||
delete[] _c;
|
||||
}
|
||||
|
||||
///}
|
||||
|
||||
/// @name operators
|
||||
///{
|
||||
|
||||
Matrix& operator=(T oc[]) {
|
||||
LOG;
|
||||
assert(sizeof(oc)==MEM_SIZE);
|
||||
memcpy(_c, oc, MEM_SIZE);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix& operator=(const Matrix& o) {
|
||||
LOG;
|
||||
if (o.ROWS!=ROWS&&o.COLUMNS!=COLUMNS) {
|
||||
delete[] _c;
|
||||
ROWS = o.ROWS;
|
||||
COLUMNS = o.COLUMNS;
|
||||
SIZE = o.SIZE;
|
||||
MEM_SIZE = o.MEM_SIZE;
|
||||
_c = new T[SIZE];
|
||||
}
|
||||
memcpy(_c, o._c, MEM_SIZE);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix& operator+=(const Matrix& o) {
|
||||
LOG;
|
||||
assert(o.ROWS==ROWS);
|
||||
assert(o.COLUMNS==COLUMNS);
|
||||
T *to((T*)(_c)+MEM_SIZE), *from((T*)(o._c)+MEM_SIZE);
|
||||
while (to>(T*)(_c)) *--to += *--from;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RowVector operator[](size_t row) {
|
||||
assert(row<ROWS);
|
||||
return RowVector(*this, _c+row*COLUMNS);
|
||||
}
|
||||
|
||||
const ConstRowVector operator[](size_t row) const {
|
||||
assert(row<ROWS);
|
||||
return ConstRowVector(*this, _c+row*COLUMNS);
|
||||
}
|
||||
|
||||
///}
|
||||
|
||||
//................................................................methods
|
||||
protected:
|
||||
|
||||
void copy_args(T*) {}
|
||||
template<typename ...ARGS>
|
||||
void copy_args(T* to, T t1, ARGS...t) {
|
||||
*to = t1;
|
||||
copy_args(++to, t...);
|
||||
}
|
||||
|
||||
//..............................................................variables
|
||||
protected:
|
||||
|
||||
T* _c;
|
||||
|
||||
};
|
||||
|
||||
template<typename T, size_t ROWS, size_t COLUMNS>
|
||||
Matrix<T, ROWS, COLUMNS> operator+(const Matrix<T, ROWS, COLUMNS>& m1, const Matrix<T, ROWS, COLUMNS>& m2) {
|
||||
LOG;
|
||||
Matrix<T, ROWS, COLUMNS> res(m1);
|
||||
return res+=m2;
|
||||
}
|
||||
|
||||
template<typename T, size_t ROWS, size_t COLUMNS>
|
||||
std::ostream& operator<<(std::ostream& s, const Matrix<T, ROWS, COLUMNS>& m) {
|
||||
LOG;
|
||||
for (size_t w = 0; w < m.ROWS; ++w) {
|
||||
for (size_t h = 0; h < m.COLUMNS;++h) {
|
||||
s<<m[w][h]<<' ';
|
||||
}
|
||||
s<<'\n';
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user