DUNE PDELab (git)

containerdescriptors.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_CONTAINERDESCRIPTORS_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_CONTAINERDESCRIPTORS_HH
9
10#include <array>
11#include <cassert>
12#include <functional>
13#include <type_traits>
14#include <vector>
15
19
20#include <dune/functions/common/type_traits.hh>
21#include <dune/functions/functionspacebases/basistags.hh>
22
46namespace Dune::Functions {
47namespace ContainerDescriptors {
48
50struct Unknown {};
51
52} // end namespace ContainerDescriptors
53
54namespace Impl {
55
56template<class PreBasis>
57auto containerDescriptorImpl(const PreBasis& preBasis, Dune::PriorityTag<1>)
58 -> decltype(preBasis.containerDescriptor())
59{
60 return preBasis.containerDescriptor();
61}
62
63template<class PreBasis>
64auto containerDescriptorImpl(const PreBasis& preBasis, Dune::PriorityTag<0>)
65{
66 return ContainerDescriptors::Unknown{};
67}
68
69} // end namespace Impl
70
72template<class PreBasis>
73auto containerDescriptor(const PreBasis& preBasis)
74{
75 return Impl::containerDescriptorImpl(preBasis, Dune::PriorityTag<2>{});
76}
77
78
79namespace ContainerDescriptors {
80
82struct Value
83{
85 template<class Index>
86 Value operator[] (const Index&) const { return {}; }
87
89 static constexpr std::size_t size () { return 0; }
90};
91
93template<class... Children>
94using Tuple = Dune::TupleVector<Children...>;
95
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)
102{
103 using Descriptor = Tuple<Child0,Children...>;
104 return Descriptor{std::move(child0),std::move(children)...};
105}
106
107
109template<class Child, std::size_t n>
110using Array = std::array<Child, n>;
111
113template<class Child0, class... Children,
114 std::enable_if_t<(std::is_same_v<Child0, Children> &&...), int> = 0>
115auto makeDescriptor (Child0 child, Children... children)
116{
117 using Descriptor = Array<Child0,1+sizeof...(Children)>;
118 return Descriptor{std::move(child),std::move(children)...};
119}
120
121
123template<class Child>
124using Vector = std::vector<Child>;
125
127template<class Child, std::size_t n>
129{
131 template<class C = Child,
132 std::enable_if_t<std::is_default_constructible_v<C>, int> = 0>
134 : child_{}
135 {}
136
139 : child_{std::move(child)}
140 {}
141
143 template<class Index>
144 const Child& operator[] (const Index& /*i*/) const { return child_; }
145
147 static constexpr std::size_t size () { return n; }
148
149private:
150 Child child_;
151};
152
154template<std::size_t n>
155using FlatArray = UniformArray<Value,n>;
156
158template<class Child, std::size_t n>
159auto makeUniformDescriptor (std::integral_constant<std::size_t,n>, Child child)
160{
161 return UniformArray<Child,n>{std::move(child)};
162}
163
164
166template<class Child>
168{
170 template<class C = Child,
171 std::enable_if_t<std::is_default_constructible_v<C>, int> = 0>
172 explicit UniformVector (std::size_t size)
173 : size_{size}
174 , child_{}
175 {}
176
179 : size_{size}
180 , child_{std::move(child)}
181 {}
182
184 template<class Index>
185 const Child& operator[] (const Index& /*i*/) const { return child_; }
186
188 std::size_t size () const { return size_; }
189
190private:
191 std::size_t size_;
192 Child child_;
193};
194
196using FlatVector = UniformVector<Value>;
197
199template<class Child>
200auto makeUniformDescriptor (std::size_t n, Child child)
201{
202 return UniformVector<Child>{n,std::move(child)};
203}
204
205namespace Impl {
206
207template<class InnerFunc, class LeafFunc>
208struct TreeTransform
209{
210 TreeTransform (const InnerFunc& innerFunc, const LeafFunc& leafFunc)
211 : innerFunc_(innerFunc)
212 , leafFunc_(leafFunc)
213 {}
214
215 Unknown operator() (const Unknown& tree) const
216 {
217 return tree;
218 }
219
220 auto operator() (const Value& tree) const
221 {
222 return leafFunc_(tree);
223 }
224
225 template<class... V>
226 auto operator() (const Tuple<V...>& tree) const
227 {
228 return unpackIntegerSequence([&](auto... ii) {
229 return makeDescriptor(innerFunc_(tree[ii])...);
230 }, std::make_index_sequence<sizeof...(V)>());
231 }
232
233 template<class V, std::size_t n>
234 auto operator() (const Array<V,n>& tree) const
235 {
236 return unpackIntegerSequence([&](auto... ii) {
237 return makeDescriptor(innerFunc_(tree[ii])...);
238 }, std::make_index_sequence<n>());
239 }
240
241 template<class V>
242 auto operator() (const Vector<V>& tree) const
243 {
244 using W = decltype(innerFunc_(tree[0]));
245 Vector<W> result;
246 result.reserve(tree.size());
247 for (std::size_t i = 0; i < tree.size(); ++i)
248 result.emplace_back(innerFunc_(tree[i]));
249 return result;
250 }
251
252 template<class V, std::size_t n>
253 auto operator() (const UniformArray<V,n>& tree) const
254 {
255 return makeUniformDescriptor(Dune::index_constant<n>{}, innerFunc_(tree[0]));
256 }
257
258 template<class V>
259 auto operator() (const UniformVector<V>& tree) const
260 {
261 return makeUniformDescriptor(tree.size(), innerFunc_(tree[0]));
262 }
263
264private:
265 InnerFunc innerFunc_;
266 LeafFunc leafFunc_;
267};
268
269
280template<class Size, class T>
281auto appendToTree (Size s, const T& tree)
282{
283 auto transform = TreeTransform(
284 [s](auto&& node) { return appendToTree(s, node); },
285 [s](auto&& node) { return makeUniformDescriptor(s, node); });
286 return transform(tree);
287}
288
289} // end namespace Impl
290} // end namespace ContainerDescriptors
291} // end namespace Dune::Functions
292
293#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_CONTAINERDESCRIPTORS_HH
A class augmenting std::tuple by element access via operator[].
Definition: tuplevector.hh:35
Utility to generate an array with a certain value.
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
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: indices.hh:29
typename impl::_Child< Node, indices... >::type Child
Template alias for the type of a child node given by a list of child indices.
Definition: childextraction.hh:225
ImplementationDefined child(Node &&node, Indices... indices)
Extracts the child of a node given by a sequence of compile-time and run-time indices.
Definition: childextraction.hh:128
STL namespace.
Descriptor for arrays with all children identical and the number of children a static size.
Definition: containerdescriptors.hh:129
static constexpr std::size_t size()
The static size information, i.e., number of children.
Definition: containerdescriptors.hh:147
UniformArray()
Default constructor. Is enable if the child-type is default constructible.
Definition: containerdescriptors.hh:133
UniformArray(Child child)
Constructor that stores a single child only.
Definition: containerdescriptors.hh:138
const Child & operator[](const Index &) const
Access the i'th child that is always the same, i.e., child_.
Definition: containerdescriptors.hh:144
Uniform descriptor with dynamic size.
Definition: containerdescriptors.hh:168
UniformVector(std::size_t size, Child child)
Constructor that stores the size and a single child only.
Definition: containerdescriptors.hh:178
std::size_t size() const
The dynamic size information, i.e., number of children.
Definition: containerdescriptors.hh:188
UniformVector(std::size_t size)
Default constructor with size. Is enable if the child-type is default constructible.
Definition: containerdescriptors.hh:172
const Child & operator[](const Index &) const
Access the i'th child that is always the same, i.e., child_.
Definition: containerdescriptors.hh:185
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
Helper class for tagging priorities.
Definition: typeutilities.hh:87
Helper class for tagging priorities.
Definition: typeutilities.hh:73
Provides the TupleVector class that augments std::tuple by operator[].
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 24, 23:30, 2024)