From 6233f08e287865edf7af142594179620243f39de Mon Sep 17 00:00:00 2001 From: Carlos Brito Date: Wed, 31 Jan 2024 17:56:52 +0100 Subject: [PATCH] Metaprogramming facilities --- examples/PDEs/Darcy.cpp | 42 ++++++++- src/Rodin/Tuple.h | 51 +++++++--- src/Rodin/Utility/Extract.h | 26 +++++ src/Rodin/Utility/ParameterPack.h | 6 ++ src/Rodin/Utility/Product.h | 50 ++++++++++ src/Rodin/Variational.h | 1 + src/Rodin/Variational/Problem.h | 131 ++++++++++++++++---------- src/Rodin/Variational/ShapeFunction.h | 48 ++++------ 8 files changed, 266 insertions(+), 89 deletions(-) create mode 100644 src/Rodin/Utility/Extract.h create mode 100644 src/Rodin/Utility/Product.h diff --git a/examples/PDEs/Darcy.cpp b/examples/PDEs/Darcy.cpp index 897b4cb03..2b24cf7c5 100644 --- a/examples/PDEs/Darcy.cpp +++ b/examples/PDEs/Darcy.cpp @@ -13,6 +13,30 @@ using namespace Rodin; using namespace Rodin::Geometry; using namespace Rodin::Variational; + template + struct IsTrialFunctionReferenceWrapper + { + static constexpr Boolean Value = false; + }; + + template + struct IsTrialFunctionReferenceWrapper> + { + static constexpr Boolean Value = IsTrialFunction::Value; + }; + + template + struct IsTestFunctionReferenceWrapper + { + static constexpr Boolean Value = false; + }; + + template + struct IsTestFunctionReferenceWrapper> + { + static constexpr Boolean Value = IsTestFunction::Value; + }; + template struct IsFloatingPoint { @@ -25,6 +49,13 @@ auto foo(const T& v) return 2 * v; } + +template +struct Pair +{ +}; + + int main(int argc, char** argv) { // Load mesh @@ -38,7 +69,16 @@ int main(int argc, char** argv) TrialFunction u(vh); TestFunction v(vh); - Problem problem(u, v, u, v, v); + Tuple us{std::ref(u), std::ref(v), std::ref(u), std::ref(v), std::ref(v), std::ref(u), std::ref(u)}; + + using Miaow = Utility::Product, Tuple>::Type; + auto res = us.filter(); + + Miaow t; + auto tt = t; + std::cout << res.size() << std::endl; + // Problem problem(u, v, u, v, v); + // trw.apply([](auto&& v){ std::cout << v << " "; }); std::cout << std::endl; diff --git a/src/Rodin/Tuple.h b/src/Rodin/Tuple.h index 0ef050a9f..d554dd24d 100644 --- a/src/Rodin/Tuple.h +++ b/src/Rodin/Tuple.h @@ -1,3 +1,9 @@ +/* + * Copyright Carlos BRITO PACHECO 2021 - 2022. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE or copy at + * https://www.boost.org/LICENSE_1_0.txt) + */ #ifndef RODIN_TUPLE_H #define RODIN_TUPLE_H @@ -48,6 +54,13 @@ namespace Rodin constexpr void apply(Function&& func) {} + + inline + constexpr + size_t size() const + { + return 0; + } }; Tuple() -> Tuple<>; @@ -79,7 +92,7 @@ namespace Rodin constexpr void apply(Function&& func) { - applyImpl(std::forward(func), std::index_sequence_for{}); + applyImpl(std::forward(func), std::index_sequence_for{}); } template @@ -111,16 +124,30 @@ namespace Rodin constexpr auto map(Func&& func) const { - return mapImpl(std::index_sequence_for(), std::forward(func)); + return mapImpl(std::index_sequence_for(), std::forward(func)); + } + + inline + constexpr + Tuple concatenate(const Tuple<>& other) const + { + return *this; } template inline constexpr - Tuple concatenate(const Tuple& other) const + Tuple concatenate(const Tuple& other) const { return concatenateImpl(other, - std::index_sequence_for(), std::index_sequence_for()); + std::index_sequence_for(), std::index_sequence_for()); + } + + inline + constexpr + size_t size() const + { + return sizeof...(Ts) + 1; } private: @@ -129,26 +156,28 @@ namespace Rodin constexpr void applyImpl(Function&& func, std::index_sequence) { - (func(std::get(*this)), ...); + (func(get()), ...); } - template + template inline constexpr - auto mapImpl(std::index_sequence, Func&& func) const + auto mapImpl(std::index_sequence, Func&& func) const { - return Tuple...>(func(get())...); + return Tuple< + std::invoke_result_t, + std::invoke_result_t...>(func(get()), func(get())...); } template inline constexpr - Tuple concatenateImpl( + Tuple concatenateImpl( const Tuple& other, std::index_sequence, std::index_sequence) const { - return Tuple(get()..., other.template get()...); + return Tuple{get()..., other.template get()...}; } template class Predicate> @@ -156,7 +185,7 @@ namespace Rodin constexpr auto filterImpl() const { - if constexpr(Index == sizeof...(Ts)) + if constexpr(Index == sizeof...(Ts) + 1) { return Tuple<>{}; } diff --git a/src/Rodin/Utility/Extract.h b/src/Rodin/Utility/Extract.h new file mode 100644 index 000000000..f9c2d9939 --- /dev/null +++ b/src/Rodin/Utility/Extract.h @@ -0,0 +1,26 @@ +/* + * Copyright Carlos BRITO PACHECO 2021 - 2022. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE or copy at + * https://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef RODIN_UTILITY_EXTRACT_H +#define RODIN_UTILITY_EXTRACT_H + +#include "Rodin/Tuple.h" + +namespace Rodin::Utility +{ + template + struct Extract; + + template + struct Extract> + { + template