Skip to content
Snippets Groups Projects
Commit 8da44451 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Resize abstraction for matrices and vectors

parent 3fec45ce
No related branches found
No related tags found
1 merge request!44Resize abstraction for matrices and vectors
#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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment