Commit 8bf3862f authored by Praetorius, Simon's avatar Praetorius, Simon

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

parent 1d1ddecc
......@@ -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
......
......@@ -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;
......
#pragma once
#include <memory>
#include <utility>
#include <amdis/common/Utility.hpp>
namespace AMDiS
{
// A pointer class that deletes only when owning the pointer
template <class T>
class ClonablePtr
{
private:
struct alloc_tag {}; ///< hidden helper struct, used by \ref make
public:
using Self = ClonablePtr;
using element_type = T;
/// Default constructor, creates a non-owned nullptr
ClonablePtr() = default;
/// Constructor from pointer. Can only be used via make method,
/// Transfers ownership.
ClonablePtr(owner<T>* p, alloc_tag) noexcept
: p(p)
, is_owner(true)
{}
/// Constructor from reference
explicit ClonablePtr(T& ref) noexcept
: p(&ref)
, is_owner(false)
{}
/// Constructor from std::unique_ptr
explicit ClonablePtr(std::unique_ptr<T>& ptr)
: p(ptr.release())
, is_owner(true)
{}
explicit ClonablePtr(std::unique_ptr<T>&& ptr)
: p(ptr.release())
, is_owner(true)
{}
/// Destructor, deletes in case of owner only
~ClonablePtr() noexcept
{
if (is_owner)
delete p;
}
/// Copy constructor, creates a clone of the pointed to object
ClonablePtr(Self const& that) noexcept( std::is_nothrow_copy_constructible<T>::value )
: p(new T(*that.p))
, is_owner(true)
{}
/// Move constructor, copies the pointer only.
ClonablePtr(Self&& that) noexcept
: p(that.p)
, is_owner(that.is_owner)
{
that.p = nullptr;
that.is_owner = false;
}
/// Copy and move assignment operator, using the copy-and-swap idiom
Self& operator=(Self that) noexcept
{
swap(that);
return *this;
}
/// Factory method. creates a new Object of type T and stores the pointer.
template <class... Args>
static Self make(Args&&... args)
noexcept( std::is_nothrow_constructible<T, remove_cvref_t<Args>...>::value )
{
return {new T(FWD(args)...), Self::alloc_tag()};
}
/// Access-method by dereferencing
T& operator*() const noexcept
{
return *p;
}
/// Access-method by pointer access
T* operator->() const noexcept
{
return p;
}
/// retrieve the underlying pointer
T* get() const noexcept
{
return p;
}
/// Test whether pointer is NULL
operator bool() const noexcept
{
return !(p == NULL);
}
void swap(Self& that) noexcept
{
using std::swap;
swap(p, that.p);
swap(is_owner, that.is_owner);
}
private:
T* p = nullptr; ///< managed pointer
bool is_owner = false; ///< true, if class is owner of pointer, false otherwise
};
template <class T>
void swap(ClonablePtr<T>& a, ClonablePtr<T>& b) noexcept
{
a.swap(b);
}
} // end namespace AMDiS
......@@ -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]
......
......@@ -125,8 +125,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 +139,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 +156,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 +191,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 +223,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)...);
}
};
......
#pragma once
#include <dune/common/ftraits.hh>
#include <amdis/common/Utility.hpp>
namespace AMDiS
{
template <class... T>
struct CommonFieldTraits
{
using field_type = std::common_type_t<typename Dune::FieldTraits<T>::field_type...>;
using real_type = std::common_type_t<typename Dune::FieldTraits<T>::real_type...>;
};
} // end namespace AMDiS
......@@ -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
......
#pragma once
// std c++ headers
#include <type_traits>
#include <amdis/common/Utility.hpp>
namespace AMDiS
{
namespace Traits
{
template <class T>
struct IsIntegral
: public std::is_integral<remove_cvref_t<T>> {};
template <class T>
struct IsArithmetic
: public std::is_arithmetic<remove_cvref_t<T>> {};
} // end namespace traits
namespace Concepts
{
/** \addtogroup Concepts
* @{
**/
/// \brief The types following the std type-trait \ref std::is_integral are
/// categorized as *integral types*.
template <class T>
constexpr bool Integral = Traits::IsIntegral<T>::value;
/// \brief The types following the std type-trait \ref std::is_arithmetic are
/// categorized as *arithmetic types*.
template <class T>
constexpr bool Arithmetic = Traits::IsArithmetic<T>::value;
/** @} **/
} // end namespace Concepts
} // end namespace AMDiS
......@@ -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;