Loading...
Searching...
No Matches
childaccess.hh
Go to the documentation of this file.
// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=8 sw=2 sts=2:
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
#ifndef DUNE_COMMON_TYPETREE_CHILDACCESS_HH
#define DUNE_COMMON_TYPETREE_CHILDACCESS_HH
#include <cstddef>
#include <type_traits>
#include <utility>
#include <tuple>
#include <dune/common/indices.hh>
#include <dune/common/typelist.hh>
#include <dune/common/typetraits.hh>
#include <dune/common/hybridmultiindex.hh>
#include <dune/common/typetree/nodeconcepts.hh>
#include <dune/common/typetree/treepath.hh>
namespace Dune::TypeTree {
template<typename Node, typename... Indices>
decltype(auto) child (Node&& node, TreePath<Indices...> treePath)
{
if constexpr (sizeof...(Indices) == 0)
return std::forward<Node>(node);
else
{
using I0 = std::tuple_element_t<0, TreePath<Indices...>>;
if constexpr (Dune::IsIntegralConstant<I0>::value and Concept::StaticDegreeInnerTreeNode<Node>)
static_assert(I0::value < std::decay_t<Node>::degree(), "Child index out of range");
else
assert(std::size_t(treePath.front()) < node.degree() && "Child index out of range");
if constexpr (sizeof...(Indices) == 1)
return node.child(treePath.front());
else
return child(node.child(treePath.front()), pop_front(treePath));
}
}
template<typename Node, typename... Indices>
decltype(auto) child (Node&& node, Indices... indices)
{
return child(node, Dune::HybridMultiIndex{indices...});
}
namespace Impl {
// We could directly implement Child as
//
// using Child = std::decay_t<decltype(child(std::declval<Node>(), Dune::index_constant<indices>()...))>;
//
// but this triggers an internal compiler error in
// gcc 11, 12, and 13 while it does work with gcc 10
// and 14 and clang. This can be avoided by extracting
// this into a traits class.
template<typename Node, std::size_t... indices>
struct ChildTraits
{
using type = std::decay_t<decltype(child(std::declval<Node>(), Dune::index_constant<indices>()...))>;
};
}
template<typename Node, std::size_t... indices>
using Child = typename Impl::ChildTraits<Node, indices...>::type;
template<typename Node, typename TreePath>
using ChildForTreePath = std::decay_t<decltype(child(std::declval<Node>(), std::declval<TreePath>()))>;
namespace Impl {
template<class N>
static constexpr auto childTypes()
{
if constexpr (Dune::TypeTree::Concept::StaticDegreeInnerTreeNode<N>)
{
return Dune::unpackIntegerSequence([&](auto... i) {
return Dune::MetaType<std::tuple<Dune::TypeTree::Child<N, i>...>>{};
}, std::make_index_sequence<N::degree()>{});
}
else
return Dune::MetaType<void>{};
}
template<class N>
using Children = typename decltype(Impl::childTypes<N>())::type;
}
} //namespace Dune::TypeTree
#endif // DUNE_COMMON_TYPETREE_CHILDACCESS_HH
typetraits.hh
Traits for type conversions and type information.
typelist.hh
indices.hh
hybridmultiindex.hh
treepath.hh
nodeconcepts.hh
Dune::unpackIntegerSequence
decltype(auto) constexpr unpackIntegerSequence(F &&f, std::integer_sequence< I, i... > sequence)
Unpack an std::integer_sequence<I,i...> to std::integral_constant<I,i>...
Definition indices.hh:124
Dune::index_constant
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition indices.hh:29
Dune::TypeTree::child
decltype(auto) child(Node &&node, TreePath< Indices... > treePath)
Extracts the child of a node given by a TreePath object.
Definition childaccess.hh:55
Dune::TypeTree::Child
typename Impl::ChildTraits< Node, indices... >::type Child
Template alias for the type of a child node given by a list of child indices.
Definition childaccess.hh:129
Dune::TypeTree::ChildForTreePath
std::decay_t< decltype(child(std::declval< Node >(), std::declval< TreePath >()))> ChildForTreePath
Template alias for the type of a child node given by a TreePath type.
Definition childaccess.hh:140
Dune::TypeTree::TreePath
Dune::HybridMultiIndex< T... > TreePath
A type for representing tree paths that supports both compile time and run time indices.
Definition treepath.hh:43
Dune::TypeTree::treePath
constexpr auto treePath(const T &... t)
Constructs a new TreePath from the given indices.
Definition treepath.hh:55
Dune::Indices
Namespace with predefined compile time indices for the range [0,19].
Definition indices.hh:50
Dune::TypeTree
Definition childaccess.hh:23
Dune::TypeTree::pop_front
constexpr auto pop_front(const HybridMultiIndex< T... > &tp)
Removes first index on a HybridMultiIndex.
Definition hybridmultiindex.hh:374
Dune::HybridMultiIndex
A hybrid multi-index class that supports both compile time and run time indices.
Definition hybridmultiindex.hh:81
Dune::type
Dune::MetaType
A type that refers to another type.
Definition typelist.hh:33
Dune::IsIntegralConstant
Check if T is an std::integral_constant<I, i>.
Definition typetraits.hh:384
Dune::TypeTree::Concept::StaticDegreeInnerTreeNode
Model of an inner node of a typetree with compile time known degree and child access via index_consta...
Definition nodeconcepts.hh:41