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

Cleanup the treepath functions and concepts

parent f9a94a4e
......@@ -39,7 +39,7 @@
#include <amdis/GridFunctions.hpp>
#include <amdis/gridfunctions/DiscreteFunction.hpp>
#include <amdis/io/FileWriterBase.hpp>
#include <amdis/typetree/Traits.hpp>
#include <amdis/typetree/Concepts.hpp>
#include <amdis/typetree/TreePath.hpp>
namespace AMDiS
......
install(FILES
Concepts.hpp
FiniteElementType.hpp
MultiIndex.hpp
RangeType.hpp
Traits.hpp
Traversal.hpp
TreeContainer.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,224 +9,196 @@
#include <dune/typetree/treepath.hh>
#include <dune/typetree/typetraits.hh>
#include <amdis/common/Apply.hpp>
#include <amdis/common/Logical.hpp>
namespace AMDiS
{
using RootTreePath = Dune::TypeTree::HybridTreePath<>;
namespace Concepts
{
/** \addtogroup Concepts
* @{
**/
namespace AMDiS {
namespace Definition
{
template <class Index>
struct IsPreTreePath
: std::is_integral<Index>
{};
using RootTreePath = Dune::TypeTree::HybridTreePath<>;
template <class Index, Index I>
struct IsPreTreePath<std::integral_constant<Index, I>>
: std::is_integral<Index>
{};
namespace Concepts {
template <class Index, Index... I>
struct IsPreTreePath<std::integer_sequence<Index, I...>>
: std::is_integral<Index>
{};
/** \addtogroup Concepts
* @{
**/
template <class... Indices>
struct IsPreTreePath<std::tuple<Indices...>>
: std::conjunction<std::is_integral<Indices>...>
{};
namespace Definition
{
template <class Index>
struct IsPreTreePath
: std::is_integral<Index>
{};
} // end namespace Definition
template <class Index, Index I>
struct IsPreTreePath<std::integral_constant<Index, I>>
: std::is_integral<Index>
{};
template <class TP>
constexpr bool PreTreePath = Dune::TypeTree::IsTreePath<TP>::value || Definition::IsPreTreePath<TP>::value;
template <class Index, Index... I>
struct IsPreTreePath<std::integer_sequence<Index, I...>>
: std::is_integral<Index>
{};
template <class TP>
using PreTreePath_t = bool_t<PreTreePath<TP>>;
template <class... Indices>
struct IsPreTreePath<std::tuple<Indices...>>
: std::conjunction<std::is_integral<Indices>...>
{};
/** @} **/
} // end namespace Definition
} // end namespace Concepts
template <class TP>
constexpr bool PreTreePath = Dune::TypeTree::IsTreePath<TP>::value || Definition::IsPreTreePath<TP>::value;
namespace Impl
{
template <class Index,
std::enable_if_t<std::is_integral_v<Index>, int> = 0>
std::size_t treePathIndex(Index i)
{
return std::size_t(i);
}
template <class Index, Index i,
std::enable_if_t<std::is_integral_v<Index>, int> = 0>
auto treePathIndex(std::integral_constant<Index,i>)
{
return std::integral_constant<std::size_t,std::size_t(i)>{};
}
} // end namespace Impl
template <class TP>
using PreTreePath_t = bool_t<PreTreePath<TP>>;
#ifdef DOXYGEN
/** @} **/
/// \brief Converts a sequence of indices into a HybridTreePath
/**
* Converts an integer, an integralconstant, a sequence of those, or a TreePath
* into an \ref Dune::TypeTree::HybridTreePath that is used in GlobalBasis traversal.
*
* **Requirements:**
* The arguments can be one or more of
* - integer type (`int, std::size_t`)
* - integral constant (`std::integral_constant<[int|std::size_t],i>, index_t<i>`)
* or one of dune treepath types, e.g.
* - any Dune TreePath (`TreePath<std::size_t...>, HybridTreePath<class... T>`)
* - a `std::tuple` type
*
* **Example:**
* ```
* makeTreePath(0,1,2),
* makeTreePath(int_<2>, 0),
* makeTreePath(1, index_<2>),
* makeTreePath(hybridTreePath(0,1,2)),
* makeTreePath(std::tuple{0,index_<2>,2})
* ```
**/
template <class PreTreePath>
auto makeTreePath(PreTreePath tp);
} // end namespace Concepts
#else // DOXYGEN
template <class... Indices>
auto makeTreePath(Indices... ii)
-> decltype( Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...) )
{
return Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...);
}
inline auto makeTreePath()
namespace Impl
{
template <class Index,
std::enable_if_t<std::is_integral_v<Index>, int> = 0>
std::size_t treePathIndex(Index i)
{
return Dune::TypeTree::hybridTreePath();
return std::size_t(i);
}
template <class Index, Index... I>
auto makeTreePath(std::integer_sequence<Index, I...>)
template <class Index, Index i,
std::enable_if_t<std::is_integral_v<Index>, int> = 0>
auto treePathIndex(std::integral_constant<Index,i>)
{
return makeTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...);
return std::integral_constant<std::size_t,std::size_t(i)>{};
}
template <class... T>
auto makeTreePath(std::tuple<T...> const& tp)
{
return std::apply([](auto... ii) { return makeTreePath(ii...); }, tp);
}
} // end namespace Impl
template <class... T>
auto const& makeTreePath(Dune::TypeTree::HybridTreePath<T...> const& tp)
{
return tp;
}
#ifdef DOXYGEN
#if DUNE_VERSION_LT(DUNE_TYPETREE,2,7)
template <std::size_t... I>
auto makeTreePath(Dune::TypeTree::TreePath<I...>)
{
return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
}
#else
template <std::size_t... I>
auto makeTreePath(Dune::TypeTree::StaticTreePath<I...>)
{
return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
}
#endif
/// \brief Converts a sequence of indices into a HybridTreePath
/**
* Converts an integer, an integralconstant, a sequence of those, or a TreePath
* into an \ref Dune::TypeTree::HybridTreePath that is used in GlobalBasis traversal.
*
* **Requirements:**
* The arguments can be one or more of
* - integer type (`int, std::size_t`)
* - integral constant (`std::integral_constant<[int|std::size_t],i>, index_t<i>`)
* or one of dune treepath types, e.g.
* - any Dune TreePath (`TreePath<std::size_t...>, HybridTreePath<class... T>`)
* - a `std::tuple` type
*
* **Example:**
* ```
* makeTreePath(0,1,2),
* makeTreePath(int_<2>, 0),
* makeTreePath(1, index_<2>),
* makeTreePath(hybridTreePath(0,1,2)),
* makeTreePath(std::tuple{0,index_<2>,2})
* ```
**/
template <class PreTreePath>
auto makeTreePath(PreTreePath tp);
#endif // DOXYGEN
#else // DOXYGEN
template <class... Indices>
auto makeTreePath(Indices... ii)
-> decltype( Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...) )
{
return Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...);
}
namespace Impl
{
template <class TreePath, std::size_t... I>
void printTreePath(std::ostream& os, TreePath const& tp, std::index_sequence<I...>)
{
(void)std::initializer_list<int>{
((void)(os << treePathIndex(tp, std::integral_constant<std::size_t, I>{}) << ","), 0)...
};
}
}
inline auto makeTreePath()
{
return Dune::TypeTree::hybridTreePath();
}
template <class T0, class... T>
std::string to_string(Dune::TypeTree::HybridTreePath<T0,T...> const& tp)
{
std::stringstream ss;
Impl::printTreePath(ss, tp, std::make_index_sequence<sizeof...(T)>{});
ss << Dune::TypeTree::treePathEntry<sizeof...(T)>(tp);
return ss.str();
}
template <class Index, Index... I>
auto makeTreePath(std::integer_sequence<Index, I...>)
{
return makeTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...);
}
inline std::string to_string(Dune::TypeTree::HybridTreePath<> const&)
{
return "";
}
template <class... T>
auto makeTreePath(std::tuple<T...> const& tp)
{
return std::apply([](auto... ii) { return makeTreePath(ii...); }, tp);
}
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... T>
auto const& makeTreePath(Dune::TypeTree::HybridTreePath<T...> const& tp)
{
return 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)>{});
}
#if DUNE_VERSION_LT(DUNE_TYPETREE,2,7)
template <std::size_t... I>
auto makeTreePath(Dune::TypeTree::TreePath<I...>)
{
return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
}
#else
template <std::size_t... I>
auto makeTreePath(Dune::TypeTree::StaticTreePath<I...>)
{
return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
}
#endif
inline std::array<std::size_t,1> to_array(Dune::TypeTree::HybridTreePath<> const&)
{
return {{0u}};
}
#endif // DOXYGEN
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)...);
}
}
// convert a treepath into a string, comma-separated
template <class... T>
std::string to_string(Dune::TypeTree::HybridTreePath<T...> const& tp)
{
auto entry = [&](auto i) { return std::to_string(std::size_t(Dune::TypeTree::treePathEntry<i>(tp))); };
auto first = [&] { return entry(std::integral_constant<std::size_t,0>()); };
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)>{});
}
return Ranges::applyIndices<1,sizeof...(T)>([&](auto... i) -> std::string {
return (first() +...+ ("," + entry(i)));
});
}
template <class... T, class TN>
Dune::TypeTree::HybridTreePath<T...> pop_front(Dune::TypeTree::HybridTreePath<T...,TN> const& tp)
{
return Impl::popBackImpl(tp, std::make_index_sequence<sizeof...(T)>{});
}
inline std::string to_string(Dune::TypeTree::HybridTreePath<> const&)
{
return "";
}
template <class... S, class... T>
Dune::TypeTree::HybridTreePath<S...,T...> 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));
}
// convert a treepath into an array
template <class... T>
auto to_array(Dune::TypeTree::HybridTreePath<T...> const& tp)
{
return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
return std::array<std::size_t,sizeof...(T)>{std::size_t(Dune::TypeTree::treePathEntry<i>(tp))...};
});
}
/// 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));
}
} // end namespace AMDiS
......@@ -8,7 +8,7 @@
#include <amdis/Environment.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/typetree/Traits.hpp>
#include <amdis/typetree/Concepts.hpp>
#include <amdis/typetree/TreePath.hpp>
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