Commit 14a25e76 authored by Praetorius, Simon's avatar Praetorius, Simon

Merge branch 'feature/macros' into 'develop'

introduce macros FWD and TYPEOF to reducine typing of std::forward and decltype

See merge request spraetor/dune-amdis!90
parents 43e0a683 227d7857
Pipeline #1774 canceled with stage
......@@ -138,7 +138,7 @@ namespace AMDiS
template <class LocalContext, class Operator, class... Nodes>
auto makeAssembler(Operator&& op, Nodes const&...)
{
return Assembler<LocalContext, Underlying_t<Operator>, Nodes...>{std::forward<Operator>(op)};
return Assembler<LocalContext, Underlying_t<Operator>, Nodes...>{FWD(op)};
}
} // end namespace AMDiS
......@@ -82,8 +82,7 @@ namespace AMDiS
}
};
using NodeDataTransferContainer = std::decay_t<decltype(
makeTreeContainer<Tree, NDT>(std::declval<const Tree&>(), NDT()))>;
using NodeDataTransferContainer = TYPEOF(makeTreeContainer<Tree, NDT>(std::declval<const Tree&>(), NDT()));
// Returns the Node's NodeElementData
struct NodeElementData
......@@ -97,8 +96,7 @@ namespace AMDiS
}
};
using ElementData = std::decay_t<decltype(
makeTreeContainer<Tree, NodeElementData>(std::declval<const Tree&>(), NodeElementData()))>;
using ElementData = TYPEOF(makeTreeContainer<Tree, NodeElementData>(std::declval<const Tree&>(), NodeElementData()));
public:
// Container with data that persists during grid adaptation
......
......@@ -41,16 +41,16 @@ namespace AMDiS
template <class BM, class Values,
REQUIRES(Concepts::Functor<Values, Range(Domain)>) >
DirichletBC(BM&& boundaryManager, BoundaryType id, Values&& values)
: Super(std::forward<BM>(boundaryManager), id)
, values_(std::forward<Values>(values))
: Super(FWD(boundaryManager), id)
, values_(FWD(values))
{}
template <class Predicate, class Values,
REQUIRES(Concepts::Functor<Predicate, bool(Domain)>),
REQUIRES(Concepts::Functor<Values, Range(Domain)>)>
DirichletBC(Predicate&& predicate, Values&& values)
: predicate_(std::forward<Predicate>(predicate))
, values_(std::forward<Values>(values))
: predicate_(FWD(predicate))
, values_(FWD(values))
{}
template <class Intersection>
......
......@@ -70,7 +70,7 @@ namespace AMDiS
**/
template <class GF>
GridFunctionOperatorBase(GF&& gridFct, int termOrder)
: gridFct_(std::forward<GF>(gridFct))
: gridFct_(FWD(gridFct))
, termOrder_(termOrder)
{}
......@@ -80,7 +80,7 @@ namespace AMDiS
{
using ctype = typename Geometry::ctype;
quadFactory_.emplace(
makeQuadratureFactory<ctype, LocalContext::mydimension, LocalFunction>(std::forward<PreQuadFactory>(pre)));
makeQuadratureFactory<ctype, LocalContext::mydimension, LocalFunction>(FWD(pre)));
}
protected:
......@@ -157,14 +157,14 @@ namespace AMDiS
template <class... Args,
std::enable_if_t<Dune::Std::is_detected<Constructable, Transposed, Args...>::value, int> = 0>
GridFunctionOperatorTransposed(Args&&... args)
: transposedOp_(std::forward<Args>(args)...)
: transposedOp_(FWD(args)...)
{}
/// Redirects the setQuadFactory call top the transposed operator
template <class PreQuadFactory>
void setQuadFactory(PreQuadFactory&& pre)
{
transposedOp_.setQuadFactory(std::forward<PreQuadFactory>(pre));
transposedOp_.setQuadFactory(FWD(pre));
}
private:
......@@ -210,9 +210,8 @@ namespace AMDiS
template <class Tag, class Expr, class... QuadratureArgs>
auto makeOperator(Tag tag, Expr&& expr, QuadratureArgs&&... args)
{
auto pqf = makePreQuadratureFactory(std::forward<QuadratureArgs>(args)...);
using PreGridFctOp = PreGridFunctionOperator<Tag, std::decay_t<Expr>, decltype(pqf)>;
return PreGridFctOp{tag, std::forward<Expr>(expr), std::move(pqf)};
auto pqf = makePreQuadratureFactory(FWD(args)...);
return PreGridFunctionOperator<Tag, TYPEOF(expr), TYPEOF(pqf)>{tag, FWD(expr), std::move(pqf)};
}
/** @} **/
......@@ -238,9 +237,8 @@ namespace AMDiS
template <class Context, class Tag, class GF, class QF>
auto makeGridFunctionOperator(Tag tag, GF&& gf, QF&& qf)
{
using GridFctOp = GridFunctionOperator<Tag, Context, std::decay_t<GF>>;
GridFctOp gfo{tag, std::forward<GF>(gf)};
gfo.setQuadFactory(std::forward<QF>(qf));
GridFunctionOperator<Tag, Context, TYPEOF(gf)> gfo{tag, FWD(gf)};
gfo.setQuadFactory(FWD(qf));
return gfo;
}
......
......@@ -11,9 +11,9 @@ namespace AMDiS
template <class GF, class GridView, class QuadProvider>
auto integrateImpl(GF&& gf, GridView const& gridView, QuadProvider makeQuad)
{
auto localFct = localFunction(std::forward<GF>(gf));
auto localFct = localFunction(FWD(gf));
using GridFct = std::decay_t<GF>;
using GridFct = remove_cvref_t<GF>;
using Range = typename GridFct::Range;
Range result(0);
......@@ -34,7 +34,7 @@ namespace AMDiS
template <class GF, class GridView, class QuadProvider>
auto integrateImpl(GF&& gf, GridView const& gv, QuadProvider makeQuad, std::true_type)
{
return integrateImpl(std::forward<GF>(gf), gv, makeQuad);
return integrateImpl(FWD(gf), gv, makeQuad);
}
template <class GF, class GV, class QP>
......@@ -55,10 +55,10 @@ namespace AMDiS
template <class Expr, class GridView>
auto integrate(Expr&& expr, GridView const& gridView)
{
auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), gridView);
auto&& gridFct = makeGridFunction(FWD(expr), gridView);
// test whether the gridFct model `Concepts::HasLocalFunctionOrder`
using GF = std::decay_t<decltype(gridFct)>;
using GF = TYPEOF(gridFct);
static const bool expr_has_order = Concepts::HasLocalFunctionOrder<GF>;
static_assert(expr_has_order,
"Polynomial degree of expression can not be deduced. You need to provide an explicit value for the quadrature degree or a quadrature rule in `integrate()`.");
......@@ -66,8 +66,7 @@ namespace AMDiS
using Rules = Dune::QuadratureRules<typename GridView::ctype, GridView::dimension>;
auto makeQuad = [](auto&& t, auto&& lf) { return Rules::rule(t, order(lf)); };
return Impl::integrateImpl(std::forward<decltype(gridFct)>(gridFct), gridView, makeQuad,
std::integral_constant<bool,expr_has_order>{});
return Impl::integrateImpl(FWD(gridFct), gridView, makeQuad, bool_<expr_has_order>);
}
......@@ -83,9 +82,8 @@ namespace AMDiS
class QuadratureRule = Dune::QuadratureRule<typename GridView::ctype, GridView::dimension>>
auto integrate(Expr&& expr, GridView const& gridView, QuadratureRule const& quad)
{
auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), gridView);
return Impl::integrateImpl(std::forward<decltype(gridFct)>(gridFct), gridView,
[&](auto&&, auto&&) { return quad; });
auto&& gridFct = makeGridFunction(FWD(expr), gridView);
return Impl::integrateImpl(FWD(gridFct), gridView, [&](auto&&, auto&&) { return quad; });
}
......@@ -102,8 +100,8 @@ namespace AMDiS
{
using Rules = Dune::QuadratureRules<typename GridView::ctype, GridView::dimension>;
auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), gridView);
return Impl::integrateImpl(std::forward<decltype(gridFct)>(gridFct), gridView,
auto&& gridFct = makeGridFunction(FWD(expr), gridView);
return Impl::integrateImpl(FWD(gridFct), gridView,
[&](auto const& type, auto&&) { return Rules::rule(type, degree, qt); });
}
......
......@@ -8,6 +8,7 @@
#include <dune/grid/common/grid.hh>
#include <amdis/common/ConceptsBase.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/gridfunctions/GridFunctionConcepts.hpp>
......@@ -382,7 +383,7 @@ namespace AMDiS
template <class GF>
GridFunctionMarker(std::string const& name, std::shared_ptr<Grid> const& grid, GF&& gf)
: Super{name, grid}
, gridFct_{makeGridFunction(std::forward<GF>(gf), grid->leafGridView())}
, gridFct_{makeGridFunction(FWD(gf), grid->leafGridView())}
{}
/// \brief Implementation of \ref Marker::markElement. Does nothing since marking is
......@@ -402,11 +403,10 @@ namespace AMDiS
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
// Deduction guide for GridFunctionMarker class
template <class Grid, class PreGridFct>
GridFunctionMarker(std::string const& name, std::shared_ptr<Grid> const& grid,
PreGridFct&& preGridFct)
template <class Grid, class GF>
GridFunctionMarker(std::string const& name, std::shared_ptr<Grid> const& grid, GF&& gf)
-> GridFunctionMarker<Grid,
std::decay_t<decltype(makeGridFunction(std::forward<PreGridFct>(preGridFct), grid->leafGridView()))>>;
TYPEOF( makeGridFunction(FWD(gf), grid->leafGridView()) )>;
#endif
// Generator function for GridFunctionMarker class
......@@ -414,9 +414,8 @@ namespace AMDiS
auto makeGridFunctionMarker(std::string const& name, std::shared_ptr<Grid> const& grid,
PreGridFct&& preGridFct)
{
auto gridFct = makeGridFunction(std::forward<PreGridFct>(preGridFct), grid->leafGridView());
using GridFct = decltype(gridFct);
return GridFunctionMarker<Grid,GridFct>{name, grid, gridFct};
auto gridFct = makeGridFunction(FWD(preGridFct), grid->leafGridView());
return GridFunctionMarker<Grid,TYPEOF(gridFct)>{name, grid, std::move(gridFct)};
}
} // end namespace AMDiS
......
......@@ -76,19 +76,19 @@ namespace AMDiS
template <class Op>
void push(tag::element_operator<Element>, Op&& op)
{
element_.emplace_back(std::forward<Op>(op));
element_.emplace_back(FWD(op));
}
template <class Op>
void push(tag::intersection_operator<Intersection>, Op&& op)
{
intersection_.emplace_back(std::forward<Op>(op));
intersection_.emplace_back(FWD(op));
}
template <class Op>
void push(tag::boundary_operator<Intersection> b, Op&& op)
{
boundary_.push_back({std::forward<Op>(op), b});
boundary_.push_back({FWD(op), b});
}
......
......@@ -22,6 +22,8 @@
#include <fmt/core.h>
#include <fmt/ostream.h>
#include <amdis/common/TypeTraits.hpp>
/**
* \def AMDIS_ENABLE_MSG_DBG
* \brief The preprocessor constant enables the functions \ref AMDiS::MSG_DBG
......@@ -66,12 +68,12 @@ namespace AMDiS
MPI_Comm_size(MPI_COMM_WORLD, &num_ranks);
if (num_ranks > 1 && rank == 0) {
out << "[0] ";
fmt::print(out, std::forward<Args>(args)...);
fmt::print(out, FWD(args)...);
} else if (num_ranks == 1) {
fmt::print(out, std::forward<Args>(args)...);
fmt::print(out, FWD(args)...);
}
#else
fmt::print(out, std::forward<Args>(args)...);
fmt::print(out, FWD(args)...);
#endif
return out;
}
......@@ -89,7 +91,7 @@ namespace AMDiS
template <class... Args>
void msg(Args&&... args)
{
Impl::msg(std::cout, std::forward<Args>(args)...) << std::endl;
Impl::msg(std::cout, FWD(args)...) << std::endl;
}
......@@ -103,7 +105,7 @@ namespace AMDiS
template <class... Args>
void msg_(Args&&... args)
{
Impl::msg(std::cout, std::forward<Args>(args)...);
Impl::msg(std::cout, FWD(args)...);
}
......@@ -117,14 +119,14 @@ namespace AMDiS
void error_exit(Args&&... args)
{
#ifdef AMDIS_NO_THROW
Impl::msg(std::cerr << "ERROR: ", std::forward<Args>(args)...) << std::endl;
Impl::msg(std::cerr << "ERROR: ", FWD(args)...) << std::endl;
#ifndef NDEBUG
assert(false);
#else
std::exit(EXIT_FAILURE);
#endif
#else
throw std::runtime_error( std::string("ERROR: ") + fmt::format(std::forward<Args>(args)...));
throw std::runtime_error( std::string("ERROR: ") + fmt::format(FWD(args)...));
#endif
}
......@@ -141,14 +143,14 @@ namespace AMDiS
template <class... Args>
void test_exit(bool condition, Args&&... args)
{
if (!condition) { error_exit(std::forward<Args>(args)...); }
if (!condition) { error_exit(FWD(args)...); }
}
template <class... Args>
void warning(Args&&... args)
{
Impl::msg(std::cout << "WARNING: ", std::forward<Args>(args)...) << std::endl;
Impl::msg(std::cout << "WARNING: ", FWD(args)...) << std::endl;
}
......@@ -161,7 +163,7 @@ namespace AMDiS
template <class... Args>
void test_warning(bool condition, Args&&... args)
{
if (!condition) { warning(std::forward<Args>(args)...); }
if (!condition) { warning(FWD(args)...); }
}
......@@ -172,7 +174,7 @@ namespace AMDiS
* \ref AMDIS_ENABLE_MSG_DBG is set to 1, otherwise the function is empty.
**/
template <class... Args>
void msg_dbg(Args&&... args) { msg(std::forward<Args>(args)...); }
void msg_dbg(Args&&... args) { msg(FWD(args)...); }
/// \brief call assert_msg, in debug mode only
......@@ -183,7 +185,7 @@ namespace AMDiS
template <class... Args>
void test_exit_dbg(bool condition, Args&&... args)
{
test_exit(condition, std::forward<Args>(args)...);
test_exit(condition, FWD(args)...);
}
#else
template <class... Args>
......
......@@ -54,7 +54,7 @@ namespace AMDiS
public:
template <class BM>
PeriodicBC(BM&& boundaryManager, BoundaryType id, FaceTrafo faceTrafo)
: Super(std::forward<BM>(boundaryManager), id)
: Super(FWD(boundaryManager), id)
, faceTrafo_(std::move(faceTrafo))
{}
......
......@@ -202,7 +202,7 @@ coords(Node const& tree, std::vector<std::size_t> const& localIndices) const
auto geometry = node.element().geometry();
auto const& localInterpol = node.finiteElement().localInterpolation();
using FiniteElement = std::decay_t<decltype(node.finiteElement())>;
using FiniteElement = TYPEOF(node.finiteElement());
using DomainType = typename FiniteElement::Traits::LocalBasisType::Traits::DomainType;
using RangeType = typename FiniteElement::Traits::LocalBasisType::Traits::RangeType;
......
......@@ -5,6 +5,7 @@
#include <utility>
#include <amdis/common/Mpl.hpp>
#include <amdis/common/TypeTraits.hpp>
namespace AMDiS
{
......@@ -15,7 +16,7 @@ namespace AMDiS
template <class F, class Tuple, std::size_t... I>
constexpr decltype(auto) apply_impl(F&& f, Tuple&& t, std::index_sequence<I...>)
{
return f(std::get<I>(std::forward<Tuple>(t))...);
return f(std::get<I>(FWD(t))...);
}
template <class F, std::size_t I0, std::size_t... I>
......@@ -28,31 +29,27 @@ namespace AMDiS
template <class F, class Tuple>
constexpr decltype(auto) apply(F&& f, Tuple&& t)
{
return Impl_::apply_impl(
std::forward<F>(f), std::forward<Tuple>(t),
return Impl_::apply_impl(FWD(f), FWD(t),
std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
}
template <class F, class... Args>
constexpr decltype(auto) apply_variadic(F&& f, Args&&... args)
{
return apply(std::forward<F>(f), std::forward_as_tuple(args...));
return apply(FWD(f), std::forward_as_tuple(args...));
}
template <class F, std::size_t N>
constexpr decltype(auto) apply_indices(F&& f, index_t<N>)
{
return Impl_::apply_indices_impl(
std::forward<F>(f),
index_t<0>{},
return Impl_::apply_indices_impl(FWD(f), index_t<0>{},
std::make_index_sequence<N>{});
}
template <class F, std::size_t I0, std::size_t I1>
constexpr decltype(auto) apply_indices(F&& f, index_t<I0>, index_t<I1>)
{
return Impl_::apply_indices_impl(
std::forward<F>(f), index_t<I0>{},
return Impl_::apply_indices_impl(FWD(f), index_t<I0>{},
std::make_index_sequence<I1-I0>{});
}
}
......
......@@ -20,7 +20,7 @@ namespace AMDiS
{
template <class A, class B>
struct IsSimilar
: std::is_same<std::decay_t<A>, std::decay_t<B>> {};
: std::is_same<remove_cvref_t<A>, remove_cvref_t<B>> {};
template <class A, class B>
struct IsSimilar<Types<A>, Types<B>>
......@@ -52,7 +52,7 @@ namespace AMDiS
struct Callable
{
template <class F, class... Args>
auto requires_(F&& f, Args&&... args) -> decltype( f(std::forward<Args>(args)...));
auto requires_(F&& f, Args&&... args) -> decltype(f(FWD(args)...));
};
// idx[0]
......
......@@ -78,8 +78,7 @@ namespace AMDiS
template <class F, class... Args>
data_type const& get_or_init(key_type const& key, F&& f, Args&&... args) const
{
return impl(std::is_default_constructible<data_type>{},
key, std::forward<F>(f), std::forward<Args>(args)...);
return impl(std::is_default_constructible<data_type>{}, key, FWD(f), FWD(args)...);
}
private:
......@@ -90,7 +89,7 @@ namespace AMDiS
data_type empty;
auto it = cachedData_.emplace(key, std::move(empty));
if (it.second) {
data_type data = f(key, std::forward<Args>(args)...);
data_type data = f(key, FWD(args)...);
it.first->second = std::move(data);
}
return it.first->second;
......@@ -104,7 +103,7 @@ namespace AMDiS
if (it != cachedData_.end())
return it->second;
else {
data_type data = f(key, std::forward<Args>(args)...);
data_type data = f(key, FWD(args)...);
auto it = cachedData_.emplace(key, std::move(data));
return it.first->second;
}
......@@ -125,8 +124,7 @@ namespace AMDiS
template <class F, class... Args>
static data_type const& get_or_init(key_type const& key, F&& f, Args&&... args)
{
return impl(std::is_default_constructible<data_type>{},
key, std::forward<F>(f), std::forward<Args>(args)...);
return impl(std::is_default_constructible<data_type>{}, key, FWD(f), FWD(args)...);
}
private:
......@@ -140,7 +138,7 @@ namespace AMDiS
data_type empty;
auto it = cached_data.emplace(key, std::move(empty));
if (it.second) {
data_type data = f(key, std::forward<Args>(args)...);
data_type data = f(key, FWD(args)...);
it.first->second = std::move(data);
}
return it.first->second;
......@@ -157,7 +155,7 @@ namespace AMDiS
if (it != cached_data.end())
return it->second;
else {
data_type data = f(key, std::forward<Args>(args)...);
data_type data = f(key, FWD(args)...);
auto it = cached_data.emplace(key, std::move(data));
return it.first->second;
}
......@@ -192,7 +190,7 @@ namespace AMDiS
return it->second;
else {
read_lock.unlock();
data_type data = f(key, std::forward<Args>(args)...);
data_type data = f(key, FWD(args)...);
std::unique_lock<mutex_type> write_lock(access_mutex);
auto new_it = cached_data.emplace(key, std::move(data));
return new_it.first->second;
......@@ -224,7 +222,7 @@ namespace AMDiS
static_assert(Dune::Std::is_callable<F(key_type, Args...), data_type>::value,
"Functor F must have the signature data_type(key_type, Args...)");
return ConcurrentCache::get_or_init(key, std::forward<F>(f), std::forward<Args>(args)...);
return ConcurrentCache::get_or_init(key, FWD(f), FWD(args)...);
}
};
......
......@@ -7,6 +7,8 @@
#include <dune/common/fvector.hh>
#include <dune/common/typetraits.hh>
#include <amdis/common/TypeTraits.hpp>
namespace std
{
template <class T, int N>
......@@ -82,7 +84,7 @@ namespace Dune
template <class T>
decltype(auto) simplify(T&& t)
{
return std::forward<T>(t);
return FWD(t);
}
template <class T>
......
......@@ -305,7 +305,7 @@ T distance(FieldVector<T, N> const& lhs, FieldVector<T, N> const& rhs)
template <class T, class S, int N, int M, int K>
auto outer(FieldMatrix<T,N,K> const& vec1, FieldMatrix<S,M,K> const& vec2)
{
using result_type = FieldMatrix<decltype( std::declval<T>() * std::declval<S>() ), N, M>;
using result_type = FieldMatrix<TYPEOF( std::declval<T>() * std::declval<S>() ), N, M>;
result_type mat;
for (int i = 0; i < N; ++i)
for (int j = 0; j < M; ++j)
......
......@@ -56,7 +56,7 @@ namespace AMDiS
template <class... Rows_,
REQUIRES( Concepts::Similar<Types<Rows...>, Types<Rows_...>> )>
MultiTypeMatrix(Rows_&&... rows)
: Super(std::forward<Rows_>(rows)...)
: Super(FWD(rows)...)
{}
/// Default construction of tuple of FieldVectors
......
......@@ -49,7 +49,7 @@ namespace AMDiS
template <class... FV_,
REQUIRES( Concepts::Similar<Types<FV...>, Types<FV_...>> )>
MultiTypeVector(FV_&&... fv)
: Super(std::forward<FV_>(fv)...)
: Super(FWD(fv)...)
{}
/// Default construction of tuple of FieldVectors
......
......@@ -79,10 +79,10 @@ namespace AMDiS
/// Get the number of elements in a tuple / pair / array / ...
template <class T>
constexpr std::size_t Size_v = Impl::SizeImpl<std::decay_t<T>>::value;
constexpr std::size_t Size_v = Impl::SizeImpl<remove_cvref_t<T>>::value;
template <class T>
using Size_t = Impl::SizeImpl<std::decay_t<T>>;
using Size_t = Impl::SizeImpl<remove_cvref_t<T>>;
namespace Impl
......@@ -111,10 +111,10 @@ namespace AMDiS
/// Get the number of rows in a fixed-size matrix
template <class T>
constexpr std::size_t Rows_v = Impl::RowsImpl<std::decay_t<T>>::value;
constexpr std::size_t Rows_v = Impl::RowsImpl<remove_cvref_t<T>>::value;
template <class T>
using Rows_t = Impl::RowsImpl<std::decay_t<T>>;
using Rows_t = Impl::RowsImpl<remove_cvref_t<T>>;
namespace Impl
......@@ -143,9 +143,9 @@ namespace AMDiS
/// Get the number of columns in a fixed-size matrix
template <class T>
constexpr std::size_t Cols_v = Impl::ColsImpl<std::decay_t<T>>::value;
constexpr std::size_t Cols_v = Impl::ColsImpl<remove_cvref_t<T>>::value;
template <class T>
using Cols_t = Impl::ColsImpl<std::decay_t<T>>;
using Cols_t = Impl::ColsImpl<remove_cvref_t<T>>;
} // end namespace AMDiS
......@@ -8,7 +8,7 @@ namespace AMDiS
template <class Matrix>
class TransposedMatrix
{
using RawMatrix = std::decay_t<Matrix>;
using RawMatrix = remove_cvref_t<Matrix>;
public:
using size_type = typename RawMatrix::size_type;
......@@ -40,7 +40,7 @@ namespace AMDiS
public:
template <class M>
TransposedMatrix(M&& matrix)
: matrix_(std::forward<M>(matrix))
: matrix_(FWD(matrix))
{}
ConstRowProxy operator[](size_type row) const
......@@ -73,7 +73,7 @@ namespace AMDiS
auto transposed(Matrix&& matrix)
{
using M = std::remove_reference_t<Matrix>;
return TransposedMatrix<M>{std::forward<Matrix>(matrix)};
return TransposedMatrix<M>{FWD(matrix)};
}
} // end namespace AMDiS
......@@ -12,24 +12,52 @@
namespace AMDiS
{
/// \brief Remove cv and ref qualifiers of type T.
/**
* If the type T is a reference type, provides the member typedef type which
* is the type referred to by T with its topmost cv-qualifiers removed.
* Otherwise type is T with its topmost cv-qualifiers removed.
*
* Note: This is a backport of c++20 std::remove_cvref
**/
template< class T >
struct remove_cvref
{
using type = std::remove_cv_t<std::remove_reference_t<T>>;
};
/// Helper alias template for \ref remove_cvref
template< class T >
using remove_cvref_t = typename remove_cvref<T>::type;
namespace Impl
{
template <class T>
struct UnderlyingType
{
using type = T;
using type = remove_cvref_t<T>;
};
template <class T>
struct UnderlyingType<std::reference_wrapper<T>>
{
using type = T;
using type = remove_cvref_t<T>;
};
}
template <class T>
using Underlying_t = typename Impl::UnderlyingType<T>::type;
/// Macro for forwarding universal references to obj
#define FWD(obj) std::forward<decltype(obj)>(obj)
/// A decay version of decltype, similar to GCCs __typeof__
#define TYPEOF(...) AMDiS::remove_cvref_t<decltype(__VA_ARGS__)>
/// Extract the static value of an integral_constant variable
#define VALUE(...) TYPEOF(__VA_ARGS__)::value
// ---------------------------------------------------------------------------
/// A variadic type list
......@@ -37,7 +65,7 @@ namespace AMDiS
struct Types {};
template <class... Ts>
using Types_t = Types<std::decay_t<Ts>...>;
using Types_t = Types<remove_cvref_t<Ts>...>;
/// Alias that indicates ownership of resources
......@@ -49,7 +77,7 @@ namespace AMDiS
template <class Obj>
auto makeUniquePtr(Obj&& obj)
{
return std::make_unique<std::decay_t<Obj>>(std::forward<Obj>(obj));
return std::make_unique<TYPEOF(obj)>(FWD(obj));
}
} // end namespace AMDiS
......@@ -18,7 +18,7 @@ namespace AMDiS
};
template <class T>
using ValueCategory_t = typename ValueCategory<std::decay_t<T>>::type;
using ValueCategory_t = typename ValueCategory<remove_cvref_t<T>>::type;