Commit ba263fc2 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Cleanup the treepath functions and concepts

parent f9a94a4e
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include <amdis/GridFunctions.hpp> #include <amdis/GridFunctions.hpp>
#include <amdis/gridfunctions/DiscreteFunction.hpp> #include <amdis/gridfunctions/DiscreteFunction.hpp>
#include <amdis/io/FileWriterBase.hpp> #include <amdis/io/FileWriterBase.hpp>
#include <amdis/typetree/Traits.hpp> #include <amdis/typetree/Concepts.hpp>
#include <amdis/typetree/TreePath.hpp> #include <amdis/typetree/TreePath.hpp>
namespace AMDiS namespace AMDiS
......
install(FILES install(FILES
Concepts.hpp
FiniteElementType.hpp FiniteElementType.hpp
MultiIndex.hpp MultiIndex.hpp
RangeType.hpp RangeType.hpp
Traits.hpp
Traversal.hpp Traversal.hpp
TreeContainer.hpp TreeContainer.hpp
TreeContainerTrafo.hpp TreeContainerTrafo.hpp
......
#pragma once
#include <type_traits>
#include <dune/typetree/treepath.hh>
#include <amdis/typetree/TreePath.hpp>
namespace AMDiS {
namespace Traits {
template <class Tree, class TreePath, class NodeTag = typename Tree::NodeTag>
struct IsValidTreePath;
// empty treepath
template <class Tree, class NodeTag>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<>, NodeTag>
: std::true_type {};
// leaf nodes
template <class Tree, class I0, class... II>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<I0,II...>, Dune::TypeTree::LeafNodeTag>
: std::false_type {};
// power nodes
template <class Tree, class I0, class... II>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<I0,II...>, Dune::TypeTree::PowerNodeTag>
: IsValidTreePath<typename Tree::ChildType, Dune::TypeTree::HybridTreePath<II...>> {};
// composite node with integer index
template <class Tree, class I0, class... II>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<I0,II...>, Dune::TypeTree::CompositeNodeTag>
: std::false_type {};
// composite node with integral-constant index
template <class Tree, class Int, Int i, class... II>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<std::integral_constant<Int,i>,II...>, Dune::TypeTree::CompositeNodeTag>
: std::conditional_t<(i >= 0 && i < Tree::degree()),
IsValidTreePath<typename Tree::template Child<(i >= 0 && i < Tree::degree()) ? i : 0>::Type, Dune::TypeTree::HybridTreePath<II...>>,
std::false_type> {};
} // end namespace Traits
namespace Concepts {
/// \brief Check whether `Path` is a valid index of treepath for the given typetree `Tree`
template <class Tree, class Path>
static constexpr bool ValidTreePath = Traits::IsValidTreePath<Tree,TYPEOF(makeTreePath(std::declval<Path>()))>::value;
} // end namespace Concepts
} // end namespace AMDiS
#pragma once
#include <type_traits>
#include <dune/typetree/treepath.hh>
#include <amdis/typetree/TreePath.hpp>
namespace AMDiS
{
namespace Traits
{
template <class Tree, class TreePath, class NodeTag = typename Tree::NodeTag>
struct IsValidTreePath;
// empty treepath
template <class Tree, class NodeTag>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<>, NodeTag>
: std::true_type {};
// leaf nodes
template <class Tree, class I0, class... II>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<I0,II...>, Dune::TypeTree::LeafNodeTag>
: std::false_type {};
// power nodes
template <class Tree, class I0, class... II>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<I0,II...>, Dune::TypeTree::PowerNodeTag>
: IsValidTreePath<typename Tree::ChildType, Dune::TypeTree::HybridTreePath<II...>> {};
// composite node with integer index
template <class Tree, class I0, class... II>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<I0,II...>, Dune::TypeTree::CompositeNodeTag>
: std::false_type {};
// composite node with integral-constant index
template <class Tree, class Int, Int i, class... II>
struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<std::integral_constant<Int,i>,II...>, Dune::TypeTree::CompositeNodeTag>
: std::conditional_t<(i >= 0 && i < Tree::degree()),
IsValidTreePath<typename Tree::template Child<(i >= 0 && i < Tree::degree()) ? i : 0>::Type, Dune::TypeTree::HybridTreePath<II...>>,
std::false_type> {};
} // end namespace Traits
namespace Concepts
{
/// \brief Check whether `Path` is a valid index of treepath for the given typetree `Tree`
template <class Tree, class Path>
static constexpr bool ValidTreePath = Traits::IsValidTreePath<Tree,TYPEOF(makeTreePath(std::declval<Path>()))>::value;
}
} // end namespace AMDiS
...@@ -9,20 +9,21 @@ ...@@ -9,20 +9,21 @@
#include <dune/typetree/treepath.hh> #include <dune/typetree/treepath.hh>
#include <dune/typetree/typetraits.hh> #include <dune/typetree/typetraits.hh>
#include <amdis/common/Apply.hpp>
#include <amdis/common/Logical.hpp> #include <amdis/common/Logical.hpp>
namespace AMDiS namespace AMDiS {
{
using RootTreePath = Dune::TypeTree::HybridTreePath<>;
namespace Concepts using RootTreePath = Dune::TypeTree::HybridTreePath<>;
{
/** \addtogroup Concepts namespace Concepts {
/** \addtogroup Concepts
* @{ * @{
**/ **/
namespace Definition namespace Definition
{ {
template <class Index> template <class Index>
struct IsPreTreePath struct IsPreTreePath
: std::is_integral<Index> : std::is_integral<Index>
...@@ -43,20 +44,20 @@ namespace AMDiS ...@@ -43,20 +44,20 @@ namespace AMDiS
: std::conjunction<std::is_integral<Indices>...> : std::conjunction<std::is_integral<Indices>...>
{}; {};
} // end namespace Definition } // end namespace Definition
template <class TP> template <class TP>
constexpr bool PreTreePath = Dune::TypeTree::IsTreePath<TP>::value || Definition::IsPreTreePath<TP>::value; constexpr bool PreTreePath = Dune::TypeTree::IsTreePath<TP>::value || Definition::IsPreTreePath<TP>::value;
template <class TP> template <class TP>
using PreTreePath_t = bool_t<PreTreePath<TP>>; using PreTreePath_t = bool_t<PreTreePath<TP>>;
/** @} **/ /** @} **/
} // end namespace Concepts } // end namespace Concepts
namespace Impl namespace Impl
{ {
template <class Index, template <class Index,
std::enable_if_t<std::is_integral_v<Index>, int> = 0> std::enable_if_t<std::is_integral_v<Index>, int> = 0>
std::size_t treePathIndex(Index i) std::size_t treePathIndex(Index i)
...@@ -71,12 +72,12 @@ namespace AMDiS ...@@ -71,12 +72,12 @@ namespace AMDiS
return std::integral_constant<std::size_t,std::size_t(i)>{}; return std::integral_constant<std::size_t,std::size_t(i)>{};
} }
} // end namespace Impl } // end namespace Impl
#ifdef DOXYGEN #ifdef DOXYGEN
/// \brief Converts a sequence of indices into a HybridTreePath /// \brief Converts a sequence of indices into a HybridTreePath
/** /**
* Converts an integer, an integralconstant, a sequence of those, or a TreePath * Converts an integer, an integralconstant, a sequence of those, or a TreePath
* into an \ref Dune::TypeTree::HybridTreePath that is used in GlobalBasis traversal. * into an \ref Dune::TypeTree::HybridTreePath that is used in GlobalBasis traversal.
* *
...@@ -97,136 +98,107 @@ namespace AMDiS ...@@ -97,136 +98,107 @@ namespace AMDiS
* makeTreePath(std::tuple{0,index_<2>,2}) * makeTreePath(std::tuple{0,index_<2>,2})
* ``` * ```
**/ **/
template <class PreTreePath> template <class PreTreePath>
auto makeTreePath(PreTreePath tp); auto makeTreePath(PreTreePath tp);
#else // DOXYGEN #else // DOXYGEN
template <class... Indices> template <class... Indices>
auto makeTreePath(Indices... ii) auto makeTreePath(Indices... ii)
-> decltype( Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...) ) -> decltype( Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...) )
{ {
return Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...); return Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...);
} }
inline auto makeTreePath() inline auto makeTreePath()
{ {
return Dune::TypeTree::hybridTreePath(); return Dune::TypeTree::hybridTreePath();
} }
template <class Index, Index... I> template <class Index, Index... I>
auto makeTreePath(std::integer_sequence<Index, I...>) auto makeTreePath(std::integer_sequence<Index, I...>)
{ {
return makeTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...); return makeTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...);
} }
template <class... T> template <class... T>
auto makeTreePath(std::tuple<T...> const& tp) auto makeTreePath(std::tuple<T...> const& tp)
{ {
return std::apply([](auto... ii) { return makeTreePath(ii...); }, tp); return std::apply([](auto... ii) { return makeTreePath(ii...); }, tp);
} }
template <class... T> template <class... T>
auto const& makeTreePath(Dune::TypeTree::HybridTreePath<T...> const& tp) auto const& makeTreePath(Dune::TypeTree::HybridTreePath<T...> const& tp)
{ {
return tp; return tp;
} }
#if DUNE_VERSION_LT(DUNE_TYPETREE,2,7) #if DUNE_VERSION_LT(DUNE_TYPETREE,2,7)
template <std::size_t... I> template <std::size_t... I>
auto makeTreePath(Dune::TypeTree::TreePath<I...>) auto makeTreePath(Dune::TypeTree::TreePath<I...>)
{ {
return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...); return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
} }
#else #else
template <std::size_t... I> template <std::size_t... I>
auto makeTreePath(Dune::TypeTree::StaticTreePath<I...>) auto makeTreePath(Dune::TypeTree::StaticTreePath<I...>)
{ {
return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...); return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
} }
#endif #endif
#endif // DOXYGEN #endif // DOXYGEN
namespace Impl // convert a treepath into a string, comma-separated
{ template <class... T>
template <class TreePath, std::size_t... I> std::string to_string(Dune::TypeTree::HybridTreePath<T...> const& tp)
void printTreePath(std::ostream& os, TreePath const& tp, std::index_sequence<I...>) {
{ auto entry = [&](auto i) { return std::to_string(std::size_t(Dune::TypeTree::treePathEntry<i>(tp))); };
(void)std::initializer_list<int>{ auto first = [&] { return entry(std::integral_constant<std::size_t,0>()); };
((void)(os << treePathIndex(tp, std::integral_constant<std::size_t, I>{}) << ","), 0)...
};
}
}
template <class T0, class... T> return Ranges::applyIndices<1,sizeof...(T)>([&](auto... i) -> std::string {
std::string to_string(Dune::TypeTree::HybridTreePath<T0,T...> const& tp) return (first() +...+ ("," + entry(i)));
{ });
std::stringstream ss; }
Impl::printTreePath(ss, tp, std::make_index_sequence<sizeof...(T)>{});
ss << Dune::TypeTree::treePathEntry<sizeof...(T)>(tp);
return ss.str();
}
inline std::string to_string(Dune::TypeTree::HybridTreePath<> const&) inline std::string to_string(Dune::TypeTree::HybridTreePath<> const&)
{ {
return ""; return "";
} }
namespace Impl
{
template <class TreePath, std::size_t... I>
std::array<std::size_t, sizeof...(I)> toArrayImpl(TreePath const& tp, std::index_sequence<I...>)
{
return {{std::size_t(Dune::TypeTree::treePathEntry<I>(tp))...}};
}
}
template <class T0, class... T>
auto to_array(Dune::TypeTree::HybridTreePath<T0,T...> const& tp)
{
return Impl::toArrayImpl(tp, std::make_index_sequence<1+sizeof...(T)>{});
}
inline std::array<std::size_t,1> to_array(Dune::TypeTree::HybridTreePath<> const&)
{
return {{0u}};
}
namespace Impl
{
template <class TreePath, std::size_t... I>
auto popFrontImpl(TreePath const& tp, std::index_sequence<I...>)
{
return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<I+1>(tp)...);
}
template <class TreePath, std::size_t... I>
auto popBackImpl(TreePath const& tp, std::index_sequence<I...>)
{
return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<I>(tp)...);
}
}
template <class T0, class... T>
Dune::TypeTree::HybridTreePath<T...> pop_front(Dune::TypeTree::HybridTreePath<T0,T...> const& tp)
{
return Impl::popFrontImpl(tp, std::make_index_sequence<sizeof...(T)>{});
}
template <class... T, class TN> // convert a treepath into an array
Dune::TypeTree::HybridTreePath<T...> pop_front(Dune::TypeTree::HybridTreePath<T...,TN> const& tp) template <class... T>
{ auto to_array(Dune::TypeTree::HybridTreePath<T...> const& tp)
return Impl::popBackImpl(tp, std::make_index_sequence<sizeof...(T)>{}); {
} return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
return std::array<std::size_t,sizeof...(T)>{std::size_t(Dune::TypeTree::treePathEntry<i>(tp))...};
template <class... S, class... T> });
Dune::TypeTree::HybridTreePath<S...,T...> cat(Dune::TypeTree::HybridTreePath<S...> const& tp0, }
Dune::TypeTree::HybridTreePath<T...> const& tp1)
{ /// Extract the first entry in the treepath
template <class T0, class... T>
auto pop_front(Dune::TypeTree::HybridTreePath<T0,T...> const& tp)
{
return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<i+1>(tp)...);
});
}
/// Extract the last entry in the treepath
template <class... T, class TN>
auto pop_back(Dune::TypeTree::HybridTreePath<T...,TN> const& tp)
{
return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<i>(tp)...);
});
}
/// Concatenate two treepaths
template <class... S, class... T>
auto cat(Dune::TypeTree::HybridTreePath<S...> const& tp0, Dune::TypeTree::HybridTreePath<T...> const& tp1)
{
return Dune::TypeTree::HybridTreePath<S...,T...>(std::tuple_cat(tp0._data,tp1._data)); return Dune::TypeTree::HybridTreePath<S...,T...>(std::tuple_cat(tp0._data,tp1._data));
} }
} // end namespace AMDiS } // end namespace AMDiS
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <amdis/Environment.hpp> #include <amdis/Environment.hpp>
#include <amdis/common/TypeTraits.hpp> #include <amdis/common/TypeTraits.hpp>
#include <amdis/typetree/Traits.hpp> #include <amdis/typetree/Concepts.hpp>
#include <amdis/typetree/TreePath.hpp> #include <amdis/typetree/TreePath.hpp>
using namespace AMDiS; using namespace AMDiS;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment