Loading...
Searching...
No Matches
compositenode.hh
Go to the documentation of this file.
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-GPL-2.0-only-with-PDELab-exception
#ifndef DUNE_TYPETREE_COMPOSITENODE_HH
#define DUNE_TYPETREE_COMPOSITENODE_HH
#include <tuple>
#include <memory>
#include <type_traits>
#include <dune/typetree/nodetags.hh>
#include <dune/typetree/childextraction.hh>
#include <dune/typetree/typetraits.hh>
namespace Dune {
namespace TypeTree {
template<typename... Children>
class CompositeNode
{
public:
typedef CompositeNodeTag NodeTag;
typedef std::tuple<std::shared_ptr<Children>... > NodeStorage;
typedef std::tuple<Children...> ChildTypes;
static const bool isLeaf = false;
static const bool isPower = false;
static const bool isComposite = true;
static constexpr auto degree ()
{
return std::integral_constant<std::size_t,sizeof...(Children)>{};
}
template<std::size_t k>
struct Child {
static_assert((k < degree()), "child index out of range");
typedef typename std::tuple_element<k,ChildTypes>::type Type;
typedef typename std::tuple_element<k,ChildTypes>::type type;
};
template<std::size_t k>
typename Child<k>::Type& child (index_constant<k> = {})
{
return *std::get<k>(_children);
}
template<std::size_t k>
const typename Child<k>::Type& child (index_constant<k> = {}) const
{
return *std::get<k>(_children);
}
template<std::size_t k>
std::shared_ptr<typename Child<k>::Type> childStorage (index_constant<k> = {})
{
return std::get<k>(_children);
}
template<std::size_t k>
std::shared_ptr<const typename Child<k>::Type> childStorage (index_constant<k> = {}) const
{
return std::get<k>(_children);
}
template<std::size_t k>
void setChild (typename Child<k>::Type& child, index_constant<k> = {})
{
std::get<k>(_children) = stackobject_to_shared_ptr(child);
}
template<std::size_t k>
void setChild (typename Child<k>::Type&& child, index_constant<k> = {})
{
std::get<k>(_children) = convert_arg(std::move(child));
}
template<std::size_t k>
void setChild (std::shared_ptr<typename Child<k>::Type> child, index_constant<k> = {})
{
std::get<k>(_children) = std::move(child);
}
const NodeStorage& nodeStorage () const
{
return _children;
}
// The following two methods require a little bit of SFINAE trickery to work correctly:
// We have to make sure that they don't shadow the methods for direct child access because
// those get called by the generic child() machinery. If that machinery picks up the methods
// defined below, we have an infinite recursion.
// So the methods make sure that either
//
// * there are more than one argument. In that case, we got multiple indices and can forward
// to the general machine.
//
// * the first argument is not a valid flat index, i.e. either a std::size_t or an index_constant.
// The argument thus has to be some kind of TreePath instance that we can also pass to the
// generic machine.
//
// The above SFINAE logic works, but there is still a problem with the return type deduction.
// We have to do a lazy lookup of the return type after SFINAE has succeeded, otherwise the return
// type deduction will trigger the infinite recursion.
#ifdef DOXYGEN
template<typename... Indices>
ImplementationDefined& child (Indices... indices)
#else
template<typename I0, typename... I,
std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
decltype(auto) child (I0 i0, I... i)
#endif
{
static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
"You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
);
return Dune::TypeTree::child(*this,i0,i...);
}
#ifdef DOXYGEN
template<typename... Indices>
const ImplementationDefined& child (Indices... indices)
#else
template<typename I0, typename... I,
std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
decltype(auto) child (I0 i0, I... i) const
#endif
{
static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
"You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
);
return Dune::TypeTree::child(*this,i0,i...);
}
protected:
CompositeNode ()
{}
template<typename... Args, typename = typename std::enable_if<(sizeof...(Args) == degree())>::type>
CompositeNode (Args&&... args)
: _children(convert_arg(std::forward<Args>(args))...)
{}
CompositeNode (std::shared_ptr<Children>... children)
: _children(std::move(children)...)
{}
CompositeNode (const NodeStorage& children)
: _children(children)
{}
private:
NodeStorage _children;
};
} // namespace TypeTree
} //namespace Dune
#endif // DUNE_TYPETREE_COMPOSITENODE_HH
typetraits.hh
nodetags.hh
childextraction.hh
Dune
Definition accumulate_static.hh:17
Dune::TypeTree
Definition accumulate_static.hh:18
Dune::TypeTree::CompositeNode::isLeaf
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition compositenode.hh:42
Dune::TypeTree::CompositeNode::child
ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition compositenode.hh:166
Dune::TypeTree::CompositeNode::isComposite
static const bool isComposite
Mark this class as a composite in the dune-typetree.
Definition compositenode.hh:48
Dune::TypeTree::CompositeNode::CompositeNode
CompositeNode()
Default constructor.
Definition compositenode.hh:214
Dune::TypeTree::CompositeNode::NodeTag
CompositeNodeTag NodeTag
The type tag that describes a CompositeNode.
Definition compositenode.hh:33
Dune::TypeTree::CompositeNode::setChild
void setChild(typename Child< k >::Type &child, index_constant< k >={})
Sets the k-th child to the passed-in value.
Definition compositenode.hh:113
Dune::TypeTree::CompositeNode::setChild
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition compositenode.hh:120
Dune::TypeTree::CompositeNode::degree
static constexpr auto degree()
Definition compositenode.hh:50
Dune::TypeTree::CompositeNode::nodeStorage
const NodeStorage & nodeStorage() const
Definition compositenode.hh:132
Dune::TypeTree::CompositeNode::CompositeNode
CompositeNode(std::shared_ptr< Children >... children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition compositenode.hh:224
Dune::TypeTree::CompositeNode::childStorage
std::shared_ptr< typename Child< k >::Type > childStorage(index_constant< k >={})
Returns the storage of the k-th child.
Definition compositenode.hh:96
Dune::TypeTree::CompositeNode::ChildTypes
std::tuple< Children... > ChildTypes
A tuple storing the types of all children.
Definition compositenode.hh:39
Dune::TypeTree::CompositeNode::setChild
void setChild(std::shared_ptr< typename Child< k >::Type > child, index_constant< k >={})
Sets the storage of the k-th child to the passed-in value.
Definition compositenode.hh:127
Dune::TypeTree::CompositeNode::child
const ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition compositenode.hh:186
Dune::TypeTree::CompositeNode::isPower
static const bool isPower
Mark this class as a non power in the dune-typetree.
Definition compositenode.hh:45
Dune::TypeTree::CompositeNode::childStorage
std::shared_ptr< const typename Child< k >::Type > childStorage(index_constant< k >={}) const
Returns the storage of the k-th child (const version).
Definition compositenode.hh:106
Dune::TypeTree::CompositeNode::child
Child< k >::Type & child(index_constant< k >={})
Returns the k-th child.
Definition compositenode.hh:76
Dune::TypeTree::CompositeNode::CompositeNode
CompositeNode(const NodeStorage &children)
Initialize the CompositeNode with a copy of the passed-in storage type.
Definition compositenode.hh:229
Dune::TypeTree::CompositeNode::NodeStorage
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition compositenode.hh:36
Dune::TypeTree::CompositeNode::child
const Child< k >::Type & child(index_constant< k >={}) const
Returns the k-th child (const version).
Definition compositenode.hh:86
Dune::TypeTree::CompositeNode::Child
Access to the type and storage type of the i-th child.
Definition compositenode.hh:57
Dune::TypeTree::CompositeNode::Child::Type
std::tuple_element< k, ChildTypes >::type Type
The type of the child.
Definition compositenode.hh:62
Dune::TypeTree::CompositeNode::Child::type
std::tuple_element< k, ChildTypes >::type type
The type of the child.
Definition compositenode.hh:65
Dune::TypeTree::CompositeNodeTag
Tag designating a composite node.
Definition nodetags.hh:27
Dune::TypeTree::IsTreePath
Check if type represents a tree path.
Definition typetraits.hh:184