7#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_CONTAINERDESCRIPTORS_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_CONTAINERDESCRIPTORS_HH
16#include <dune/common/filledarray.hh>
17#include <dune/common/tuplevector.hh>
18#include <dune/common/typeutilities.hh>
20#include <dune/functions/common/type_traits.hh>
21#include <dune/functions/functionspacebases/basistags.hh>
46namespace Dune::Functions {
47namespace ContainerDescriptors {
56template<
class PreBasis>
57auto containerDescriptorImpl(
const PreBasis& preBasis, Dune::PriorityTag<1>)
58 ->
decltype(preBasis.containerDescriptor())
60 return preBasis.containerDescriptor();
63template<
class PreBasis>
64auto containerDescriptorImpl(
const PreBasis& preBasis, Dune::PriorityTag<0>)
66 return ContainerDescriptors::Unknown{};
72template<
class PreBasis>
73auto containerDescriptor(
const PreBasis& preBasis)
75 return Impl::containerDescriptorImpl(preBasis, Dune::PriorityTag<2>{});
79namespace ContainerDescriptors {
89 static constexpr std::size_t
size () {
return 0; }
93template<
class... Children>
94using Tuple = Dune::TupleVector<Children...>;
98template<
class Child0,
class... Children,
99 std::enable_if_t<(
sizeof...(Children) > 0),
int> = 0,
100 std::enable_if_t<(...|| (not std::is_same_v<Child0, Children>)),
int> = 0>
101auto makeDescriptor (Child0 child0, Children... children)
103 using Descriptor = Tuple<Child0,Children...>;
104 return Descriptor{std::move(child0),std::move(children)...};
109template<
class Child, std::
size_t n>
110using Array = std::array<Child, n>;
113template<
class Child0,
class... Children,
114 std::enable_if_t<(std::is_same_v<Child0, Children> &&...),
int> = 0>
115auto makeDescriptor (Child0 child, Children... children)
117 using Descriptor = Array<Child0,1+
sizeof...(Children)>;
118 return Descriptor{std::move(child),std::move(children)...};
124using Vector = std::vector<Child>;
127template<
class Child, std::
size_t n>
131 template<
class C = Child,
132 std::enable_if_t<std::is_default_constructible_v<C>,
int> = 0>
139 : child_{std::move(child)}
143 template<
class Index>
144 const Child&
operator[] (
const Index& )
const {
return child_; }
147 static constexpr std::size_t
size () {
return n; }
154template<std::
size_t n>
155using FlatArray = UniformArray<Value,n>;
158template<
class Child, std::
size_t n>
159auto makeUniformDescriptor (std::integral_constant<std::size_t,n>, Child child)
161 return UniformArray<Child,n>{std::move(child)};
170 template<
class C = Child,
171 std::enable_if_t<std::is_default_constructible_v<C>,
int> = 0>
180 , child_{std::move(child)}
184 template<
class Index>
185 const Child&
operator[] (
const Index& )
const {
return child_; }
188 std::size_t
size ()
const {
return size_; }
196using FlatVector = UniformVector<Value>;
200auto makeUniformDescriptor (std::size_t n, Child child)
202 return UniformVector<Child>{n,std::move(child)};
207template<
class InnerFunc,
class LeafFunc>
210 TreeTransform (
const InnerFunc& innerFunc,
const LeafFunc& leafFunc)
211 : innerFunc_(innerFunc)
212 , leafFunc_(leafFunc)
215 Unknown operator() (
const Unknown& tree)
const
220 auto operator() (
const Value& tree)
const
222 return leafFunc_(tree);
226 auto operator() (
const Tuple<V...>& tree)
const
228 return unpackIntegerSequence([&](
auto... ii) {
229 return makeDescriptor(innerFunc_(tree[ii])...);
230 }, std::make_index_sequence<
sizeof...(V)>());
233 template<
class V, std::
size_t n>
234 auto operator() (
const Array<V,n>& tree)
const
236 return unpackIntegerSequence([&](
auto... ii) {
237 return makeDescriptor(innerFunc_(tree[ii])...);
238 }, std::make_index_sequence<n>());
242 auto operator() (
const Vector<V>& tree)
const
244 using W =
decltype(innerFunc_(tree[0]));
246 result.reserve(tree.size());
247 for (std::size_t i = 0; i < tree.size(); ++i)
248 result.emplace_back(innerFunc_(tree[i]));
252 template<
class V, std::
size_t n>
253 auto operator() (
const UniformArray<V,n>& tree)
const
255 return makeUniformDescriptor(Dune::index_constant<n>{}, innerFunc_(tree[0]));
259 auto operator() (
const UniformVector<V>& tree)
const
261 return makeUniformDescriptor(tree.size(), innerFunc_(tree[0]));
265 InnerFunc innerFunc_;
280template<
class Size,
class T>
281auto appendToTree (Size s,
const T& tree)
283 auto transform = TreeTransform(
284 [s](
auto&& node) {
return appendToTree(s, node); },
285 [s](
auto&& node) {
return makeUniformDescriptor(s, node); });
286 return transform(tree);
Fallback container descriptor if nothing else fits.
Definition: containerdescriptors.hh:50
The node in the descriptor tree representing a value placeholder.
Definition: containerdescriptors.hh:83
static constexpr std::size_t size()
A value placeholder does not have any sub-descriptors, thus its size is zero.
Definition: containerdescriptors.hh:89
Value operator[](const Index &) const
The child access method is only available for the interface, but should not be called.
Definition: containerdescriptors.hh:86