Skip to content

Commit

Permalink
Metaprogramming facilities
Browse files Browse the repository at this point in the history
  • Loading branch information
cbritopacheco committed Jan 31, 2024
1 parent e308cc0 commit 6233f08
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 89 deletions.
42 changes: 41 additions & 1 deletion examples/PDEs/Darcy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@ using namespace Rodin;
using namespace Rodin::Geometry;
using namespace Rodin::Variational;

template <class T>
struct IsTrialFunctionReferenceWrapper
{
static constexpr Boolean Value = false;
};

template <class T>
struct IsTrialFunctionReferenceWrapper<std::reference_wrapper<T>>
{
static constexpr Boolean Value = IsTrialFunction<T>::Value;
};

template <class T>
struct IsTestFunctionReferenceWrapper
{
static constexpr Boolean Value = false;
};

template <class T>
struct IsTestFunctionReferenceWrapper<std::reference_wrapper<T>>
{
static constexpr Boolean Value = IsTestFunction<T>::Value;
};

template <class T>
struct IsFloatingPoint
{
Expand All @@ -25,6 +49,13 @@ auto foo(const T& v)
return 2 * v;
}


template <class L, class R>
struct Pair
{
};


int main(int argc, char** argv)
{
// Load mesh
Expand All @@ -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<int, char, bool>, Tuple<float, double>>::Type<Pair>;
auto res = us.filter<IsTrialFunctionReferenceWrapper>();

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;
Expand Down
51 changes: 40 additions & 11 deletions src/Rodin/Tuple.h
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -48,6 +54,13 @@ namespace Rodin
constexpr
void apply(Function&& func)
{}

inline
constexpr
size_t size() const
{
return 0;
}
};

Tuple() -> Tuple<>;
Expand Down Expand Up @@ -79,7 +92,7 @@ namespace Rodin
constexpr
void apply(Function&& func)
{
applyImpl(std::forward<Function>(func), std::index_sequence_for<Ts...>{});
applyImpl(std::forward<Function>(func), std::index_sequence_for<T, Ts...>{});
}

template <std::size_t Index>
Expand Down Expand Up @@ -111,16 +124,30 @@ namespace Rodin
constexpr
auto map(Func&& func) const
{
return mapImpl(std::index_sequence_for<Ts...>(), std::forward<Func>(func));
return mapImpl(std::index_sequence_for<T, Ts...>(), std::forward<Func>(func));
}

inline
constexpr
Tuple concatenate(const Tuple<>& other) const
{
return *this;
}

template <typename ... Gs>
inline
constexpr
Tuple<Ts..., Gs...> concatenate(const Tuple<Gs...>& other) const
Tuple<T, Ts..., Gs...> concatenate(const Tuple<Gs...>& other) const
{
return concatenateImpl(other,
std::index_sequence_for<Ts...>(), std::index_sequence_for<Gs...>());
std::index_sequence_for<T, Ts...>(), std::index_sequence_for<Gs...>());
}

inline
constexpr
size_t size() const
{
return sizeof...(Ts) + 1;
}

private:
Expand All @@ -129,34 +156,36 @@ namespace Rodin
constexpr
void applyImpl(Function&& func, std::index_sequence<Indices...>)
{
(func(std::get<Indices>(*this)), ...);
(func(get<Indices>()), ...);
}

template <std::size_t ... Is, typename Func>
template <size_t I0, std::size_t ... Is, typename Func>
inline
constexpr
auto mapImpl(std::index_sequence<Is...>, Func&& func) const
auto mapImpl(std::index_sequence<I0, Is...>, Func&& func) const
{
return Tuple<std::invoke_result_t<Func, Ts>...>(func(get<Is>())...);
return Tuple<
std::invoke_result_t<Func, T>,
std::invoke_result_t<Func, Ts>...>(func(get<I0>()), func(get<Is>())...);
}

template <typename ... Gs, std::size_t... Indices1, std::size_t... Indices2>
inline
constexpr
Tuple<Ts..., Gs...> concatenateImpl(
Tuple<T, Ts..., Gs...> concatenateImpl(
const Tuple<Gs...>& other,
std::index_sequence<Indices1...>,
std::index_sequence<Indices2...>) const
{
return Tuple<Ts..., Gs...>(get<Indices1>()..., other.template get<Indices2>()...);
return Tuple<T, Ts..., Gs...>{get<Indices1>()..., other.template get<Indices2>()...};
}

template <std::size_t Index, template <class> class Predicate>
inline
constexpr
auto filterImpl() const
{
if constexpr(Index == sizeof...(Ts))
if constexpr(Index == sizeof...(Ts) + 1)
{
return Tuple<>{};
}
Expand Down
26 changes: 26 additions & 0 deletions src/Rodin/Utility/Extract.h
Original file line number Diff line number Diff line change
@@ -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 <class ...>
struct Extract;

template <class T, class ... Ts>
struct Extract<Tuple<T, Ts...>>
{
template <template <class> class Extractor>
using Type = Tuple<typename Extractor<T>::Type, typename Extractor<Ts>::Type...>;
};
}

#endif

6 changes: 6 additions & 0 deletions src/Rodin/Utility/ParameterPack.h
Original file line number Diff line number Diff line change
@@ -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_UTILITY_PARAMETERPACK_H
#define RODIN_UTILITY_PARAMETERPACK_H

Expand Down
50 changes: 50 additions & 0 deletions src/Rodin/Utility/Product.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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_PRODUCT_H
#define RODIN_UTILITY_PRODUCT_H

#include "Rodin/Tuple.h"

namespace Rodin::Utility
{
template <class ...>
struct Product;

template <class H1, class H2, class ... Hs, class ... Gs>
struct Product<Tuple<H1, H2, Hs...>, Tuple<Gs...>>
{
template <template <class, class> class Pair>
using Type =
decltype(
std::declval<Tuple<Pair<H1, Gs>...>>().concatenate(
std::declval<Tuple<Pair<H2, Gs>...>>()).concatenate(
std::declval<typename Product<Tuple<Hs...>, Tuple<Gs...>>::template Type<Pair>>()));
};

template <class H, class ... Gs>
struct Product<Tuple<H>, Tuple<Gs...>>
{
template <template <class, class> class Pair>
using Type = Tuple<Pair<H, Gs>...>;
};

template <class ... Gs>
struct Product<Tuple<>, Tuple<Gs...>>
{
using Type = Tuple<>;
};

template <class ... Gs>
struct Product<Tuple<Gs...>, Tuple<>>
{
using Type = Tuple<>;
};
}

#endif


1 change: 1 addition & 0 deletions src/Rodin/Variational.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "Variational/GridFunction.h"
#include "Variational/FiniteElementSpace.h"

#include "Variational/ShapeFunction.h"
#include "Variational/TrialFunction.h"
#include "Variational/TestFunction.h"

Expand Down
Loading

0 comments on commit 6233f08

Please sign in to comment.