Dune Core Modules (2.9.0)

utility.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 #ifndef DUNE_TYPETREE_UTILITY_HH
5 #define DUNE_TYPETREE_UTILITY_HH
6 
7 #include <memory>
8 #include <tuple>
9 #include <type_traits>
10 #include <utility>
11 #include <algorithm>
12 
14 #include <dune/common/indices.hh>
15 #include <dune/common/hybridutilities.hh>
16 #include <dune/typetree/nodeinterface.hh>
17 #include <dune/typetree/nodetags.hh>
18 
19 namespace Dune {
20  namespace TypeTree {
21 
26 #ifndef DOXYGEN
27 
28  template<typename T>
29  std::shared_ptr<T> convert_arg(const T& t)
30  {
31  return std::make_shared<T>(t);
32  }
33 
34  template<typename T>
35  std::shared_ptr<T> convert_arg(T& t)
36  {
37  return stackobject_to_shared_ptr(t);
38  }
39 
40  template<typename BaseType, typename T>
41  T& assertGridViewType(T& t)
42  {
43  static_assert((std::is_same<typename BaseType::Traits::GridViewType,
44  typename T::Traits::GridViewType>::value),
45  "GridViewType must be equal in all components of composite type");
46  return t;
47  }
48 
49  // only bind to real rvalues
50  template<typename T>
51  typename std::enable_if<!std::is_lvalue_reference<T>::value,std::shared_ptr<T> >::type convert_arg(T&& t)
52  {
53  return std::make_shared<T>(std::forward<T>(t));
54  }
55 
56 
57  namespace Experimental {
58 
67  template<class BinaryOp, class Arg>
68  constexpr decltype(auto)
69  left_fold(BinaryOp&& binary_op, Arg&& arg)
70  {
71  return std::forward<Arg>(arg);
72  }
73 
95  template<class BinaryOp, class Init, class Arg0, class... Args>
96  constexpr decltype(auto)
97  left_fold(BinaryOp&& binary_op, Init&& init, Arg0&& arg_0, Args&&... args)
98  {
99  return left_fold(
100  std::forward<BinaryOp>(binary_op),
101  binary_op(std::forward<Init>(init), std::forward<Arg0>(arg_0)),
102  std::forward<Args>(args)...);
103  }
104 
105 
106  namespace Hybrid {
107  using namespace Dune::Hybrid;
108 
109  namespace Detail {
110  template<class Op, class... Args>
111  constexpr auto applyOperator(Op&& op, Args&&... args)
112  {
113  using T = std::common_type_t<Args...>;
114  return op(static_cast<T>(args)...);
115  }
116 
117  template<class Op, class T, T... Args>
118  constexpr auto applyOperator(Op, std::integral_constant<T,Args>...)
119  {
120  static_assert(std::is_default_constructible_v<Op>,
121  "Operator in integral expressions shall be default constructible");
122  constexpr auto result = Op{}(T{Args}...);
123  return std::integral_constant<std::decay_t<decltype(result)>,result>{};
124  }
125 
126  // FIXME: use lambda when we adpot c++20
127  struct Max {
128  template<class... Args>
129  constexpr auto operator()(Args&&... args) const
130  {
131  using T = std::common_type_t<Args...>;
132  return std::max({static_cast<T>(args)...});
133  }
134  };
135  }
136 
137  static constexpr auto max = [](const auto& a, const auto& b)
138  {
139  return Detail::applyOperator(Detail::Max{}, a, b);
140  };
141 
142  static constexpr auto plus = [](const auto& a, const auto& b)
143  {
144  return Detail::applyOperator(std::plus<>{}, a, b);
145  };
146 
147  static constexpr auto minus = [](const auto& a, const auto& b)
148  {
149  return Detail::applyOperator(std::minus<>{}, a, b);
150  };
151  } // namespace Hybrid
152 
153  } // namespace Experimental
154 
155 
156 #endif // DOXYGEN
157 
159 
166  template<typename Tree, typename Tag = StartTag>
167  struct TreeInfo
168  {
169 
170  private:
171  // Start the tree traversal
173 
174  public:
175 
177  static const std::size_t depth = NodeInfo::depth;
178 
180  static const std::size_t nodeCount = NodeInfo::nodeCount;
181 
183  static const std::size_t leafCount = NodeInfo::leafCount;
184 
185  };
186 
187 
188 #ifndef DOXYGEN
189 
190  // ********************************************************************************
191  // TreeInfo specializations for the different node types
192  // ********************************************************************************
193 
194 
195  // leaf node
196  template<typename Node>
197  struct TreeInfo<Node,LeafNodeTag>
198  {
199 
200  static const std::size_t depth = 1;
201 
202  static const std::size_t nodeCount = 1;
203 
204  static const std::size_t leafCount = 1;
205 
206  };
207 
208 
209  // power node - exploit the fact that all children are identical
210  template<typename Node>
211  struct TreeInfo<Node,PowerNodeTag>
212  {
213 
214  typedef TreeInfo<typename Node::ChildType,NodeTag<typename Node::ChildType>> ChildInfo;
215 
216  static const std::size_t depth = 1 + ChildInfo::depth;
217 
218  static const std::size_t nodeCount = 1 + StaticDegree<Node>::value * ChildInfo::nodeCount;
219 
220  static const std::size_t leafCount = StaticDegree<Node>::value * ChildInfo::leafCount;
221 
222  };
223 
224 
225  namespace {
226 
227  // TMP for iterating over the children of a composite node
228  // identical for both composite node implementations
229  template<typename Node, std::size_t k, std::size_t n>
230  struct generic_compositenode_children_info
231  {
232 
233  typedef generic_compositenode_children_info<Node,k+1,n> NextChild;
234 
235  // extract child info
236  typedef typename Node::template Child<k>::Type Child;
237  typedef NodeTag<Child> ChildTag;
238  typedef TreeInfo<Child,ChildTag> ChildInfo;
239 
240  // combine information of current child with info about following children
241  static const std::size_t maxDepth = ChildInfo::depth > NextChild::maxDepth ? ChildInfo::depth : NextChild::maxDepth;
242 
243  static const std::size_t nodeCount = ChildInfo::nodeCount + NextChild::nodeCount;
244 
245  static const std::size_t leafCount = ChildInfo::leafCount + NextChild::leafCount;
246 
247  };
248 
249  // End of recursion
250  template<typename Node, std::size_t n>
251  struct generic_compositenode_children_info<Node,n,n>
252  {
253  static const std::size_t maxDepth = 0;
254 
255  static const std::size_t nodeCount = 0;
256 
257  static const std::size_t leafCount = 0;
258  };
259 
260  } // anonymous namespace
261 
262 
263  // Struct for building information about composite node
264  template<typename Node>
265  struct GenericCompositeNodeInfo
266  {
267 
268  typedef generic_compositenode_children_info<Node,0,StaticDegree<Node>::value> Children;
269 
270  static const std::size_t depth = 1 + Children::maxDepth;
271 
272  static const std::size_t nodeCount = 1 + Children::nodeCount;
273 
274  static const std::size_t leafCount = Children::leafCount;
275 
276  };
277 
278 
279  // CompositeNode: delegate to GenericCompositeNodeInfo
280  template<typename Node>
281  struct TreeInfo<Node,CompositeNodeTag>
282  : public GenericCompositeNodeInfo<Node>
283  {};
284 
285 
286 #endif // DOXYGEN
287 
288 
289  using Dune::index_constant;
290  namespace Indices = Dune::Indices;
291 
293 
294  } // namespace TypeTree
295 } //namespace Dune
296 
297 #endif // DUNE_TYPETREE_UTILITY_HH
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: indices.hh:30
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:81
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:223
Namespace with predefined compile time indices for the range [0,19].
Definition: indices.hh:51
Dune namespace.
Definition: alignedallocator.hh:13
std::shared_ptr< T > stackobject_to_shared_ptr(T &t)
Create a shared_ptr for a stack-allocated object.
Definition: shared_ptr.hh:72
This file implements several utilities related to std::shared_ptr.
Tag designating a leaf node.
Definition: nodetags.hh:16
Struct for obtaining some basic structural information about a TypeTree.
Definition: utility.hh:168
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 27, 22:29, 2024)