Commit 8da44451 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Resize abstraction for matrices and vectors

parent 3fec45ce
#pragma once
#include <dune/common/typeutilities.hh>
#include <amdis/common/ConceptsBase.hpp>
#include <amdis/common/Logical.hpp>
namespace AMDiS
{
namespace Concepts
{
namespace Definition
{
struct VectorResizable
{
template <class V>
auto requires_(V const& vec, Dune::PriorityTag<2>) -> decltype( const_cast<V&>(vec).resize(0u), 0);
template <class V>
auto requires_(V const& vec, Dune::PriorityTag<1>) -> decltype( const_cast<V&>(vec).change_dim(0u), 0);
};
struct MatrixResizable
{
template <class M>
auto requires_(M const& mat, Dune::PriorityTag<3>) -> decltype( const_cast<M&>(mat).resize(0u,0u), 0);
template <class M>
auto requires_(M const& mat, Dune::PriorityTag<2>) -> decltype( const_cast<M&>(mat).change_dim(0u,0u), 0);
template <class M>
auto requires_(M const& mat, Dune::PriorityTag<1>) -> decltype( const_cast<M&>(mat).setSize(0u,0u), 0);
};
}
/// Checks whether a vector can be resized by various resize methods
template <class Vector>
using VectorResizable_t = bool_t<models<Definition::VectorResizable(Vector, Dune::PriorityTag<42>)> >;
/// Checks whether a matrix can be resized by various resize methods
template <class Matrix>
using MatrixResizable_t = bool_t<models<Definition::MatrixResizable(Matrix, Dune::PriorityTag<42>)> >;
} // end namespace Concepts
#ifdef DOXYGEN
/// \brief Uniform vector resize, using either vector.resize() or vector.change_dim()
template <class Vector>
void resize(Vector& vec, std::size_t size);
/// \brief Uniform matrix resize, using either matrix.resize(), matrix.setSize() or matrix.change_dim()
template <class Matrix>
void resize(Matrix& mat, std::size_t r, std::size_t c);
#else
namespace Impl
{
template <class Vector,
class = void_t<decltype(std::declval<Vector&>().resize(0u))> >
void resize_impl(Vector& vec, std::size_t size, Dune::PriorityTag<2>)
{
vec.resize(size);
}
template <class Vector,
class = void_t<decltype(std::declval<Vector&>().change_dim(0u))> >
void resize_impl(Vector& vec, std::size_t size, Dune::PriorityTag<1>)
{
vec.change_dim(size);
}
template <class Vector>
void resize_impl(Vector& /*vec*/, std::size_t /*size*/, Dune::PriorityTag<0>)
{
/* do nothing */
}
}
template <class Vector>
void resize(Vector& vec, std::size_t size)
{
Impl::resize_impl(vec, size, Dune::PriorityTag<42>{});
}
namespace Impl
{
template <class Matrix,
class = void_t<decltype(std::declval<Matrix&>().resize(0u,0u))> >
void resize_impl(Matrix& mat, std::size_t rows, std::size_t cols, Dune::PriorityTag<3>)
{
mat.resize(rows, cols);
}
template <class Matrix,
class = void_t<decltype(std::declval<Matrix&>().change_dim(0u,0u))> >
void resize_impl(Matrix& mat, std::size_t rows, std::size_t cols, Dune::PriorityTag<2>)
{
mat.change_dim(rows, cols);
}
template <class Matrix,
class = void_t<decltype(std::declval<Matrix&>().setSize(0u,0u))> >
void resize_impl(Matrix& mat, std::size_t rows, std::size_t cols, Dune::PriorityTag<1>)
{
mat.setSize(rows, cols);
}
template <class Matrix>
void resize_impl(Matrix& /*mat*/, std::size_t /*rows*/, std::size_t /*cols*/, Dune::PriorityTag<0>)
{
/* do nothing */
}
}
template <class Matrix>
void resize(Matrix& mat, std::size_t rows, std::size_t cols)
{
Impl::resize_impl(mat, rows, cols, Dune::PriorityTag<42>{});
}
#endif
} // end namespace AMDiS
......@@ -55,6 +55,9 @@ dune_add_test(SOURCES ProblemStatTest.cpp
dune_add_test(SOURCES RangeTypeTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES ResizeTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES StringTest.cpp
LINK_LIBRARIES amdis)
......
#include <amdis/AMDiS.hpp>
#include <amdis/common/Resize.hpp>
using namespace AMDiS;
struct Vec1 { void resize(std::size_t) {} };
struct Vec2 { void change_dim(std::size_t) {} };
struct Vec3
{
void resize(std::size_t) {}
void change_dim(std::size_t) {}
};
struct Mat1 { void resize(std::size_t,std::size_t) {} };
struct Mat2 { void change_dim(std::size_t,std::size_t) {} };
struct Mat3 { void setSize(std::size_t,std::size_t) {} };
struct Mat4
{
void resize(std::size_t,std::size_t) {}
void change_dim(std::size_t,std::size_t) {}
void setSize(std::size_t,std::size_t) {}
};
struct NotResizable {};
int main(int argc, char** argv)
{
AMDiS::init(argc, argv);
Vec1 vec1;
Vec2 vec2;
Vec3 vec3;
resize(vec1, 1);
resize(vec2, 1);
resize(vec3, 1);
static_assert(Concepts::VectorResizable_t<Vec1>::value, "");
static_assert(Concepts::VectorResizable_t<Vec2>::value, "");
static_assert(Concepts::VectorResizable_t<Vec3>::value, "");
Mat1 mat1;
Mat2 mat2;
Mat3 mat3;
Mat4 mat4;
resize(mat1,1,1);
resize(mat2,1,1);
resize(mat3,1,1);
resize(mat4,1,1);
static_assert(Concepts::MatrixResizable_t<Mat1>::value, "");
static_assert(Concepts::MatrixResizable_t<Mat2>::value, "");
static_assert(Concepts::MatrixResizable_t<Mat3>::value, "");
static_assert(Concepts::MatrixResizable_t<Mat4>::value, "");
NotResizable notResizable;
resize(notResizable,1);
resize(notResizable,1,1);
static_assert(not Concepts::VectorResizable_t<NotResizable>::value, "");
static_assert(not Concepts::MatrixResizable_t<NotResizable>::value, "");
AMDiS::finalize();
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment