Flow123d  JS_before_hm-883-gc471082
mixed.hh
Go to the documentation of this file.
1 /*
2  * mixed.hh
3  *
4  * Created on: Apr 8, 2019
5  * Author: jb
6  */
7 
8 #ifndef SRC_TOOLS_MIXED_HH_
9 #define SRC_TOOLS_MIXED_HH_
10 
11 #include <tuple>
12 #include <memory>
13 #include <iostream>
14 #include <type_traits>
15 
16 const int __spacedim = 3;
17 
18 using Dim = unsigned int;
19 
20 template<template<Dim ...> class T>
21 using _MixedBase0 = std::tuple<T<0>, T<1>, T<2>, T<3>>;
22 
23 template<template<Dim ...> class T>
24 using _MixedBase1 = std::tuple<T<1>, T<2>, T<3>>;
25 
26 
27 template< template<Dim ...> class T, int lower_dim=0>
28 class Mixed : public _MixedBase0<T> {
29 /**
30  * Template to simplify storing and passing tuples of instances of dimension parametrized templates.
31  * Currently instances for dim = 0,1,2,3 are created. We assume spacedim=3.
32  * Usage:
33  *
34  * fe_order = 10;
35  * auto gauss = Mixed<QGauss>(q_order); // template <int dim> class QGauss;
36  * auto mapping = MixedSpaceDim<Mapping>(); // template <int dim, int spacedim> class Mapping;
37  * ...
38  * fe_values = FEValues<dim>(mapping.get<dim>(), gauss.get<dim>(), ...)
39  *
40  * All parameters of the Mixed<T>(...) constructor are forwarder (by value) to the T(...) constructor for every dimension.
41  * Only forwarding by value is supported due to problems with MixedPtr.
42  * Can not resolve copy constructor correctly.
43  *
44  */
45 public:
46  template < template<Dim...> class TT>
47  Mixed(const Mixed<TT> &other)
48  : _MixedBase0<T>(
49  T<0>( (other.template get<0>()) ),
50  T<1>( (other.template get<1>()) ),
51  T<2>( (other.template get<2>()) ),
52  T<3>( (other.template get<3>()) ) )
53  { static_assert(std::is_convertible<TT<0>, T<0>>::value, "Non-convertible types!"); }
54 
55  Mixed(const T<0> &p0,const T<1> &p1,const T<2> &p2,const T<3> &p3)
56  : _MixedBase0<T>(p0, p1, p2, p3)
57  {}
58 
59  Mixed(T<0> &&p0, T<1> &&p1, T<2> &&p2, T<3> &&p3)
60  : _MixedBase0<T>(p0, p1, p2, p3)
61  {}
62 
63 
64  template<typename... Args>
65  Mixed(Args... args)
66  : _MixedBase0<T>(
67  T<0>(std::forward<Args>(args)...),
68  T<1>(std::forward<Args>(args)...),
69  T<2>(std::forward<Args>(args)...),
70  T<3>(std::forward<Args>(args)...))
71  {}
72 
73  template<Dim i_dim>
74  T<i_dim> &get() {
75  return std::get<i_dim>(*this);
76  }
77 
78  template<Dim i_dim>
79  const T<i_dim> &get() const {
80  return std::get<i_dim>(*this);
81  }
82 
83  template< template<Dim...> class TParent, typename std::enable_if<std::is_convertible<TParent<0>, T<0>>::value, T<0> >::type >
84  operator Mixed<TParent> () const {
85  //ASSERT(std::is_base_of<TParent, T>::value);
86  return Mixed<TParent>(
87  TParent<0>(this->get<0>()),
88  TParent<1>(this->get<1>()),
89  TParent<2>(this->get<2>()),
90  TParent<3>(this->get<3>()));
91  }
92 
93  // Possible collective methods must be implemented in MixedPtr childs.
94 };
95 
96 
97 
98 
99 template< template<Dim ...> class T>
100 class Mixed<T, 1> : public _MixedBase1<T> {
101 /**
102  * Template to simplify storing and passing tuples of instances of dimension parametrized templates.
103  * Currently instances for dim = 0,1,2,3 are created. We assume spacedim=3.
104  * Usage:
105  *
106  * fe_order = 10;
107  * auto gauss = Mixed<QGauss>(q_order); // template <int dim> class QGauss;
108  * auto mapping = MixedSpaceDim<Mapping>(); // template <int dim, int spacedim> class Mapping;
109  * ...
110  * fe_values = FEValues<dim>(mapping.get<dim>(), gauss.get<dim>(), ...)
111  *
112  * All parameters of the Mixed<T>(...) constructor are forwarder (by value) to the T(...) constructor for every dimension.
113  * Only forwarding by value is supported due to problems with MixedPtr.
114  * Can not resolve copy constructor correctly.
115  *
116  */
117 public:
118  template < template<Dim...> class TT>
119  Mixed(const Mixed<TT, 1> &other)
120  : _MixedBase1<T>(
121  T<1>(other.template get<1>() ),
122  T<2>(other.template get<2>() ),
123  T<3>(other.template get<3>() ) )
124  { static_assert(std::is_convertible<TT<1>, T<1>>::value, "Non-convertible types!"); }
125 
126  Mixed(const T<1> &p1,const T<2> &p2,const T<3> &p3)
127  : _MixedBase1<T>( p1, p2, p3)
128  {}
129 
130  Mixed( T<1> &&p1, T<2> &&p2, T<3> &&p3)
131  : _MixedBase1<T>(p1, p2, p3)
132  {}
133 
134 
135  template<typename... Args>
136  Mixed(Args... args)
137  : _MixedBase1<T>(
138  T<1>(std::forward<Args>(args)...),
139  T<2>(std::forward<Args>(args)...),
140  T<3>(std::forward<Args>(args)...))
141  {}
142 
143  template<Dim i_dim>
144  T<i_dim> &get() {
145  return std::get<i_dim-1>(*this);
146  }
147 
148  template<Dim i_dim>
149  const T<i_dim> &get() const {
150  return std::get<i_dim-1>(*this);
151  }
152 
153  template< template<Dim...> class TParent, typename std::enable_if<std::is_convertible<TParent<1>, T<1>>::value, T<1> >::type >
154  operator Mixed<TParent> () const {
155  //ASSERT(std::is_base_of<TParent, T>::value);
156  return Mixed<TParent>(
157  TParent<1>(this->get<1>()),
158  TParent<2>(this->get<2>()),
159  TParent<3>(this->get<3>()));
160  }
161 
162  // Possible collective methods must be implemented in MixedPtr childs.
163 };
164 
165 
166 
167 
168 //template< template<Dim, Dim> class T>
169 //struct FixSpaceDim {
170 ///**
171 // * Partial template resolution (parameter binding).
172 // * See implementation of MixedSpaceDim for the usage. Can be used for
173 // * possible child classes of the Mixed template.
174 // */
175 //public:
176 // template<Dim dim>
177 // using type = T<dim, __spacedim>;
178 //};
179 //
180 //
181 //template< template<Dim, Dim> class T>
182 //using MixedSpaceDim = Mixed< FixSpaceDim<T>::template type >;
183 
184 
185 
186 
187 
188 
189 template<template<Dim...> class T>
190 using _MixedPtrBase0 = std::tuple<
191  std::shared_ptr<T<0>>, std::shared_ptr<T<1>>,
192  std::shared_ptr<T<2>>, std::shared_ptr<T<3>>>;
193 
194 template<template<Dim...> class T>
195 using _MixedPtrBase1 = std::tuple< std::shared_ptr<T<1>>,
196  std::shared_ptr<T<2>>, std::shared_ptr<T<3>>>;
197 
198 
199 template< template<Dim...> class T, int lower_dim=0>
200 class MixedPtr : public _MixedPtrBase0<T> {
201 /**
202  * Template to simplify storing and passing tuples of shatred_ptr to instances of dimension parametrized templates.
203  * Currently instances for dim = 0,1,2,3 are created. We assume spacedim=3.
204  * Usage:
205  *
206  * fe_order = 10;
207  * auto gauss = MixedPtr<QGauss>(q_order); // template <int dim> class QGauss;
208  * auto mapping = MixedSpaceDimPtr<Mapping>(); // template <int dim, int spacedim> class Mapping;
209  * ...
210  * fe_values = FEValues<dim>(*mapping.get<dim>(), *gauss.get<dim>(), ...)
211  *
212  * All parameters of the Mixed<T>(...) constructor are forwarder (by value) to the T(...) constructor for every dimension.
213  * Only forwarding by value is supported due to problems with MixedPtr.
214  * We are unable to give precedence to the copy constructor over the prefect forwarding constructor MixedPtr(Args&& ...).
215  */
216 public:
217  template <Dim dim>
218  using TPtr = std::shared_ptr<T<dim>>;
219 
220  template < template<Dim...> class TT>
221  MixedPtr(const MixedPtr<TT> &other)
222  : _MixedPtrBase0<T>(
223  other.template get<0>(),
224  other.template get<1>(),
225  other.template get<2>(),
226  other.template get<3>())
227  {}
228 
230  : _MixedPtrBase0<T>(p0, p1, p2, p3)
231  {}
232 
233  template<typename... Args>
234  MixedPtr(Args... args)
235  : _MixedPtrBase0<T>(
236  std::make_shared<T<0>>(std::forward<Args>(args)...),
237  std::make_shared<T<1>>(std::forward<Args>(args)...),
238  std::make_shared<T<2>>(std::forward<Args>(args)...),
239  std::make_shared<T<3>>(std::forward<Args>(args)...))
240  {}
241 
242 
243  template<Dim i_dim>
244  std::shared_ptr<T<i_dim>> get() {
245  return std::get<i_dim>(*this);
246  }
247 
248  template<int i_dim>
249  const std::shared_ptr<T<i_dim>> get() const {
250  return std::get<i_dim>(*this);
251  }
252 
254  return Mixed<T>(
255  *(this->get<0>()),
256  *(this->get<1>()),
257  *(this->get<2>()),
258  *(this->get<3>()));
259  }
260 
261  // Possible collective methods must be implemented in MixedPtr childs.
262 
263 };
264 
265 
266 template< template<Dim...> class T>
267 class MixedPtr<T, 1> : public _MixedPtrBase1<T> {
268 /**
269  * Template to simplify storing and passing tuples of shatred_ptr to instances of dimension parametrized templates.
270  * Currently instances for dim = 0,1,2,3 are created. We assume spacedim=3.
271  * Usage:
272  *
273  * fe_order = 10;
274  * auto gauss = MixedPtr<QGauss>(q_order); // template <int dim> class QGauss;
275  * auto mapping = MixedSpaceDimPtr<Mapping>(); // template <int dim, int spacedim> class Mapping;
276  * ...
277  * fe_values = FEValues<dim>(*mapping.get<dim>(), *gauss.get<dim>(), ...)
278  *
279  * All parameters of the Mixed<T>(...) constructor are forwarder (by value) to the T(...) constructor for every dimension.
280  * Only forwarding by value is supported due to problems with MixedPtr.
281  * We are unable to give precedence to the copy constructor over the prefect forwarding constructor MixedPtr(Args&& ...).
282  */
283 public:
284  template <Dim dim>
285  using TPtr = std::shared_ptr<T<dim>>;
286 
287  template < template<Dim...> class TT>
288  MixedPtr(const MixedPtr<TT, 1> &other)
289  : _MixedPtrBase1<T>(
290  other.template get<1>(),
291  other.template get<2>(),
292  other.template get<3>())
293  {}
294 
296  : _MixedPtrBase1<T>(p1, p2, p3)
297  {}
298 
299  template<typename... Args>
300  MixedPtr(Args... args)
301  : _MixedPtrBase1<T>(
302  std::make_shared<T<1>>(std::forward<Args>(args)...),
303  std::make_shared<T<2>>(std::forward<Args>(args)...),
304  std::make_shared<T<3>>(std::forward<Args>(args)...))
305  {}
306 
307 
308  template<Dim i_dim>
309  std::shared_ptr<T<i_dim>> get() {
310  return std::get<i_dim-1>(*this);
311  }
312 
313  template<int i_dim>
314  const std::shared_ptr<T<i_dim>> get() const {
315  return std::get<i_dim-1>(*this);
316  }
317 
319  return Mixed<T, 1>(
320  *(this->get<1>()),
321  *(this->get<2>()),
322  *(this->get<3>()));
323  }
324 
325  // Possible collective methods must be implemented in MixedPtr childs.
326 
327 };
328 
329 //template< template<Dim, Dim> class T>
330 //using MixedSpaceDimPtr = MixedPtr< FixSpaceDim<T>::template type >;
331 
332 
333 
334 //template< template <int> class Fn, class ...Args>
335 //auto dim_switch(Dim dim, Args&&... args) -> decltype( builder.makeObject() )
336 //{
337 // switch (dim)
338 // {
339 // case 0:
340 // return Fn<0>(std::forward<Args>(args)...);
341 // case 0:
342 // return Fn<1>(std::forward<Args>(args)...);
343 // case 0:
344 // return Fn<2>(std::forward<Args>(args)...);
345 // case 0:
346 // return Fn<3>(std::forward<Args>(args)...);
347 // }
348 //
349 //}
350 
351 
352 #endif /* SRC_TOOLS_MIXED_HH_ */
Mixed(Args...args)
Definition: mixed.hh:65
unsigned int Dim
Definition: mixed.hh:18
Mixed(const T< 0 > &p0, const T< 1 > &p1, const T< 2 > &p2, const T< 3 > &p3)
Definition: mixed.hh:55
Mixed(const Mixed< TT, 1 > &other)
Definition: mixed.hh:119
std::tuple< T< 1 >, T< 2 >, T< 3 >> _MixedBase1
Definition: mixed.hh:24
std::tuple< T< 0 >, T< 1 >, T< 2 >, T< 3 >> _MixedBase0
Definition: mixed.hh:21
std::tuple< std::shared_ptr< T< 0 >>, std::shared_ptr< T< 1 >>, std::shared_ptr< T< 2 >>, std::shared_ptr< T< 3 >>> _MixedPtrBase0
Definition: mixed.hh:192
static constexpr bool value
Definition: json.hpp:87
UnitSI operator*(const UnitSI &a, const UnitSI &b)
Product of two units.
Definition: unit_si.cc:235
T< i_dim > & get()
Definition: mixed.hh:74
const int __spacedim
Definition: mixed.hh:16
MixedPtr(TPtr< 0 > p0, TPtr< 1 > p1, TPtr< 2 > p2, TPtr< 3 > p3)
Definition: mixed.hh:229
MixedPtr(Args...args)
Definition: mixed.hh:234
Mixed(const T< 1 > &p1, const T< 2 > &p2, const T< 3 > &p3)
Definition: mixed.hh:126
Definition: mixed.hh:28
Mixed(T< 1 > &&p1, T< 2 > &&p2, T< 3 > &&p3)
Definition: mixed.hh:130
std::tuple< std::shared_ptr< T< 1 >>, std::shared_ptr< T< 2 >>, std::shared_ptr< T< 3 >>> _MixedPtrBase1
Definition: mixed.hh:196
std::shared_ptr< T< dim >> TPtr
Definition: mixed.hh:285
MixedPtr(Args...args)
Definition: mixed.hh:300
MixedPtr(const MixedPtr< TT, 1 > &other)
Definition: mixed.hh:288
std::shared_ptr< DimAssembly< dim >> TPtr
Definition: mixed.hh:218
Mixed(const Mixed< TT > &other)
Definition: mixed.hh:47
MixedPtr(TPtr< 1 > p1, TPtr< 2 > p2, TPtr< 3 > p3)
Definition: mixed.hh:295
Mixed(Args...args)
Definition: mixed.hh:136
Mixed(T< 0 > &&p0, T< 1 > &&p1, T< 2 > &&p2, T< 3 > &&p3)
Definition: mixed.hh:59
MixedPtr(const MixedPtr< TT > &other)
Definition: mixed.hh:221