dune-typetree  2.4-dev
powernode.hh
Go to the documentation of this file.
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_POWERNODE_HH
5 #define DUNE_TYPETREE_POWERNODE_HH
6 
7 #include <cassert>
8 #include <array>
9 
10 #include <dune/common/typetraits.hh>
11 
13 #include <dune/typetree/utility.hh>
14 
15 namespace Dune {
16  namespace TypeTree {
17 
23 #ifndef DOXYGEN
24 
25  namespace {
26 
27  // prototype and end of recursion
28  template<typename T, typename It, typename... Args>
29  void assign_reference_pack_to_shared_ptr_array_unpack(It it, Args&&... args) {}
30 
31  template<typename T, typename It, typename Arg, typename... Args>
32  void assign_reference_pack_to_shared_ptr_array_unpack(It it, Arg&& arg, Args&&... args)
33  {
34  static_assert(is_same<T,typename remove_const<typename remove_reference<Arg>::type>::type>::value,"type mismatch during array conversion");
35  *it = convert_arg(std::forward<Arg>(arg));
36  assign_reference_pack_to_shared_ptr_array_unpack<T>(++it,std::forward<Args>(args)...);
37  }
38 
39  template<typename T, std::size_t n, typename... Args>
40  void assign_reference_pack_to_shared_ptr_array(std::array<shared_ptr<T>,n>& res, Args&&... args)
41  {
42  static_assert(sizeof...(Args) == n, "invalid number of arguments");
43  return assign_reference_pack_to_shared_ptr_array_unpack<T>(res.begin(),std::forward<Args>(args)...);
44  }
45 
46 
47  // prototype and end of recursion
48  template<typename T, typename It, typename... Args>
49  void assign_shared_ptr_pack_to_shared_ptr_array_unpack(It it, Args&&... args) {}
50 
51  template<typename T, typename It, typename Arg, typename... Args>
52  void assign_shared_ptr_pack_to_shared_ptr_array_unpack(It it, Arg&& arg, Args&&... args)
53  {
54  static_assert(is_same<T,typename std::remove_reference<Arg>::type::element_type>::value,"type mismatch during array conversion");
55  *it = arg;
56  assign_shared_ptr_pack_to_shared_ptr_array_unpack<T>(++it,args...);
57  }
58 
59  template<typename T, std::size_t n, typename... Args>
60  void assign_shared_ptr_pack_to_shared_ptr_array(std::array<shared_ptr<T>,n>& res, Args&&... args)
61  {
62  static_assert(sizeof...(Args) == n, "invalid number of arguments");
63  return assign_shared_ptr_pack_to_shared_ptr_array_unpack<T>(res.begin(),args...);
64  }
65 
66  } // anonymous namespace
67 
68 #endif
69 
70 #ifndef DOXYGEN
71 
73  template<typename PowerNode, typename T, std::size_t k>
74  struct AssertPowerNodeChildCount
75  : public enable_if<is_same<
76  typename PowerNode::ChildType,
77  T>::value &&
78  PowerNode::CHILDREN == k,
79  T>
80  {};
81 
82 #endif
83 
89  template<typename T, std::size_t k>
90  class PowerNode
91  {
92 
93  public:
94 
96  static const bool isLeaf = false;
97 
99  static const bool isPower = true;
100 
102  static const bool isComposite = false;
103 
105  static const std::size_t CHILDREN = k;
106 
109 
111  typedef T ChildType;
112 
114  typedef shared_ptr<T> ChildStorageType;
115 
117  typedef shared_ptr<const T> ChildConstStorageType;
118 
120  typedef std::array<ChildStorageType,k> NodeStorage;
121 
122 
124  template<std::size_t i>
125  struct Child
126  {
127 
128  static_assert((i < CHILDREN), "child index out of range");
129 
131  typedef T Type;
132 
134  typedef T type;
135 
137  typedef ChildStorageType Storage;
138 
140  typedef ChildConstStorageType ConstStorage;
141  };
142 
145 
147 
150  template<std::size_t i>
151  T& child ()
152  {
153  static_assert((i < CHILDREN), "child index out of range");
154  return *_children[i];
155  }
156 
158 
161  template<std::size_t i>
162  const T& child () const
163  {
164  static_assert((i < CHILDREN), "child index out of range");
165  return *_children[i];
166  }
167 
169 
172  template<std::size_t i>
173  ChildStorageType childStorage()
174  {
175  static_assert((i < CHILDREN), "child index out of range");
176  return _children[i];
177  }
178 
180 
186  template<std::size_t i>
187  ChildConstStorageType childStorage() const
188  {
189  static_assert((i < CHILDREN), "child index out of range");
190  return _children[i];
191  }
192 
194  template<std::size_t i>
195  void setChild (T& t)
196  {
197  static_assert((i < CHILDREN), "child index out of range");
198  _children[i] = stackobject_to_shared_ptr(t);
199  }
200 
202  template<std::size_t i>
203  void setChild (ChildStorageType st)
204  {
205  static_assert((i < CHILDREN), "child index out of range");
206  _children[i] = st;
207  }
208 
210 
211 
214 
216 
219  T& child (std::size_t i)
220  {
221  assert(i < CHILDREN && "child index out of range");
222  return *_children[i];
223  }
224 
226 
229  const T& child (std::size_t i) const
230  {
231  assert(i < CHILDREN && "child index out of range");
232  return *_children[i];
233  }
234 
236 
239  ChildStorageType childStorage(std::size_t i)
240  {
241  assert(i < CHILDREN && "child index out of range");
242  return _children[i];
243  }
244 
246 
252  ChildConstStorageType childStorage (std::size_t i) const
253  {
254  assert(i < CHILDREN && "child index out of range");
255  return (_children[i]);
256  }
257 
259  void setChild (std::size_t i, T& t)
260  {
261  assert(i < CHILDREN && "child index out of range");
262  _children[i] = stackobject_to_shared_ptr(t);
263  }
264 
266  void setChild (std::size_t i, ChildStorageType st)
267  {
268  assert(i < CHILDREN && "child index out of range");
269  _children[i] = st;
270  }
271 
272  const NodeStorage& nodeStorage() const
273  {
274  return _children;
275  }
276 
278 
281 
282  protected:
283 
285 
294  {}
295 
297  explicit PowerNode(const NodeStorage& children)
298  : _children(children)
299  {}
300 
302  explicit PowerNode (T& t, bool distinct_objects = true)
303  {
304  if (distinct_objects)
305  {
306  for (typename NodeStorage::iterator it = _children.begin(); it != _children.end(); ++it)
307  *it = make_shared<T>(t);
308  }
309  else
310  {
311  shared_ptr<T> sp = stackobject_to_shared_ptr(t);
312  std::fill(_children.begin(),_children.end(),sp);
313  }
314  }
315 
316 #ifdef DOXYGEN
317 
319 
329  PowerNode(T& t1, T& t2, ...)
330  {}
331 
332 #else
333 
334  // this weird signature avoids shadowing other 1-argument constructors
335  template<typename C0, typename C1, typename... Children>
336  PowerNode (C0&& c0, C1&& c1, Children&&... children)
337  {
338  assign_reference_pack_to_shared_ptr_array(_children,std::forward<C0>(c0),std::forward<C1>(c1),std::forward<Children>(children)...);
339  }
340 
341  // this weird signature avoids shadowing other 1-argument constructors
342  template<typename C0, typename C1, typename... Children>
343  PowerNode (shared_ptr<C0> c0, shared_ptr<C1> c1, shared_ptr<Children>... children)
344  {
345  assign_shared_ptr_pack_to_shared_ptr_array(_children,c0,c1,children...);
346  }
347 
348 #endif // DOXYGEN
349 
351 
352  private:
353  NodeStorage _children;
354  };
355 
357 
358  } // namespace TypeTree
359 } //namespace Dune
360 
361 #endif // DUNE_TYPETREE_POWERNODE_HH
PowerNode(const NodeStorage &children)
Initialize the PowerNode with a copy of the passed-in storage type.
Definition: powernode.hh:297
T & child()
Returns the i-th child.
Definition: powernode.hh:151
static const std::size_t CHILDREN
The number of children.
Definition: powernode.hh:105
Access to the type and storage type of the i-th child.
Definition: powernode.hh:125
ChildStorageType childStorage(std::size_t i)
Returns the storage of the i-th child.
Definition: powernode.hh:239
Definition: accumulate_static.hh:12
T & child(std::size_t i)
Returns the i-th child.
Definition: powernode.hh:219
const T & child(std::size_t i) const
Returns the i-th child (const version).
Definition: powernode.hh:229
const NodeStorage & nodeStorage() const
Definition: powernode.hh:272
PowerNode(T &t, bool distinct_objects=true)
Initialize all children with copies of a storage object constructed from the parameter t...
Definition: powernode.hh:302
Collect k instances of type T within a dune-typetree.
Definition: powernode.hh:90
void setChild(std::size_t i, T &t)
Sets the i-th child to the passed-in value.
Definition: powernode.hh:259
ChildConstStorageType ConstStorage
The const storage type of the child.
Definition: powernode.hh:140
void setChild(ChildStorageType st)
Sets the stored value representing the i-th child to the passed-in value.
Definition: powernode.hh:203
static const bool isComposite
Mark this class as a non composite in the dune-typetree.
Definition: powernode.hh:102
ChildStorageType Storage
The storage type of the child.
Definition: powernode.hh:137
const T & child() const
Returns the i-th child (const version).
Definition: powernode.hh:162
T ChildType
The type of each child.
Definition: powernode.hh:111
PowerNodeTag NodeTag
The type tag that describes a PowerNode.
Definition: powernode.hh:108
ChildConstStorageType childStorage(std::size_t i) const
Returns the storage of the i-th child (const version).
Definition: powernode.hh:252
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition: powernode.hh:96
PowerNode(T &t1, T &t2,...)
Initialize all children with the passed-in objects.
Definition: powernode.hh:329
shared_ptr< const T > ChildConstStorageType
The const version of the storage type of each child.
Definition: powernode.hh:117
static const bool isPower
Mark this class as a power in the dune-typetree.
Definition: powernode.hh:99
ChildStorageType childStorage()
Returns the storage of the i-th child.
Definition: powernode.hh:173
std::array< ChildStorageType, k > NodeStorage
The type used for storing the children.
Definition: powernode.hh:120
T type
The type of the child.
Definition: powernode.hh:134
T Type
The type of the child.
Definition: powernode.hh:128
void setChild(T &t)
Sets the i-th child to the passed-in value.
Definition: powernode.hh:195
shared_ptr< T > ChildStorageType
The storage type of each child.
Definition: powernode.hh:114
ChildConstStorageType childStorage() const
Returns the storage of the i-th child (const version).
Definition: powernode.hh:187
PowerNode()
Default constructor.
Definition: powernode.hh:293
void setChild(std::size_t i, ChildStorageType st)
Sets the stored value representing the i-th child to the passed-in value.
Definition: powernode.hh:266
Tag designating a power node.
Definition: nodetags.hh:19