Liebe Gitlab-Nutzerin, lieber Gitlab-Nutzer,
es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Die Konten der externen Nutzer:innen sind über den Reiter "Standard" erreichbar.
Die Administratoren


Dear Gitlab user,
it is now possible to log in to our service using the ZIH login/LDAP. The accounts of external users can be accessed via the "Standard" tab.
The administrators

Commit c5398967 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Matrix, Vector and FixVec now follow the copy-and-swap idiom

parent 5fb3baff
......@@ -58,7 +58,7 @@ namespace AMDiS {
refinementPath(0),
refinementPathLength(0)
{
projection.set(NULL);
projection.set((Projection*)(NULL));
for (int i = 0; i < neighbourCoord.getSize(); i++)
neighbourCoord[i].init(mesh->getDim());
......
......@@ -413,40 +413,33 @@ namespace AMDiS {
WorldVector(InitType initType, const T& ini)
: super(Global::getGeo(WORLD), initType, ini)
{}
// /// Copy constructor for other of different value_type
// template <typename S>
// WorldVector(Vector<S> const& other)
// : super(Global::getGeo(WORLD), NO_INIT)
// {
// operator=(other);
// }
//
/// Copy constructor for other of same value_type
WorldVector(self const& other)
: super(other)
{}
/// Assignement operator
template <typename S>
inline self& operator=(const Vector<S>& rhs)
/// Copy assignement operator
self& operator=(self other)
{
this->setValues(rhs.getValArray());
swap(*this, other);
return *this;
}
/// Assignement operator
inline self& operator=(const self& rhs)
template <typename S>
self& operator=(const Vector<S>& other)
{
this->setValues(rhs.getValArray());
TEST_EXIT_DBG( other.getSize() == Global::getGeo(WORLD) )
("Wrong dimensions in assignment.\n");
this->setValues(other.getValArray());
return *this;
}
/// Sets all entries to scal
template <typename S>
typename enable_if<boost::is_convertible<S, T>, WorldVector<T> >::type &
typename enable_if<boost::is_convertible<S, T>, self>::type &
operator=(S scal)
{
this->set(scal);
......@@ -507,40 +500,35 @@ namespace AMDiS {
this->set(ini);
}
// /// Copy constructor for other of different value_type
// template <typename S>
// WorldMatrix(Matrix<S> const& other)
// : super(Global::getGeo(WORLD), Global::getGeo(WORLD))
// {
// this->setValues(other.getValArray());
// }
//
// /// Copy constructor
/// Copy constructor
WorldMatrix(self const& other)
: super(other)
{ }
/// Assignement operator
template <typename S>
inline self& operator=(const Matrix<S>& rhs)
/// Copy assignment operator
self& operator=(self other)
{
this->setValues(rhs.getValArray());
swap(*this, other);
return *this;
}
/// Assignement operator
inline self& operator=(const self& rhs)
/// Assignment operator
template <typename S>
self& operator=(const Matrix<S>& other)
{
this->setValues(rhs.getValArray());
TEST_EXIT_DBG( other.getNumOfRows() == Global::getGeo(WORLD) &&
other.getNumOfCols() == Global::getGeo(WORLD) )
("Wrong dimensions in assignment.\n");
this->setValues(other.getValArray());
return *this;
}
/// Assignement operator for scalars
/// Assignment operator for scalars
template <typename S>
typename enable_if<boost::is_convertible<S, T>, WorldMatrix<T> >::type &
operator=(S rhs)
operator=(S value)
{
this->set(rhs);
this->set(value);
return *this;
}
......
......@@ -41,13 +41,14 @@ namespace AMDiS {
TEST_EXIT_DBG(m.getNumRows() == this->getSize())("invalide size\n");
TEST_EXIT_DBG(v.getSize() == this->getSize())("invalide size\n");
T *mIt, *thisIt;
T const* mIt;
T* thisIt;
for (thisIt = this->begin(), mIt = m.begin();
thisIt != this->end();
thisIt++) {
*thisIt = 0;
for (T* vIt = v.begin(); vIt != v.end(); vIt++, mIt++)
for (T const* vIt = v.begin(); vIt != v.end(); vIt++, mIt++)
*thisIt += *vIt * *mIt;
}
}
......@@ -91,8 +92,8 @@ namespace AMDiS {
T *thisIt = this->begin();
for (T* v1It = v1.begin(); v1It != v1.end(); v1It++)
for (T* v2It = v2.begin(); v2It != v2.end(); v2It++, thisIt++)
for (T const* v1It = v1.begin(); v1It != v1.end(); v1It++)
for (T const* v2It = v2.begin(); v2It != v2.end(); v2It++, thisIt++)
*thisIt = *v1It * *v2It;
}
......
......@@ -42,8 +42,8 @@ namespace AMDiS {
elType(0),
deserializedNeighbourIndices(NULL)
{
neighbour.set(NULL);
projection.set(NULL);
neighbour.set((MacroElement*)(NULL));
projection.set((Projection*)(NULL));
}
......
......@@ -25,9 +25,9 @@
#ifndef AMDIS_MATRIXVECTOR_H
#define AMDIS_MATRIXVECTOR_H
#include <vector>
// #include <vector>
#include "Global.h"
#include "AMDiS_fwd.h"
// #include "AMDiS_fwd.h"
#include "Serializable.h"
#include "traits/basic.hpp" // not dependenciess on other AMDiS types
......@@ -43,23 +43,22 @@ namespace AMDiS {
typedef Vector self;
/// Constructor.
Vector(int i = 0)
: size(0),
valArray(NULL)
{
resize(i);
}
Vector(int s = 0)
: size(s),
valArray(size ? new T[size] : NULL)
{ }
/// Copy constructor.
Vector(self const& rhs)
Vector(self const& other)
: Serializable(),
size(rhs.getSize()),
valArray(new T[rhs.getSize()])
size(other.size),
valArray(size ? new T[size] : NULL)
{
setValues(rhs.getValArray());
setValues(other.valArray);
}
/// Copy constructor for other of different value_type
// TODO: notwendig?
template <typename S>
Vector(Vector<S> const& rhs)
: Serializable(),
......@@ -68,9 +67,18 @@ namespace AMDiS {
{
setValues(rhs.getValArray());
}
#if HAS_RVALUE_REFERENCES
/// move constructor
Vector(self&& other)
: Vector()
{
swap(*this, other);
}
#endif
/// Destructor.
virtual ~Vector()
~Vector()
{
if (valArray != NULL) {
delete [] valArray;
......@@ -96,74 +104,59 @@ namespace AMDiS {
/// Assignement operator
template <typename S>
inline self& operator=(Vector<S> const& rhs)
typename disable_if< boost::is_same<S, T>, self >::type &
operator=(Vector<S> const& other)
{
resize(rhs.getSize());
this->setValues(rhs.getValArray());
resize(other.getSize());
setValues(other.getValArray());
return *this;
}
inline self& operator=(self const& rhs)
/// copy assignment operator
self& operator=(self other)
{
resize(rhs.getSize());
this->setValues(rhs.getValArray());
swap(*this, other);
return *this;
}
/// Assignement operator for scalars
template <typename S>
typename enable_if<boost::is_convertible<S, T>, Vector<T> >::type &
operator=(const S& scal)
typename enable_if< boost::is_convertible<S, T>, Vector<T> >::type &
operator=(S value)
{
for (T *thisIt = this->begin(); thisIt != this->end(); ++thisIt)
*thisIt = scal;
set(value);
return *this;
}
/// Assignement operator
inline self& operator=(const T* vec)
{
this->setValues(vec);
setValues(vec);
return *this;
}
/// Sets all entries to scal.
template <typename S>
inline typename disable_if<and_<boost::is_integral<S>, boost::is_pointer<T> >, Vector<T>& >::type
set(S const& scal)
{
return *this = scal;
}
inline Vector<T>& set(T const& scal)
{
return *this = scal;
}
void setValues_aux(const T* values, true_) // trivially copyable
/// A swap function for Vector, used in the Copy-and-swap idiom
// need non-templated arguments in order to eliminate a friend declaration warning in gcc
friend void swap(Vector& first, Vector& second)
{
std::memcpy(valArray, values, sizeof(T)*size);
using std::swap; // enable ADL
swap(first.size, second.size);
swap(first.valArray, second.valArray);
}
/// Sets all entries to scal.
template <typename S>
void setValues_aux(const S* values, false_) // NOT trivially copyable
typename enable_if< boost::is_convertible<S, T> >::type
set(S value)
{
std::copy(values, values + size, valArray);
std::fill(begin(), end(), value);
}
/// Sets all entries.
template <typename S>
void setValues(const S* values)
{
typedef typename and_< boost::is_same<S,T>, traits::is_trivially_copyable<S> >::type use_memcpy;
setValues_aux(values, use_memcpy());
}
/// Sets all entries.
inline void fill(T value)
{
std::fill(valArray, valArray + size, value);
std::copy(values, values + size, valArray);
}
/// Comparison operator.
......@@ -172,11 +165,12 @@ namespace AMDiS {
if (size != rhs.size)
return false;
T *rhsIt, *thisIt;
T const* rhsIt;
T const* thisIt;
for (rhsIt = rhs.begin(), thisIt = this->begin();
rhsIt != rhs.end();
++rhsIt, ++thisIt)
if(*thisIt != *rhsIt)
if (*thisIt != *rhsIt)
return false;
return true;
......@@ -191,28 +185,24 @@ namespace AMDiS {
/// Access to the i-th vector element.
inline T& operator[](int i)
{
TEST_EXIT_DBG(i < size && i >= 0)("Invalid index %d!\n", i);
// TEST_EXIT_DBG(i < size && i >= 0)("Invalid index %d!\n", i);
return valArray[i];
}
/// Access to the i-th vector element for const vectors.
inline const T& operator[] (int i) const
{
TEST_EXIT_DBG(i < size && i >= 0)("Invalid index %d!\n", i);
// TEST_EXIT_DBG(i < size && i >= 0)("Invalid index %d!\n", i);
return valArray[i];
}
/// Returns pointer to the first vector element.
inline T *begin() const
{
return valArray;
}
inline T* begin() { return valArray; }
inline T const* begin() const { return valArray; }
/// Returns pointer after the last vector element.
inline T *end() const
{
return valArray + size;
}
inline T* end() { return valArray + size; }
inline T const* end() const { return valArray + size; }
/// Returns \ref size.
inline int getSize() const
......@@ -221,15 +211,8 @@ namespace AMDiS {
}
/// Returns \ref valArray as T-array
inline T* getValArray()
{
return valArray;
}
inline T const* getValArray() const
{
return valArray;
}
inline T* getValArray() { return valArray; }
inline T const* getValArray() const { return valArray; }
void print() const
{
......@@ -275,7 +258,7 @@ namespace AMDiS {
/// Default constructor.
Matrix()
: Vector<T>(0), rows(0), cols(0)
: super(0), rows(0), cols(0)
{}
/// Constructor.
......@@ -285,55 +268,74 @@ namespace AMDiS {
cols(c)
{}
/// copy constructor
Matrix(self const& other)
: super(other),
rows(other.getNumRows()),
cols(other.getNumCols())
{ }
#if HAS_RVALUE_REFERENCES
/// move constructor
Matrix(self&& other)
: Matrix()
{
swap(*this, other);
}
#endif
/// Changes the size of the matrix to newRows x newCols.
inline void resize(int newRows, int newCols)
{
if ((newRows != rows) || (newCols != cols)) {
Vector<T>::resize(newRows * newCols);
super::resize(newRows * newCols);
rows = newRows;
cols = newCols;
}
}
/// Assignement operator
template <typename S>
inline self& operator=(const Matrix<S>& rhs)
self& operator=(self other)
{
resize(rhs.getNumRows(), rhs.getNumCols());
this->setValues(rhs.getValArray());
swap(*this, other);
return *this;
}
inline self& operator=(self const& rhs)
/// Assignement operator
template <typename S>
inline self& operator=(const Matrix<S>& other)
{
resize(rhs.getNumRows(), rhs.getNumCols());
this->setValues(rhs.getValArray());
resize(other.getNumRows(), other.getNumCols());
this->setValues(other.getValArray());
return *this;
}
/// Assignement operator for scalars.
inline Matrix<T>& operator=(const T& scal)
self& operator=(T value)
{
Vector<T>::operator=(scal);
super::set(value);
return *this;
}
/// A swap function for Matrix, used in the Copy-and-swap idiom
// need non-templated arguments in order to eliminate a friend declaration warning in gcc
friend void swap(Matrix& first, Matrix& second)
{
using std::swap; // enable ADL
swap(first.rows, second.rows);
swap(first.cols, second.cols);
swap(static_cast<super&>(first), static_cast<super&>(second));
}
///
inline bool operator==(const Matrix<T>& rhs) const
/// Comparison operator.
inline bool operator==(const self& rhs) const
{
if (rows != rhs.getNumRows()) return false;
if (cols != rhs.getNumCols()) return false;
return Vector<T>::operator == (rhs);
return super::operator==(rhs);
}
/// Comparison operator.
inline bool operator!=(const Matrix<T>& rhs) const
inline bool operator!=(const self& rhs) const
{
return !(*this == rhs);
}
......@@ -374,18 +376,6 @@ namespace AMDiS {
return cols;
}
/// Returns \ref rows.
// inline int getSize() const
// {
// return rows*cols;
// }
/// Returns pointer after the last vector element.
// inline T *end() const
// {
// return this->valArray + (cols * rows);
// }
void print() const
{
std::cout << this->rows << " x " << this->cols << " matrix: " << std::endl;
......
......@@ -39,7 +39,9 @@ namespace AMDiS {
TEST_EXIT_DBG(m.getNumCols() == v.getSize())("m and v not compatible\n");
TEST_EXIT_DBG(v.getSize() == result.getSize())("wrong result size\n");
T *resultIt, *mIt, *vIt;
T *resultIt;
T const* mIt;
T const* vIt;
for (resultIt = result.begin(), mIt = m.begin();
resultIt != result.end();
......@@ -58,7 +60,9 @@ namespace AMDiS {
{
TEST_EXIT_DBG(v1.getSize() == v2.getSize())("invalid size in test v1 == v2\n");
TEST_EXIT_DBG(v2.getSize() == result.getSize())("invalid size in test v2 == result\n");
T *v1It, *v2It, *resultIt;
T const* v1It;
T const* v2It;
T* resultIt;
for (v1It = v1.begin(), v2It = v2.begin(), resultIt = result.begin();
v1It != v1.end();
++v1It, ++v2It, ++resultIt)
......@@ -75,7 +79,8 @@ namespace AMDiS {
{
TEST_EXIT_DBG(v.getSize() == result.getSize())("invalid size\n");
T *vIt, *resultIt;
T const* vIt;
T* resultIt;
for (vIt = v.begin(), resultIt = result.begin();
vIt != v.end();
++vIt, ++resultIt)
......@@ -89,7 +94,8 @@ namespace AMDiS {
inline const Vector<T>& add(const Vector<T>& v, const T& scal, Vector<T>& result)
{
TEST_EXIT_DBG(v.getSize() == result.getSize())("invalid size\n");
T *vIt, *resultIt;
T const* vIt;
T* resultIt;
for (vIt = v.begin(), resultIt = result.begin();
vIt != v.end();
++vIt, ++resultIt)
......@@ -105,7 +111,8 @@ namespace AMDiS {
Vector<T> &y)
{
TEST_EXIT_DBG(x.getSize() == y.getSize())("invalid size\n");
T *xIt, *yIt;
T const* xIt;
T* yIt;
for (xIt = x.begin(), yIt = y.begin();
xIt != x.end();
++xIt, ++yIt)
......@@ -140,8 +147,8 @@ namespace AMDiS {
typename traits::mult_type<T,S>::type result;
nullify(result);
T *v1It;
S *v2It;
T const* v1It;
S const* v2It;
for (v1It = v1.begin(), v2It = v2.begin();
v1It != v1.end();
++v1It, ++v2It)
......@@ -220,7 +227,7 @@ namespace AMDiS {
Vector<T>& operator+=(Vector<T>& x, const Vector<S>& y)
{
T *xIt;
S *yIt;
S const* yIt;
for (xIt = x.begin(), yIt = y.begin(); xIt != x.end(); ++xIt, ++yIt)
*xIt += *yIt;
return x;
......@@ -238,8 +245,8 @@ namespace AMDiS {
template <typename T, typename S>
Vector<T>& operator-=(Vector<T>& x, const Vector<S>& y)
{
T *xIt;
S *yIt;
T* xIt;
S const* yIt;
for (xIt = x.begin(), yIt = y.begin(); xIt != x.end(); ++xIt, ++yIt)
*xIt -= *yIt;
return x;
......@@ -261,7 +268,7 @@ namespace AMDiS {
inline T norm(const Vector<T> *v)
{
T result; nullify(result);
for (T* vIt = v->begin(); vIt != v->end(); ++vIt)
for (T const* vIt = v->begin(); vIt != v->end(); ++vIt)
result += *vIt * *vIt;
return std::sqrt(result);
}
......@@ -300,8 +307,8 @@ namespace AMDiS {
typename traits::mult_type<T,S>::type result;
nullify(result);
T *v1It;
S *v2It;
T const* v1It;
S const* v2It;
for (v1It = v1.begin(), v2It = v2.begin();
v1It != v1.end();
++v1It, ++v2It)
......@@ -457,7 +464,7 @@ namespace AMDiS {
WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<S>& m2)
{
T* m1It;
S* m2It;
S const* m2It;
for (m1It = m1.begin(), m2It = m2.begin();
m1It != m1.end();
m1It++, m2It++)
......@@ -479,7 +486,7 @@ namespace AMDiS {