Commit 975fc4c7 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

replaced implementation of static Size template with generic constexpr function

parent cfa2b1d9
......@@ -32,7 +32,7 @@ namespace AMDiS
constexpr decltype(auto) apply(F&& f, Tuple&& t)
{
return Impl_::apply_impl(FWD(f), FWD(t),
std::make_index_sequence<Size_v<std::remove_reference_t<Tuple>>>{});
std::make_index_sequence<static_size_v<Tuple>>{});
}
template <class Functor, class... Args>
......
......@@ -41,7 +41,7 @@ namespace AMDiS
template <class Tuple, class Functor>
constexpr void for_each(Tuple&& tuple, Functor&& f)
{
Tools::for_each(std::make_index_sequence<Size_v<std::remove_reference_t<Tuple>>>{}, FWD(tuple), FWD(f));
Tools::for_each(std::make_index_sequence<static_size_v<Tuple>>{}, FWD(tuple), FWD(f));
}
......
......@@ -2,13 +2,11 @@
#include <utility>
#include <dune/common/indices.hh>
#include <dune/common/rangeutilities.hh>
#include <dune/common/typeutilities.hh>
#include <amdis/common/Access.hpp>
#include <amdis/common/Concepts.hpp>
#include <amdis/common/Index.hpp>
#include <amdis/common/StaticSize.hpp>
namespace AMDiS
......@@ -33,10 +31,10 @@ namespace AMDiS
* of entries as integer value. Otherwise a `std::integral_constant` is returned.
**/
template <class Vector>
implementation-defined hybridSize(Vector const& vec);
implementation-defined hybrid_size(Vector const& vec);
/// Return either an IntegralRange or a StaticIntegralRange of the indices to
/// access the vector, depending on the type of \ref hybridSize(vec)
/// access the vector, depending on the type of \ref hybrid_size(vec)
template <class Vector>
implementation-defined hybridElements(Vector const& vec);
......@@ -46,10 +44,10 @@ namespace AMDiS
* of rows as integer value. Otherwise a `std::integral_constant` is returned.
**/
template <class Matrix>
implementation-defined hybridNumRows(Matrix const& mat);
implementation-defined hybrid_num_rows(Matrix const& mat);
/// Return either an IntegralRange or a StaticIntegralRange of the indices to
/// access the rows of the matrix, depending on the type of \ref hybridNumRows(mat)
/// access the rows of the matrix, depending on the type of \ref hybrid_num_rows(mat)
template <class Matrix>
implementation-defined hybridRows(Matrix const& mat);
......@@ -59,10 +57,10 @@ namespace AMDiS
* of columns as integer value. Otherwise a `std::integral_constant` is returned.
**/
template <class Matrix>
implementation-defined hybridNumCols(Matrix const& mat);
implementation-defined hybrid_num_cols(Matrix const& mat);
/// Return either an IntegralRange or a StaticIntegralRange of the indices to
/// access the columns of the matrix, depending on the type of \ref hybridNumCols(mat)
/// access the columns of the matrix, depending on the type of \ref hybrid_num_cols(mat)
template <class Matrix>
implementation-defined hybridCols(Matrix const& mat);
#else
......@@ -71,29 +69,32 @@ namespace AMDiS
{
template <class Vector,
REQUIRES(Concepts::DynamicVectorAccessible_t<Vector>::value)>
auto hybridSize(Vector const& vec, Dune::PriorityTag<3>)
auto hybrid_size(Vector const& vec, Dune::PriorityTag<2>)
-> decltype(vec.size()) { return vec.size(); }
template <class Vector,
REQUIRES(not Concepts::DynamicVectorAccessible_t<Vector>::value)>
constexpr index_t<Vector::dimension> hybridSize(Vector const& vec, Dune::PriorityTag<2>) { return {}; }
REQUIRES(Concepts::DynamicVectorAccessible_t<Vector>::value)>
auto hybrid_size(Vector const& vec, Dune::PriorityTag<1>)
-> decltype(size(vec)) { return size(vec); }
template <class Vector,
REQUIRES(not Concepts::DynamicVectorAccessible_t<Vector>::value)>
constexpr Size_t<Vector> hybridSize(Vector const& vec, Dune::PriorityTag<1>) { return {}; }
template <class Vector>
auto hybrid_size(Vector const& vec, Dune::PriorityTag<0>)
{
return AMDiS::static_size(vec);
}
} // end namespace Impl
template <class Vector>
auto hybridSize(Vector const& vec)
auto hybrid_size(Vector const& vec)
{
return Impl::hybridSize(vec, Dune::PriorityTag<42>{});
return Impl::hybrid_size(vec, Dune::PriorityTag<42>{});
}
template <class Vector>
auto hybridElements(Vector const& vec)
{
return Dune::range(hybridSize(vec));
return Dune::range(hybrid_size(vec));
}
......@@ -101,39 +102,42 @@ namespace AMDiS
{
template <class Matrix,
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybridNumRows(Matrix const& mat, Dune::PriorityTag<5>)
auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<5>)
-> decltype(mat.num_rows()) { return mat.num_rows(); }
template <class Matrix,
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybridNumRows(Matrix const& mat, Dune::PriorityTag<4>)
auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<4>)
-> decltype(mat.N()) { return mat.N(); }
template <class Matrix,
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybridNumRows(Matrix const& mat, Dune::PriorityTag<3>)
auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<3>)
-> decltype(mat.rows()) { return mat.rows(); }
template <class Matrix,
REQUIRES(not Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
constexpr index_t<Matrix::rows> hybridNumRows(Matrix const& mat, Dune::PriorityTag<2>) { return {}; }
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<2>)
-> decltype(num_rows(mat)) { return num_rows(mat); }
template <class Matrix,
REQUIRES(not Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
constexpr Rows_t<Matrix> hybridNumRows(Matrix const& mat, Dune::PriorityTag<1>) { return {}; }
template <class Matrix>
auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<0>)
{
return AMDiS::static_num_rows(mat);
}
} // end namespace Impl
template <class Matrix>
auto hybridNumRows(Matrix const& mat)
auto hybrid_num_rows(Matrix const& mat)
{
return Impl::hybridNumRows(mat, Dune::PriorityTag<42>{});
return Impl::hybrid_num_rows(mat, Dune::PriorityTag<42>{});
}
template <class Matrix>
auto hybridRows(Matrix const& mat)
{
return Dune::range(hybridNumRows(mat));
return Dune::range(hybrid_num_rows(mat));
}
......@@ -141,39 +145,42 @@ namespace AMDiS
{
template <class Matrix,
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybridNumCols(Matrix const& mat, Dune::PriorityTag<5>)
auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<5>)
-> decltype(mat.num_rows()) { return mat.num_cols(); }
template <class Matrix,
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybridNumCols(Matrix const& mat, Dune::PriorityTag<4>)
auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<4>)
-> decltype(mat.M()) { return mat.M(); }
template <class Matrix,
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybridNumCols(Matrix const& mat, Dune::PriorityTag<3>)
auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<3>)
-> decltype(mat.cols()) { return mat.cols(); }
template <class Matrix,
REQUIRES(not Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
constexpr index_t<Matrix::cols> hybridNumCols(Matrix const& mat, Dune::PriorityTag<2>) { return {}; }
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<2>)
-> decltype(num_cols(mat)) { return num_cols(mat); }
template <class Matrix,
REQUIRES(not Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
constexpr Cols_t<Matrix> hybridNumCols(Matrix const& mat, Dune::PriorityTag<1>) { return {}; }
template <class Matrix>
auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<0>)
{
return AMDiS::static_num_cols(mat);
}
} // end namespace Impl
template <class Matrix>
auto hybridNumCols(Matrix const& mat)
auto hybrid_num_cols(Matrix const& mat)
{
return Impl::hybridNumCols(mat, Dune::PriorityTag<42>{});
return Impl::hybrid_num_cols(mat, Dune::PriorityTag<42>{});
}
template <class Matrix>
auto hybridCols(Matrix const& mat)
{
return Dune::range(hybridNumCols(mat));
return Dune::range(hybrid_num_cols(mat));
}
#endif // DOXYGEN
......
......@@ -72,7 +72,7 @@ namespace AMDiS
/// Assignment of real number to all tuple elements
MultiTypeMatrix& operator=(real_type value)
{
Tools::for_each(*this, [value](auto& fv) { fv = value; });
Tools::for_each(as_tuple(), [value](auto& fv) { fv = value; });
return *this;
}
......@@ -93,44 +93,44 @@ namespace AMDiS
// Scaling of all tuple elements by a constant value
MultiTypeMatrix& operator*=(real_type value)
{
Tools::for_each(*this, [value](auto& fv) { fv *= value; });
Tools::for_each(as_tuple(), [value](auto& fv) { fv *= value; });
return *this;
}
// Scaling of all tuple elements by the inverse of a constant value
MultiTypeMatrix& operator/=(real_type value)
{
Tools::for_each(*this, [value](auto& fv) { fv /= value; });
Tools::for_each(as_tuple(), [value](auto& fv) { fv /= value; });
return *this;
}
/// Const access to the tuple elements
template <std::size_t I, std::size_t J>
decltype(auto) operator()(const index_t<I>&, const index_t<J>&) const
decltype(auto) operator()(index_t<I> const i, index_t<J> const j) const
{
return std::get<J>(std::get<I>(*this));
return (*this)[i][j];
}
/// Mutable access to the tuple elements
template <std::size_t I, std::size_t J>
decltype(auto) operator()(const index_t<I>&, const index_t<J>&)
decltype(auto) operator()(index_t<I> const i, index_t<J> const j)
{
return std::get<J>(std::get<I>(*this));
return (*this)[i][j];
}
/// Const access to the rows
template <std::size_t I>
decltype(auto) operator[](const index_t<I>&) const
decltype(auto) operator[](index_t<I> const) const
{
return std::get<I>(*this);
return std::get<I>(as_tuple());
}
/// Mutable access to the rows
template <std::size_t I>
decltype(auto) operator[](const index_t<I>&)
decltype(auto) operator[](index_t<I> const)
{
return std::get<I>(*this);
return std::get<I>(as_tuple());
}
/// Return number of elements of the tuple
......@@ -149,17 +149,10 @@ namespace AMDiS
{
return rows;
}
};
namespace Impl
{
template <class... Rows>
struct RowsImpl<MultiTypeMatrix<Rows...>>
: std::integral_constant<std::size_t, sizeof...(Rows) > {};
template <class Row0, class... Rows>
struct ColsImpl<MultiTypeMatrix<Row0, Rows...>>
: SizeImpl<Row0> {};
}
private:
std::tuple<Rows...>& as_tuple() { return *this; }
std::tuple<Rows...> const& as_tuple() const { return *this; }
};
} // end namespace AMDiS
......@@ -65,50 +65,50 @@ namespace AMDiS
/// Assignment of real number to all tuple elements
MultiTypeVector& operator=(real_type value)
{
Tools::for_each(*this, [value](auto& fv) { fv = value; });
Tools::for_each(as_tuple(), [value](auto& fv) { fv = value; });
return *this;
}
// Compound assignment operator +=
MultiTypeVector& operator+=(MultiTypeVector const& that)
{
Tools::for_range<0,dimension>([&that,this](auto const _i) { (*this)[_i] += that[_i]; });
Tools::for_range<0,dimension>([&that,this](auto const i) { (*this)[i] += that[i]; });
return *this;
}
// Compound assignment operator -=
MultiTypeVector& operator-=(MultiTypeVector const& that)
{
Tools::for_range<0,dimension>([&that,this](auto const _i) { (*this)[_i] -= that[_i]; });
Tools::for_range<0,dimension>([&that,this](auto const i) { (*this)[i] -= that[i]; });
return *this;
}
// Scaling of all tuple elements by a constant value
MultiTypeVector& operator*=(real_type value)
{
Tools::for_each(*this, [value](auto& fv) { fv *= value; });
Tools::for_each(as_tuple(), [value](auto& fv) { fv *= value; });
return *this;
}
// Scaling of all tuple elements by the inverse of a constant value
MultiTypeVector& operator/=(real_type value)
{
Tools::for_each(*this, [value](auto& fv) { fv /= value; });
Tools::for_each(as_tuple(), [value](auto& fv) { fv /= value; });
return *this;
}
/// Const access to the tuple elements
template <std::size_t I>
decltype(auto) operator[](const index_t<I>&) const
decltype(auto) operator[](index_t<I> const) const
{
return std::get<I>(*this);
return std::get<I>(as_tuple());
}
/// Mutable access to the tuple elements
template <std::size_t I>
decltype(auto) operator[](const index_t<I>&)
decltype(auto) operator[](index_t<I> const)
{
return std::get<I>(*this);
return std::get<I>(as_tuple());
}
/// Const access to the vector using multi-indices
......@@ -132,13 +132,10 @@ namespace AMDiS
{
return dimension;
}
};
namespace Impl
{
template <class... Ts>
struct SizeImpl<MultiTypeVector<Ts...>>
: std::integral_constant<std::size_t, sizeof...(Ts) > {};
}
private:
std::tuple<FV...>& as_tuple() { return *this; }
std::tuple<FV...> const& as_tuple() const { return *this; }
};
} // end namespace AMDiS
......@@ -86,15 +86,24 @@ namespace AMDiS
{
template <>
struct SizeImpl<Dune::Float128>
: std::integral_constant<std::size_t, 1> {};
{
static constexpr auto eval(Dune::Float128)
-> std::integral_constant<std::size_t, 1> { return {}; }
};
template <>
struct RowsImpl<Dune::Float128>
: std::integral_constant<std::size_t, 1> {};
struct NumRowsImpl<Dune::Float128>
{
static constexpr auto eval(Dune::Float128)
-> std::integral_constant<std::size_t, 1> { return {}; }
};
template <>
struct ColsImpl<Dune::Float128>
: std::integral_constant<std::size_t, 1> {};
struct NumColsImpl<Dune::Float128>
{
static constexpr auto eval(Dune::Float128)
-> std::integral_constant<std::size_t, 1> { return {}; }
};
} // end namespace Impl
......
......@@ -39,11 +39,6 @@ namespace AMDiS
template <std::size_t I, class Int, Int begin, Int end>
constexpr auto get(range_impl<Int, begin, end> const& r) { return r[index_<I>]; }
/// Return the size of the range
template <class Int, Int I, Int J>
struct SizeImpl<range_impl<Int,I,J>>
: std::integral_constant<std::size_t, std::size_t(J-I)> {};
} // end namespace Impl
template <std::size_t I, std::size_t J>
......
......@@ -4,152 +4,276 @@
#include <tuple>
#include <type_traits>
#include <dune/common/typeutilities.hh>
#include <amdis/common/TypeTraits.hpp>
namespace Dune
{
// forward declarations
template <class T, int N, int M>
class FieldMatrix;
template <class T, int N>
class FieldVector;
template <class... Ts>
class TupleVector;
template <class Row0, class... Rows>
class MultiTypeBlockMatrix;
template <class... Ts>
class MultiTypeBlockVector;
}
namespace Eigen
{
template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
class Matrix;
}
#if HAVE_MTL
#include <boost/numeric/mtl/operation/static_size.hpp>
#endif
namespace AMDiS
{
namespace Impl
{
template <class Tuple, class = void>
struct SizeImpl : std::integral_constant<std::size_t, 0> {};
template <class... Args>
struct SizeImpl<std::tuple<Args...>>
: std::integral_constant<std::size_t, sizeof...(Args) > {};
template <class Arg0, class Arg1>
struct SizeImpl<std::pair<Arg0, Arg1>>
: std::integral_constant<std::size_t, 2> {};
template <class T, std::size_t N>
struct SizeImpl<std::array<T,N>>
: std::integral_constant<std::size_t, N> {};
template <class T, int N>
struct SizeImpl<Dune::FieldVector<T,N>>
: std::integral_constant<std::size_t, N> {};
template <class T, int N, int M>
struct SizeImpl<Dune::FieldMatrix<T,N,M>>
: std::integral_constant<std::size_t, N*M> {};
template <class... Ts>
struct SizeImpl<Dune::TupleVector<Ts...>>
: std::integral_constant<std::size_t, sizeof...(Ts)> {};
template <class... Ts>
struct SizeImpl<Dune::MultiTypeBlockVector<Ts...>>
: std::integral_constant<std::size_t, sizeof...(Ts)> {};
template <class T, int N, int... opts>
struct SizeImpl<Eigen::Matrix<T,N,1,opts...>>
: std::integral_constant<std::size_t, (N >= 0 ? std::size_t(N) : 0u)> {};
template <class T, int N, int... opts>
struct SizeImpl<Eigen::Matrix<T,1,N,opts...>>
: std::integral_constant<std::size_t, (N >= 0 ? std::size_t(N) : 0u)> {};
// Specialization for arithmetic types
template <class T>
struct SizeImpl<T, std::enable_if_t<std::is_arithmetic<T>::value> >
: std::integral_constant<std::size_t, 1> {};
template <class Container>
struct SizeImpl
{
#if HAVE_MTL
// MTL4: Try if a mtl::static_size is specialized for class
template <class T>
static constexpr auto eval(T const&, Dune::PriorityTag<6>)
-> decltype(std::integral_constant<std::size_t,(mtl::static_num_rows<T>::value * mtl::static_num_cols<T>::value)>{})
{
return {};
}
#endif
// Eigen: Try if a static SizeAtCompileTime constant is specified for class
template <class T>
static constexpr auto eval(T const&, Dune::PriorityTag<5>)
-> decltype(std::integral_constant<std::size_t,T::SizeAtCompileTime>{})
{
return {};
}
// Try if tuple_size is implemented for class
template <class T>
static constexpr auto eval(T const&, Dune::PriorityTag<4>)
-> decltype(std::integral_constant<std::size_t,std::tuple_size<T>::value>{})
{
return {};
}
// Try if a static dimension constant is specified for class
template <class T>
static constexpr auto eval(T const&, Dune::PriorityTag<3>)
-> decltype(std::integral_constant<std::size_t,T::dimension>{})
{
return {};
}
// Try if a static rows and cols constants are specified for class
template <class T>
static constexpr auto eval(T const&, Dune::PriorityTag<2>)
-> decltype(std::integral_constant<std::size_t,(T::rows * T::cols)>{})
{
return {};
}
// Try if there's a static constexpr size()
template <class T>
static constexpr auto eval(T const&, Dune::PriorityTag<1>)
-> decltype(std::integral_constant<std::size_t,T::size()>{})
{
return {};
}
// Arithmetic types have size 1 otherwise size is 0
template <class T>
static constexpr auto eval(T const&, Dune::PriorityTag<0>)
-> decltype(std::integral_constant<std::size_t, (std::is_arithmetic<T>::value ? 1 : 0)>{})
{
return {};
}
static constexpr auto eval(Container const& container)
{
return eval(container, Dune::PriorityTag<42>{});
}
};
} // end namespace Impl
/// Get the number of elements in a tuple / pair / array / ...
template <class T>
constexpr std::size_t Size_v = Impl::SizeImpl<remove_cvref_t<T>>::value;
template <class T>
using Size_t = Impl::SizeImpl<remove_cvref_t<T>>;
namespace Impl
/**
* \brief Return a static constant size of the container
*
* \param container Container whose size is queried
* \return Size of t
*