From 8bf3862f54826a6efe382ed853a2a2b364046745 Mon Sep 17 00:00:00 2001 From: Simon Praetorius <simon.praetorius@tu-dresden.de> Date: Sun, 13 Jan 2019 15:31:24 +0100 Subject: [PATCH] introduce macros FWD and TYPEOF to reducine typing of std::forward and decltype --- src/amdis/Assembler.hpp | 2 +- src/amdis/DataTransfer.inc.hpp | 3 +- src/amdis/DirichletBC.hpp | 8 +- src/amdis/GridFunctionOperator.hpp | 18 ++- src/amdis/Integrate.hpp | 22 ++- src/amdis/Marker.hpp | 15 +- src/amdis/OperatorList.hpp | 6 +- src/amdis/Output.hpp | 26 ++-- src/amdis/PeriodicBC.hpp | 2 +- src/amdis/PeriodicBC.inc.hpp | 2 +- src/amdis/common/ClonablePtr.hpp | 127 +++++++++++++++++ src/amdis/common/Concepts.hpp | 2 +- src/amdis/common/ConcurrentCache.hpp | 11 +- src/amdis/common/FieldTraits.hpp | 16 +++ src/amdis/common/MultiTypeMatrix.hpp | 2 +- src/amdis/common/MultiTypeVector.hpp | 2 +- src/amdis/common/ScalarTypes.hpp | 41 ++++++ src/amdis/common/StaticSize.hpp | 12 +- src/amdis/common/Transposed.hpp | 6 +- src/amdis/common/TypeTraits.hpp | 10 ++ src/amdis/common/Utility.hpp | 130 ++++++++++++++++++ src/amdis/common/ValueCategory.hpp | 2 +- .../gridfunctions/AnalyticGridFunction.hpp | 2 +- src/amdis/gridfunctions/DOFVectorView.hpp | 7 +- .../gridfunctions/DerivativeGridFunction.hpp | 2 +- .../gridfunctions/DiscreteFunction.inc.hpp | 6 +- .../gridfunctions/FunctorGridFunction.hpp | 12 +- .../gridfunctions/GridFunctionConcepts.hpp | 4 +- .../gridfunctions/OperationsGridFunction.hpp | 56 ++++---- src/amdis/operations/Basic.hpp | 2 +- src/amdis/operations/Composer.hpp | 11 +- src/amdis/typetree/RangeType.hpp | 2 +- src/amdis/typetree/Traversal.hpp | 17 +-- 33 files changed, 451 insertions(+), 135 deletions(-) create mode 100644 src/amdis/common/ClonablePtr.hpp create mode 100644 src/amdis/common/FieldTraits.hpp create mode 100644 src/amdis/common/ScalarTypes.hpp create mode 100644 src/amdis/common/Utility.hpp diff --git a/src/amdis/Assembler.hpp b/src/amdis/Assembler.hpp index cd1aaa75..6c1c8362 100644 --- a/src/amdis/Assembler.hpp +++ b/src/amdis/Assembler.hpp @@ -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 diff --git a/src/amdis/DataTransfer.inc.hpp b/src/amdis/DataTransfer.inc.hpp index 799009cd..8d33b5e4 100644 --- a/src/amdis/DataTransfer.inc.hpp +++ b/src/amdis/DataTransfer.inc.hpp @@ -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 diff --git a/src/amdis/DirichletBC.hpp b/src/amdis/DirichletBC.hpp index 344d1076..10e932b9 100644 --- a/src/amdis/DirichletBC.hpp +++ b/src/amdis/DirichletBC.hpp @@ -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> diff --git a/src/amdis/GridFunctionOperator.hpp b/src/amdis/GridFunctionOperator.hpp index b3339453..18d93071 100644 --- a/src/amdis/GridFunctionOperator.hpp +++ b/src/amdis/GridFunctionOperator.hpp @@ -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; } diff --git a/src/amdis/Integrate.hpp b/src/amdis/Integrate.hpp index 08d527a1..2a952268 100644 --- a/src/amdis/Integrate.hpp +++ b/src/amdis/Integrate.hpp @@ -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); }); } diff --git a/src/amdis/Marker.hpp b/src/amdis/Marker.hpp index 83c62e52..48f5ccd2 100644 --- a/src/amdis/Marker.hpp +++ b/src/amdis/Marker.hpp @@ -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 diff --git a/src/amdis/OperatorList.hpp b/src/amdis/OperatorList.hpp index b0807c85..35adb2c9 100644 --- a/src/amdis/OperatorList.hpp +++ b/src/amdis/OperatorList.hpp @@ -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}); } diff --git a/src/amdis/Output.hpp b/src/amdis/Output.hpp index af4d5ff3..91264e57 100644 --- a/src/amdis/Output.hpp +++ b/src/amdis/Output.hpp @@ -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> diff --git a/src/amdis/PeriodicBC.hpp b/src/amdis/PeriodicBC.hpp index 23f4fb37..65541856 100644 --- a/src/amdis/PeriodicBC.hpp +++ b/src/amdis/PeriodicBC.hpp @@ -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)) {} diff --git a/src/amdis/PeriodicBC.inc.hpp b/src/amdis/PeriodicBC.inc.hpp index ea08e9ed..a0c03627 100644 --- a/src/amdis/PeriodicBC.inc.hpp +++ b/src/amdis/PeriodicBC.inc.hpp @@ -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; diff --git a/src/amdis/common/ClonablePtr.hpp b/src/amdis/common/ClonablePtr.hpp new file mode 100644 index 00000000..23821f1c --- /dev/null +++ b/src/amdis/common/ClonablePtr.hpp @@ -0,0 +1,127 @@ +#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 diff --git a/src/amdis/common/Concepts.hpp b/src/amdis/common/Concepts.hpp index ed851525..6131f1cf 100644 --- a/src/amdis/common/Concepts.hpp +++ b/src/amdis/common/Concepts.hpp @@ -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] diff --git a/src/amdis/common/ConcurrentCache.hpp b/src/amdis/common/ConcurrentCache.hpp index 8e84f7b5..3f820916 100644 --- a/src/amdis/common/ConcurrentCache.hpp +++ b/src/amdis/common/ConcurrentCache.hpp @@ -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)...); } }; diff --git a/src/amdis/common/FieldTraits.hpp b/src/amdis/common/FieldTraits.hpp new file mode 100644 index 00000000..b4560e0b --- /dev/null +++ b/src/amdis/common/FieldTraits.hpp @@ -0,0 +1,16 @@ +#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 diff --git a/src/amdis/common/MultiTypeMatrix.hpp b/src/amdis/common/MultiTypeMatrix.hpp index 2a512bda..392005ae 100644 --- a/src/amdis/common/MultiTypeMatrix.hpp +++ b/src/amdis/common/MultiTypeMatrix.hpp @@ -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 diff --git a/src/amdis/common/MultiTypeVector.hpp b/src/amdis/common/MultiTypeVector.hpp index bfe4a24f..1f3e38f5 100644 --- a/src/amdis/common/MultiTypeVector.hpp +++ b/src/amdis/common/MultiTypeVector.hpp @@ -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 diff --git a/src/amdis/common/ScalarTypes.hpp b/src/amdis/common/ScalarTypes.hpp new file mode 100644 index 00000000..6a3ed614 --- /dev/null +++ b/src/amdis/common/ScalarTypes.hpp @@ -0,0 +1,41 @@ +#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 diff --git a/src/amdis/common/StaticSize.hpp b/src/amdis/common/StaticSize.hpp index 81d5d48c..d1b399e1 100644 --- a/src/amdis/common/StaticSize.hpp +++ b/src/amdis/common/StaticSize.hpp @@ -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 diff --git a/src/amdis/common/Transposed.hpp b/src/amdis/common/Transposed.hpp index 4778e95f..38920b96 100644 --- a/src/amdis/common/Transposed.hpp +++ b/src/amdis/common/Transposed.hpp @@ -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 diff --git a/src/amdis/common/TypeTraits.hpp b/src/amdis/common/TypeTraits.hpp index 47397712..315b6cc2 100644 --- a/src/amdis/common/TypeTraits.hpp +++ b/src/amdis/common/TypeTraits.hpp @@ -30,6 +30,16 @@ namespace AMDiS 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(...) 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 diff --git a/src/amdis/common/Utility.hpp b/src/amdis/common/Utility.hpp new file mode 100644 index 00000000..49fc8203 --- /dev/null +++ b/src/amdis/common/Utility.hpp @@ -0,0 +1,130 @@ +#pragma once + +#include <memory> +#include <type_traits> +#include <vector> + +#if AMDIS_HAS_CXX_CONSTEXPR_IF +#define IF_CONSTEXPR if constexpr +#else +#define IF_CONSTEXPR if +#endif + +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 = remove_cvref_t<T>; + }; + + template <class T> + struct UnderlyingType<std::reference_wrapper<T>> + { + using type = std::remove_cv_t<T>; + }; + } + + /// \brief strip reference_wrapper, const, volatile, and references from type 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(...) remove_cvref_t<decltype(__VA_ARGS__)> + + /// Extract the static value of an integral_constant variable + #define VALUE(...) TYPEOF(__VA_ARGS__)::value + + /// Create a unique_ptr by copy/move construction + template <class Obj> + auto makeUniquePtr(Obj&& obj) + { + return std::make_unique<TYPEOF(obj)>(FWD(obj)); + } + + // --------------------------------------------------------------------------- + + // base template for tuple size, must implement a static value member + template <class TupleType> + struct TupleSize; + + // utility constant returning the value of the tuple size + template <class TupleType> + constexpr std::size_t TupleSize_v = TupleSize<TupleType>::value; + + + // base template for retrieving the tuple element type, must implement the type member `type` + template <size_t I, class TupleType> + struct TupleElement; + + // base template for retrieving the tuple element type + template <size_t I, class TupleType> + using TupleElement_t = typename TupleElement<I, TupleType>::type; + + + /// A variadic type list + template <class... Ts> + struct Types {}; + + template <class... Ts> + using Types_t = Types<remove_cvref_t<Ts>...>; + + + template <class... T> + struct TupleSize<Types<T...>> + : std::integral_constant<std::size_t, sizeof...(T)> {}; + + template <size_t I, class Head, class... Tail> + struct TupleElement<I, Types<Head, Tail...>> + { + using type = typename TupleElement<I-1, Types<Tail...>>::type; + }; + + template <class Head, class... Tail> + struct TupleElement<0, Types<Head, Tail...>> + { + using type = Head; + }; + + + /// Alias that indicates ownership of resources + template <class T> + using owner = T; + + + // --------------------------------------------------------------------------- + + + /// generalization of get<tuple>, get<array> for vectors + template <std::size_t I, class T, class A> + T const& get(std::vector<T,A> const& vec) + { + return vec[I]; + } + +} // end namespace AMDiS diff --git a/src/amdis/common/ValueCategory.hpp b/src/amdis/common/ValueCategory.hpp index 3c1b61c3..71d72db1 100644 --- a/src/amdis/common/ValueCategory.hpp +++ b/src/amdis/common/ValueCategory.hpp @@ -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; template <class T> struct ValueCategory<T, std::enable_if_t< std::is_arithmetic<T>::value >> diff --git a/src/amdis/gridfunctions/AnalyticGridFunction.hpp b/src/amdis/gridfunctions/AnalyticGridFunction.hpp index 53303820..c0994d4f 100644 --- a/src/amdis/gridfunctions/AnalyticGridFunction.hpp +++ b/src/amdis/gridfunctions/AnalyticGridFunction.hpp @@ -129,7 +129,7 @@ namespace AMDiS public: using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>; using Domain = typename EntitySet::GlobalCoordinate; - using Range = std::decay_t<std::result_of_t<Function(Domain)>>; + using Range = remove_cvref_t<std::result_of_t<Function(Domain)>>; enum { hasDerivative = true }; diff --git a/src/amdis/gridfunctions/DOFVectorView.hpp b/src/amdis/gridfunctions/DOFVectorView.hpp index 55f0bf74..f95677a9 100644 --- a/src/amdis/gridfunctions/DOFVectorView.hpp +++ b/src/amdis/gridfunctions/DOFVectorView.hpp @@ -44,10 +44,9 @@ namespace AMDiS auto const& basis = this->basis(); auto const& treePath = this->treePath(); - auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), basis.gridView()); + auto&& gridFct = makeGridFunction(FWD(expr), basis.gridView()); - Dune::Functions::interpolate(basis, treePath, coefficients(), - std::forward<decltype(gridFct)>(gridFct)); + Dune::Functions::interpolate(basis, treePath, coefficients(), FWD(gridFct)); } /// \brief Interpolation of GridFunction to DOFVector @@ -66,7 +65,7 @@ namespace AMDiS // create temporary copy of data DOFVector<GB,VT> tmp(coefficients()); Self tmpView{tmp, this->treePath()}; - tmpView.interpolate_noalias(std::forward<Expr>(expr)); + tmpView.interpolate_noalias(FWD(expr)); // move data from temporary vector into stored DOFVector coefficients().vector() = std::move(tmp.vector()); diff --git a/src/amdis/gridfunctions/DerivativeGridFunction.hpp b/src/amdis/gridfunctions/DerivativeGridFunction.hpp index f1b2abeb..19693c8d 100644 --- a/src/amdis/gridfunctions/DerivativeGridFunction.hpp +++ b/src/amdis/gridfunctions/DerivativeGridFunction.hpp @@ -29,7 +29,7 @@ namespace AMDiS using GridFctDomain = typename GridFunction::Domain; using RawSignature = typename Dune::Functions::SignatureTraits<GridFctRange(GridFctDomain)>::RawSignature; using DerivativeTraits = Dune::Functions::DefaultDerivativeTraits<RawSignature>; - using LocalFunction = std::decay_t<decltype(derivative(localFunction(std::declval<GridFunction>())))>; + using LocalFunction = TYPEOF( derivative(localFunction(std::declval<GridFunction>())) ) ; enum { hasDerivative = false }; diff --git a/src/amdis/gridfunctions/DiscreteFunction.inc.hpp b/src/amdis/gridfunctions/DiscreteFunction.inc.hpp index 069e67c6..52c47b3e 100644 --- a/src/amdis/gridfunctions/DiscreteFunction.inc.hpp +++ b/src/amdis/gridfunctions/DiscreteFunction.inc.hpp @@ -152,8 +152,7 @@ LocalFunction::operator()(Domain const& x) const auto&& fe = node.finiteElement(); auto&& localBasis = fe.localBasis(); - using Node = std::decay_t<decltype(node)>; - NodeCache<Node> localBasisCache(localBasis); + NodeCache<TYPEOF(node)> localBasisCache(localBasis); auto const& shapeFunctionValues = localBasisCache.evaluateFunction(localView_.element().type(),x); // Get range entry associated to this node @@ -204,8 +203,7 @@ GradientLocalFunction::operator()(Domain const& x) const auto&& fe = node.finiteElement(); auto&& localBasis = fe.localBasis(); - using Node = std::decay_t<decltype(node)>; - NodeCache<Node> localBasisCache(localBasis); + NodeCache<TYPEOF(node)> localBasisCache(localBasis); auto const& referenceGradients = localBasisCache.evaluateJacobian(localView_.element().type(),x); // The transposed inverse Jacobian of the map from the reference element to the element diff --git a/src/amdis/gridfunctions/FunctorGridFunction.hpp b/src/amdis/gridfunctions/FunctorGridFunction.hpp index 99688cf2..566a6460 100644 --- a/src/amdis/gridfunctions/FunctorGridFunction.hpp +++ b/src/amdis/gridfunctions/FunctorGridFunction.hpp @@ -67,7 +67,7 @@ namespace AMDiS template <class... GridFcts> FunctorLocalFunction(Functor const& fct, GridFcts&&... gridFcts) : fct_{fct} - , localFcts_{std::forward<GridFcts>(gridFcts)...} + , localFcts_{FWD(gridFcts)...} {} /// Calls \ref bind for all localFunctions @@ -203,9 +203,9 @@ namespace AMDiS private: template <class GridFct> - using LocalFct = std::decay_t<decltype(localFunction(std::declval<GridFct>()))>; + using LocalFct = TYPEOF( localFunction(std::declval<GridFct>()) ); - using RawRange = std::decay_t<Range>; + using RawRange = remove_cvref_t<Range>; using LocalDomain = typename EntitySet::LocalCoordinate; public: @@ -215,7 +215,7 @@ namespace AMDiS template <class... GridFcts> explicit FunctorGridFunction(Functor const& fct, GridFcts&&... gridFcts) : fct_{fct} - , gridFcts_{std::forward<GridFcts>(gridFcts)...} + , gridFcts_{FWD(gridFcts)...} {} /// Applies the functor to the evaluated gridfunctions @@ -288,7 +288,7 @@ namespace AMDiS template <class... PreGridFcts> explicit FunctorPreGridFunction(Functor const& fct, PreGridFcts&&... pgfs) : fct_{fct} - , preGridFcts_{std::forward<PreGridFcts>(pgfs)...} + , preGridFcts_{FWD(pgfs)...} {} private: @@ -320,7 +320,7 @@ namespace AMDiS template <class Functor, class... PreGridFcts> auto invokeAtQP(Functor const& f, PreGridFcts&&... gridFcts) { - return FunctorPreGridFunction<Functor, std::decay_t<PreGridFcts>...>{f, std::forward<PreGridFcts>(gridFcts)...}; + return FunctorPreGridFunction<Functor, TYPEOF(gridFcts)...>{f, FWD(gridFcts)...}; } } // end namespace AMDiS diff --git a/src/amdis/gridfunctions/GridFunctionConcepts.hpp b/src/amdis/gridfunctions/GridFunctionConcepts.hpp index ac073736..d9357bd0 100644 --- a/src/amdis/gridfunctions/GridFunctionConcepts.hpp +++ b/src/amdis/gridfunctions/GridFunctionConcepts.hpp @@ -120,8 +120,8 @@ namespace AMDiS /// can be converted to a GridFunction, or is already a GridFunction. template <class... GFs> constexpr bool AnyGridFunction = - any_of_v<GridFunction<std::decay_t<GFs>>...> || - any_of_v<Traits::IsPreGridFunction<std::decay_t<GFs>>::value...>; + any_of_v<GridFunction<remove_cvref_t<GFs>>...> || + any_of_v<Traits::IsPreGridFunction<remove_cvref_t<GFs>>::value...>; /** @} **/ diff --git a/src/amdis/gridfunctions/OperationsGridFunction.hpp b/src/amdis/gridfunctions/OperationsGridFunction.hpp index 425d5d68..18001485 100644 --- a/src/amdis/gridfunctions/OperationsGridFunction.hpp +++ b/src/amdis/gridfunctions/OperationsGridFunction.hpp @@ -20,7 +20,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Lhs>)> auto operator-(Lhs&& lhs) { - return invokeAtQP(Operation::Negate{}, std::forward<Lhs>(lhs)); + return invokeAtQP(Operation::Negate{}, FWD(lhs)); } /// \brief Applies \ref Operation::Plus to GridFunctions. \relates FunctorGridFunction @@ -28,7 +28,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto operator+(Lhs&& lhs, Rhs&& rhs) { - return invokeAtQP(Operation::Plus{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + return invokeAtQP(Operation::Plus{}, FWD(lhs), FWD(rhs)); } /// \brief Applies \ref Operation::Minus to GridFunctions. \relates FunctorGridFunction @@ -36,7 +36,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto operator-(Lhs&& lhs, Rhs&& rhs) { - return invokeAtQP(Operation::Minus{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + return invokeAtQP(Operation::Minus{}, FWD(lhs), FWD(rhs)); } /// \brief Applies \ref Operation::Multiplies to GridFunctions. \relates FunctorGridFunction @@ -44,7 +44,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto operator*(Lhs&& lhs, Rhs&& rhs) { - return invokeAtQP(Operation::Multiplies{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + return invokeAtQP(Operation::Multiplies{}, FWD(lhs), FWD(rhs)); } namespace Impl @@ -53,14 +53,14 @@ namespace AMDiS REQUIRES(Concepts::ConstantToGridFunction<Value>)> auto divideAtQP(Lhs&& lhs, Value value) { - return invokeAtQP(Operation::Multiplies{}, std::forward<Lhs>(lhs), 1.0/value); + return invokeAtQP(Operation::Multiplies{}, FWD(lhs), 1.0/value); } template <class Lhs, class Rhs, - REQUIRES(not Concepts::ConstantToGridFunction<std::decay_t<Rhs>>)> + REQUIRES(not Concepts::ConstantToGridFunction<remove_cvref_t<Rhs>>)> auto divideAtQP(Lhs&& lhs, Rhs&& rhs) { - return invokeAtQP(Operation::Divides{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + return invokeAtQP(Operation::Divides{}, FWD(lhs), FWD(rhs)); } } @@ -69,7 +69,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto operator/(Lhs&& lhs, Rhs&& rhs) { - return Impl::divideAtQP(std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + return Impl::divideAtQP(FWD(lhs), FWD(rhs)); } @@ -78,7 +78,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto max(Lhs&& lhs, Rhs&& rhs) { - return invokeAtQP(Operation::Max{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + return invokeAtQP(Operation::Max{}, FWD(lhs), FWD(rhs)); } /// \brief Applies \ref Operation::Min to GridFunctions. \relates FunctorGridFunction @@ -86,7 +86,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto min(Lhs&& lhs, Rhs&& rhs) { - return invokeAtQP(Operation::Min{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + return invokeAtQP(Operation::Min{}, FWD(lhs), FWD(rhs)); } /// \brief Applies \ref Operation::AbsMax to GridFunctions. \relates FunctorGridFunction @@ -94,7 +94,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto abs_max(Lhs&& lhs, Rhs&& rhs) { - return invokeAtQP(Operation::AbsMax{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + return invokeAtQP(Operation::AbsMax{}, FWD(lhs), FWD(rhs)); } /// \brief Applies \ref Operation::AbsMin to GridFunctions. \relates FunctorGridFunction @@ -102,7 +102,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto abs_min(Lhs&& lhs, Rhs&& rhs) { - return invokeAtQP(Operation::AbsMin{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + return invokeAtQP(Operation::AbsMin{}, FWD(lhs), FWD(rhs)); } /// \brief Applies \ref Operation::Clamp to GridFunction. \relates FunctorGridFunction @@ -110,7 +110,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<V>)> auto clamp(V&& v, T const& lo, T const& hi) { - return invokeAtQP(Operation::Clamp<T>{lo,hi}, std::forward<V>(v)); + return invokeAtQP(Operation::Clamp<T>{lo,hi}, FWD(v)); } /// \brief Applies \ref Operation::Sqr to GridFunction. \relates FunctorGridFunction @@ -118,7 +118,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<T>)> auto sqr(T&& value) { - return invokeAtQP(Operation::Sqr{}, std::forward<T>(value)); + return invokeAtQP(Operation::Sqr{}, FWD(value)); } /// \brief Applies \ref Operation::Pow<p> to GridFunction. \relates FunctorGridFunction @@ -126,7 +126,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<T>)> auto pow(T&& value) { - return invokeAtQP(Operation::Pow<p>{}, std::forward<T>(value)); + return invokeAtQP(Operation::Pow<p>{}, FWD(value)); } /// \brief Applies \ref Operation::Pow_ to GridFunction. \relates FunctorGridFunction @@ -134,7 +134,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<T>)> auto pow(T&& value, int p) { - return invokeAtQP(Operation::Pow_{p}, std::forward<T>(value)); + return invokeAtQP(Operation::Pow_{p}, FWD(value)); } /// \brief Applies \ref Operation::Get<I> to GridFunction. \relates FunctorGridFunction @@ -142,7 +142,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<T>)> auto get(T&& value) { - return invokeAtQP(Operation::Get<I>{}, std::forward<T>(value)); + return invokeAtQP(Operation::Get<I>{}, FWD(value)); } /// \brief Applies \ref Operation::Get_ to GridFunction. \relates FunctorGridFunction @@ -150,7 +150,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<T>)> auto get(T&& value, std::size_t i) { - return invokeAtQP(Operation::Get_{i}, std::forward<T>(value)); + return invokeAtQP(Operation::Get_{i}, FWD(value)); } // @} @@ -163,7 +163,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Vec>)> auto sum(Vec&& vec) { - return invokeAtQP([](auto const& v) { return sum(v); }, std::forward<Vec>(vec)); + return invokeAtQP([](auto const& v) { return sum(v); }, FWD(vec)); } /// \brief Applies \ref Operation::UnaryDot to a vector-valued GridFunction. \relates FunctorGridFunction @@ -171,7 +171,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Vec>)> auto unary_dot(Vec&& vec) { - return invokeAtQP(Operation::UnaryDot{}, std::forward<Vec>(vec)); + return invokeAtQP(Operation::UnaryDot{}, FWD(vec)); } /// \brief Applies a \ref one_norm() functor to a vector-valued GridFunction. \relates FunctorGridFunction @@ -179,7 +179,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Vec>)> auto one_norm(Vec&& vec) { - return invokeAtQP([](auto const& v) { return one_norm(v); }, std::forward<Vec>(vec)); + return invokeAtQP([](auto const& v) { return one_norm(v); }, FWD(vec)); } /// \brief Applies \ref Operation::TwoNorm to a vector-valued GridFunction. \relates FunctorGridFunction @@ -187,7 +187,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Vec>)> auto two_norm(Vec&& vec) { - return invokeAtQP(Operation::TwoNorm{}, std::forward<Vec>(vec)); + return invokeAtQP(Operation::TwoNorm{}, FWD(vec)); } /// \brief Applies a \ref p_norm() functor to a vector-valued GridFunction. \relates FunctorGridFunction @@ -195,7 +195,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Vec>)> auto p_norm(Vec&& vec) { - return invokeAtQP([](auto const& v) { return p_norm<p>(v); }, std::forward<Vec>(vec)); + return invokeAtQP([](auto const& v) { return p_norm<p>(v); }, FWD(vec)); } /// \brief Applies a \ref infty_norm() functor to a vector-valued GridFunction. \relates FunctorGridFunction @@ -203,7 +203,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Vec>)> auto infty_norm(Vec&& vec) { - return invokeAtQP([](auto const& v) { return infty_norm(v); }, std::forward<Vec>(vec)); + return invokeAtQP([](auto const& v) { return infty_norm(v); }, FWD(vec)); } /// \brief Applies \ref Operation::Trans to a matrix-valued GridFunction.\relates FunctorGridFunction @@ -211,7 +211,7 @@ namespace AMDiS REQUIRES(Concepts::AnyGridFunction<Mat>)> auto trans(Mat&& mat) { - return invokeAtQP(Operation::Trans{}, std::forward<Mat>(mat)); + return invokeAtQP(Operation::Trans{}, FWD(mat)); } // @} @@ -226,7 +226,7 @@ namespace AMDiS auto dot(Lhs&& lhs, Rhs&& rhs) { return invokeAtQP(Operation::Dot{}, - std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + FWD(lhs), FWD(rhs)); } /// \brief Applies a distance-functor to two vector-valued GridFunctions.\relates FunctorGridFunction @@ -236,7 +236,7 @@ namespace AMDiS { using namespace Operation; return invokeAtQP(compose(TwoNorm{}, Minus{}), - std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + FWD(lhs), FWD(rhs)); } /// \brief Applies an \ref outer() functor to two vector-valued GridFunctions. \relates FunctorGridFunction @@ -245,7 +245,7 @@ namespace AMDiS auto outer(Lhs&& lhs, Rhs&& rhs) { return invokeAtQP([](auto const& v, auto const& w) { return outer(v,w); }, - std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); + FWD(lhs), FWD(rhs)); } // @} diff --git a/src/amdis/operations/Basic.hpp b/src/amdis/operations/Basic.hpp index ed95863a..304023d1 100644 --- a/src/amdis/operations/Basic.hpp +++ b/src/amdis/operations/Basic.hpp @@ -117,7 +117,7 @@ namespace AMDiS template <class... Ts> constexpr auto&& operator()(Ts&&... args) const { - return std::get<I>(std::forward_as_tuple(std::forward<Ts>(args)...)); + return std::get<I>(std::forward_as_tuple(FWD(args)...)); } }; diff --git a/src/amdis/operations/Composer.hpp b/src/amdis/operations/Composer.hpp index 2e1338f0..586cc45b 100644 --- a/src/amdis/operations/Composer.hpp +++ b/src/amdis/operations/Composer.hpp @@ -32,8 +32,8 @@ namespace AMDiS template <class F_, class... Gs_, REQUIRES( Concepts::Similar<Types<F,Gs...>, Types<F_,Gs_...>>) > constexpr Composer(F_&& f, Gs_&&... gs) - : f_(std::forward<F_>(f)) - , gs_(std::forward<Gs_>(gs)...) + : f_(FWD(f)) + , gs_(FWD(gs)...) {} template <class... Ts> @@ -56,7 +56,7 @@ namespace AMDiS template <class F_, class... Gs_> static constexpr type build(F_&& f, Gs_&&... gs) { - return type{std::forward<F_>(f), std::forward<Gs_>(gs)...}; + return type{FWD(f), FWD(gs)...}; } }; #endif @@ -65,8 +65,7 @@ namespace AMDiS template <class F, class... Gs> constexpr auto compose(F&& f, Gs&&... gs) { - return ComposerBuilder<std::decay_t<F>, std::decay_t<Gs>...>::build( - std::forward<F>(f), std::forward<Gs>(gs)...); + return ComposerBuilder<TYPEOF(f), TYPEOF(gs)...>::build(FWD(f), FWD(gs)...); } // Polynomial order or composed function combines the orders of the sub-functions @@ -97,7 +96,7 @@ namespace AMDiS template <class F_> static constexpr F build(F_&& f) { - return F{std::forward<F_>(f)}; + return F{FWD(f)}; } }; #endif diff --git a/src/amdis/typetree/RangeType.hpp b/src/amdis/typetree/RangeType.hpp index 0e36925e..38b2ecec 100644 --- a/src/amdis/typetree/RangeType.hpp +++ b/src/amdis/typetree/RangeType.hpp @@ -43,7 +43,7 @@ namespace AMDiS { using LocalBasis = typename Node::FiniteElement::Traits::LocalBasisType; using T = typename LocalBasis::Traits::RangeType; - using type = std::decay_t<decltype(std::declval<R>() * std::declval<T>())>; + using type = remove_cvref_t<decltype(std::declval<R>() * std::declval<T>())>; }; // Power node diff --git a/src/amdis/typetree/Traversal.hpp b/src/amdis/typetree/Traversal.hpp index 3a02e742..a0255eb3 100644 --- a/src/amdis/typetree/Traversal.hpp +++ b/src/amdis/typetree/Traversal.hpp @@ -5,6 +5,7 @@ #include <dune/typetree/visitor.hh> #include <amdis/common/Loops.hpp> +#include <amdis/common/TypeTraits.hpp> namespace AMDiS { @@ -78,28 +79,28 @@ namespace AMDiS using Node = std::remove_reference_t<N>; using Visitor = std::remove_reference_t<V>; - v.pre(std::forward<N>(n),tp); + v.pre(FWD(n),tp); auto const deg = hybridDegree(NodeTag{}, n); forEach(Dune::range(deg), [&](auto const _k) { // always call beforeChild(), regardless of the value of visit - v.beforeChild(std::forward<N>(n),n.child(_k),tp,_k); + v.beforeChild(FWD(n),n.child(_k),tp,_k); // descend to child using C = typename HybridChildType<Node, decltype(_k)>::type; const bool visit = Visitor::template VisitChild<Node,C,TreePath>::value; - TraverseTree<Dune::TypeTree::NodeTag<C>,visit>::apply(n.child(_k),std::forward<V>(v),push_back(tp, _k)); + TraverseTree<Dune::TypeTree::NodeTag<C>,visit>::apply(n.child(_k),FWD(v),push_back(tp, _k)); // always call afterChild(), regardless of the value of visit - v.afterChild(std::forward<N>(n),n.child(_k),tp,_k); + v.afterChild(FWD(n),n.child(_k),tp,_k); // if this is not the last child, call infix callback if (notLastChild(_k, deg)) - v.in(std::forward<N>(n),tp); + v.in(FWD(n),tp); }); - v.post(std::forward<N>(n),tp); + v.post(FWD(n),tp); } }; @@ -110,7 +111,7 @@ namespace AMDiS template <typename N, typename V, typename TreePath> static void apply(N&& n, V&& v, TreePath const& tp) { - v.leaf(std::forward<N>(n),tp); + v.leaf(FWD(n),tp); } }; @@ -131,7 +132,7 @@ namespace AMDiS using Node = std::remove_reference_t<Tree>; using NodeTag = Dune::TypeTree::NodeTag<Node>; using TreePath = Dune::TypeTree::HybridTreePath<>; - TraverseTree<NodeTag>::apply(std::forward<Tree>(tree), std::forward<Visitor>(visitor), TreePath{}); + TraverseTree<NodeTag>::apply(FWD(tree), FWD(visitor), TreePath{}); } } // end namespace AMDiS -- GitLab