DUNE-ACFEM (unstable)

densevectorview.hh
1#ifndef __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_DENSEVECTORVIEW_HH__
2#define __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_DENSEVECTORVIEW_HH__
3
4#include <dune/common/densevector.hh>
5//#include "../../../expressions/operationtraits.hh"
6#include "../../../common/literals.hh"
7#include "../../tensorbase.hh"
8#include "fieldvectortraits.hh"
9
10namespace Dune {
11
12 namespace ACFem {
13
14 namespace Tensor {
15
16 // forward
17 template<class Tensor>
18 class TensorResult;
19
20 template<class T, class Storage = Expressions::Storage<OperationTraits<IdentityOperation>, T>,
21 std::size_t N = std::decay_t<T>::rank,
22 std::size_t Rank = std::decay_t<T>::rank,
23 class SFINAE = void>
24 class DenseVectorView;
25
26 template<class T, class Storage, std::size_t N, std::size_t Rank>
27 class DenseVectorViewElement;
28
30 template<class T, class Storage, std::size_t N, std::size_t Rank>
32 : public DenseVectorView<T, Storage, N, Rank>
33 , public Dune::DenseVector<DenseVectorViewElement<T, Storage, N, Rank> >
34 {
36 using DenseVectorType = Dune::DenseVector<DenseVectorViewElement<T, Storage, N, Rank> >;
37 using ValueBaseType = DenseVectorView<T, Storage, N-1, Rank>;
39 public:
40 using const_iterator = void;
41 using BaseType::lookAt;
42 using ValueType = DenseVectorViewElement<T, Storage, N-1, Rank>;
43 using IndexType = typename BaseType::IndexType;
44
45 static constexpr IndexType rank_ = Rank;
46 static constexpr IndexType fakedRank_ = N;
47 static constexpr IndexType stage_ = std::decay_t<T>::rank - N;
48
49 template<class... Args>
50 DenseVectorViewElement(Args&&...) = delete;
51
52 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value, int> = 0>
53 DenseVectorViewElement(const C&) = delete;
54
55 static constexpr std::size_t size()
56 {
58 }
59
60 const ValueType& operator[](IndexType i) const
61 {
62 lookAt()[stage_] = i;
63 return static_cast<const ValueType&>(static_cast<const ValueBaseType&>(*this));
64 }
65 };
66
68 template<class T, class Storage, std::size_t Rank>
69 class DenseVectorViewElement<T, Storage, 1, Rank>
70 : public DenseVectorView<T, Storage, 1, Rank>
71 , public Dune::DenseVector<DenseVectorViewElement<T, Storage, 1, Rank> >
72 {
75 using DenseVectorType = Dune::DenseVector<DenseVectorViewElement<T, Storage, 1, Rank> >;
76 using BaseType::lookAt;
77 using BaseType::value_;
78 public:
79 using const_iterator = void;
80 using BaseType::operand;
81 using typename BaseType::ValueType;
82 using IndexType = typename BaseType::IndexType;
83
84 static constexpr IndexType rank_ = Rank;
85 static constexpr IndexType fakedRank_ = 1;
86 static constexpr IndexType stage_ = std::decay_t<T>::rank - fakedRank_;
87
88 template<class... Args>
89 DenseVectorViewElement(Args&&...) = delete;
90
91 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value, int> = 0>
92 DenseVectorViewElement(const C&) = delete;
93
94 static constexpr std::size_t size()
95 {
96 return TensorTraits<T>::template dim<stage_>();
97 }
98
99 const ValueType& operator[](IndexType i) const
100 {
101 lookAt()[stage_] = i;
102 return value_ = tensorValue(operand(0_c), lookAt());
103 }
104
105 };
106
110 template<class T, class Storage, std::size_t N, std::size_t Rank, class SFINAE>
112 : public DenseVectorView<T, Storage, N-1, Rank>
113 {
114 static_assert(N > 1, "Recursion bug.");
115 static_assert(TensorTraits<T>::rank > 0, "This can only work if rank > 0.");
116
118 using BaseType = DenseVectorView<T, Storage, N-1, Rank>;
119 public:
120 using ValueType = DenseVectorViewElement<T, Storage, N-1, Rank>;
121 using IndexType = unsigned;
122
123 static constexpr IndexType rank_ = Rank;
124 static constexpr IndexType fakedRank_ = N;
125 static constexpr IndexType stage_ = TensorTraits<T>::rank - N;
126
127 template<class StorageArg,
128 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
130 ), int> = 0>
131 explicit DenseVectorView(StorageArg&& storage)
132 : BaseType(std::forward<StorageArg>(storage))
133 {}
134
135 DenseVectorView(const DenseVectorView& other)
136 : BaseType(other)
137 {}
138
140 : BaseType(std::move(other))
141 {}
142
143 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value, int> = 0>
144 explicit DenseVectorView(const C& other)
145 : DenseVectorView(static_cast<const ThisType&>(other))
146 {}
147
148 static constexpr std::size_t size()
149 {
150 return TensorTraits<T>::template dim<stage_>();
151 }
152
153 auto& lookAt() const
154 {
155 return BaseType::lookAt();
156 }
157 };
158
163 template<class T, class Storage, std::size_t Rank>
164 class DenseVectorView<T, Storage, 1, Rank, std::enable_if_t<Rank != 1> >
165 : public Storage
166 {
167 static_assert(std::decay_t<T>::rank > 0, "This can only work if rank > 0.");
168
169 using ThisType = DenseVectorView;
170 public:
171 using ValueType = typename std::decay_t<T>::FieldType;
172 using IndexType = unsigned;
173 using IndicesType = std::array<IndexType, std::decay_t<T>::rank>;
174
175 static constexpr IndexType rank_ = Rank;
176 static constexpr IndexType fakedRank_ = 1;
177 static constexpr IndexType stage_ = std::decay_t<T>::rank-fakedRank_;
178
179 template<class StorageArg,
180 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
182 ), int> = 0>
183 explicit DenseVectorView(StorageArg&& storage)
184 : Storage(std::forward<StorageArg>(storage))
185 {}
186
187 DenseVectorView(const DenseVectorView& other)
188 : Storage(other), value_(other.value_), indices_(other.indices_)
189 {}
190
192 : Storage(std::move(other))
193 , value_(std::move(other.value_))
194 , indices_(std::move(other.indices_))
195 {}
196
197 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value, int> = 0>
198 explicit DenseVectorView(const C& other)
199 : DenseVectorView(static_cast<const ThisType&>(other))
200 {}
201
202 static constexpr std::size_t size()
203 {
204 return TensorTraits<T>::template dim<stage_>();
205 }
206
207 auto& lookAt() const
208 {
209 return indices_;
210 }
211
212 protected:
213 mutable ValueType value_;
214 mutable IndicesType indices_;
215 };
216
221 template<class T, class Storage, std::size_t N>
222 class DenseVectorView<T, Storage, N, N, std::enable_if_t<N >= 2> >
223 : public DenseVectorView<T, Storage, N-1, N>
224 , public Dune::DenseVector<DenseVectorView<T, Storage, N, N> >
225 {
226 static_assert(TensorTraits<T>::rank > 0, "This can only work if rank > 0.");
227
229 using BaseType = DenseVectorView<T, Storage, N-1, N>;
230 using ValueType = DenseVectorViewElement<T, Storage, N-1, N>;
231 using DenseVectorType = Dune::DenseVector<DenseVectorView<T, Storage, N, N> >;
232 public:
233 using const_iterator = void;
234
235 using IndexType = typename BaseType::IndexType;
236
237 static constexpr IndexType rank_ = N;
238 static constexpr IndexType fakedRank_ = N;
239 static constexpr IndexType stage_ = std::decay_t<T>::rank - fakedRank_;
240
241 template<class StorageArg,
242 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
244 ), int> = 0>
245 explicit DenseVectorView(StorageArg&& storage)
246 : BaseType(std::forward<StorageArg>(storage))
247 {}
248
249 DenseVectorView(const DenseVectorView& other)
250 : BaseType(other)
251 {}
252
254 : BaseType(std::move(other))
255 {}
256
257 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value, int> = 0>
258 explicit DenseVectorView(const C& other)
259 : DenseVectorView(static_cast<const ThisType&>(other))
260 {}
261
262 static constexpr std::size_t size()
263 {
264 return TensorTraits<T>::template dim<stage_>();
265 }
266
267 const ValueType& operator[](IndexType i) const
268 {
269 lookAt()[stage_] = i;
270 return static_cast<const ValueType&>(static_cast<const BaseType&>(*this));
271 }
272
273 auto& lookAt() const
274 {
275 return BaseType::lookAt();
276 }
277 };
278
283 template<class T, class Storage>
284 class DenseVectorView<T, Storage, 1, 1>
285 : public Storage
286 , public Dune::DenseVector<DenseVectorView<T, Storage, 1, 1> >
287 {
288 static_assert(TensorTraits<T>::rank > 0, "This can only work if rank > 0.");
289
290 using ThisType = DenseVectorView;
291 using ValueType = typename TensorTraits<T>::FieldType;
292 using DenseVectorType = Dune::DenseVector<DenseVectorView<T, Storage, 1, 1> >;
293 public:
294 using const_iterator = void;
295 using Storage::operand;
296 using IndexType = unsigned;
297 using IndicesType = std::array<IndexType, std::decay_t<T>::rank>;
298
299 static constexpr IndexType rank_ = 1;
300 static constexpr IndexType fakedRank_ = 1;
301 static constexpr IndexType stage_ = std::decay_t<T>::rank-fakedRank_;
302
303 template<class StorageArg,
304 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
306 ), int> = 0>
307 explicit DenseVectorView(StorageArg&& storage)
308 : Storage(std::forward<StorageArg>(storage))
309 {}
310
311 DenseVectorView(const DenseVectorView& other)
312 : Storage(other), value_(other.value_), indices_(other.indices_)
313 {}
314
316 : Storage(std::move(other))
317 , value_(std::move(other.value_))
318 , indices_(std::move(other.indices_))
319 {}
320
321 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value, int> = 0>
322 explicit DenseVectorView(const C& other)
323 : DenseVectorView(static_cast<const ThisType&>(other))
324 {}
325
326 static constexpr std::size_t size()
327 {
328 return TensorTraits<T>::template dim<stage_>();
329 }
330
331 const ValueType& operator[](IndexType i) const
332 {
333 lookAt()[stage_] = i;
334 return value_ = tensorValue(operand(0_c), lookAt());
335 }
336
337 auto& lookAt() const
338 {
339 return indices_;
340 }
341
342 protected:
343 mutable ValueType value_;
344 mutable IndicesType indices_;
345 };
346
348 template<class T, class Storage>
349 class DenseVectorView<T, Storage, 0, 0>
350 : public Storage
351 {
352 static_assert(std::decay_t<T>::rank == 0, "This can only work if rank == 0.");
353
354 using ThisType = DenseVectorView;
355 using ValueType = typename std::decay_t<T>::FieldType;
356 public:
357 using Storage::operand;
358 using IndexType = unsigned;
359
360 static constexpr IndexType rank_ = 0;
361 static constexpr IndexType fakedRank_ = 0;
362
363 template<class StorageArg,
364 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
366 ), int> = 0>
367 explicit DenseVectorView(StorageArg&& storage)
368 : Storage(std::forward<StorageArg>(storage))
369 {}
370
371 DenseVectorView(const DenseVectorView& other)
372 : Storage(other)
373 {}
374
376 : Storage(std::move(other))
377 {}
378
379 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value, int> = 0>
380 explicit DenseVectorView(const C& other)
381 : DenseVectorView(static_cast<const ThisType&>(other))
382 {}
383
384 static constexpr std::size_t size()
385 {
386 return 0;
387 }
388
391 {
392 return operand(0_c)();
393 }
394 };
395
400 {
401 template<class DenseMatrix, class T>
402 static void apply(DenseMatrix& denseMatrix, const TensorResult<T> &rhs)
403 {
404 static_assert(TensorTraits<T>::rank == 2, "T should be a Tensor of rank 2.");
405
406 forLoop<TensorTraits<T>::template dim<0>()>([&](auto i) {
407 using IType = decltype(i);
408 forLoop<TensorTraits<T>::template dim<1>()>([&](auto j) {
409 using JType = decltype(j);
410 using Indices = Seq<IType::value, JType::value>;
411 denseMatrix[IType::value][JType::value] = rhs(Indices{});
412 });
413 });
414 }
415
416 template<class DenseMatrix, class T, class Storage, std::size_t Rank>
417 static void apply(DenseMatrix& denseMatrix,
419 {
420 using Traits = TensorTraits<T>;
421 constexpr std::size_t rank = Traits::rank;
422 forLoop<Traits::template dim<rank-2>()>([&](auto i) {
423 using IType = decltype(i);
424 forLoop<Traits::template dim<rank-1>()>([&](auto j) {
425 using JType = decltype(j);
426 denseMatrix[IType::value][JType::value] = rhs[IType::value][JType::value];
427 });
428 });
429 }
430
431 template<class DenseMatrix, class T, class Storage, std::size_t Rank>
432 static void apply(DenseMatrix& denseMatrix,
434 {
435 apply(denseMatrix, static_cast<const DenseVectorViewElement<T, Storage, 2, Rank>&>(rhs));
436 }
437 };
438
439 } // NS Tensor
440
441 } // NS ACFem
442
451 template<class Field, int Size, class T>
452 struct PromotionTraits<FieldVector<Field, Size>, T>
453 {};
454
455 template<class Field, int Size, class T>
456 struct PromotionTraits<T, FieldVector<Field, Size> >
457 {};
458
459 template<class Field, int Size>
460 struct PromotionTraits<FieldVector<Field, Size>, FieldVector<Field, Size> >
461 {
462 using PromotedType = FieldVector<Field, Size>;
463 };
464
465 template<class Field, int Rows, int Cols, class T>
466 struct PromotionTraits<FieldMatrix<Field, Rows, Cols>, T>
467 {};
468
469 template<class Field, int Rows, int Cols, class T>
470 struct PromotionTraits<T, FieldMatrix<Field, Rows, Cols> >
471 {};
472
473 template<class Any, class T, class Storage, std::size_t N, std::size_t Rank>
474 struct PromotionTraits<Any, ACFem::Tensor::DenseVectorView<T, Storage, N, Rank> >
475 {};
476
477 template<class Any, class T, class Storage, std::size_t N, std::size_t Rank>
478 struct PromotionTraits<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank>, Any>
479 {};
480
481 template<class T1, class Storage1, std::size_t N1, std::size_t Rank1,
482 class T2, class Storage2, std::size_t N2, std::size_t Rank2>
483 struct PromotionTraits<ACFem::Tensor::DenseVectorView<T1, Storage1, N1, Rank1>,
484 ACFem::Tensor::DenseVectorView<T2, Storage2, N2, Rank2> >
485 {};
486
487 template<class T, class Storage, std::size_t N, std::size_t Rank>
488 struct PromotionTraits<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank>,
489 ACFem::Tensor::DenseVectorView<T, Storage, N, Rank> >
490 {};
491
492 template<class Any, class T, class Storage, std::size_t N, std::size_t Rank>
493 struct PromotionTraits<Any, ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
494 {};
495
496 template<class Any, class T, class Storage, std::size_t N, std::size_t Rank>
497 struct PromotionTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank>, Any>
498 {};
499
500 template<class T1, class Storage1, std::size_t N1, std::size_t Rank1,
501 class T2, class Storage2, std::size_t N2, std::size_t Rank2>
502 struct PromotionTraits<ACFem::Tensor::DenseVectorViewElement<T1, Storage1, N1, Rank1>,
503 ACFem::Tensor::DenseVectorViewElement<T2, Storage2, N2, Rank2> >
504 {};
505
506 template<class T, class Storage, std::size_t N, std::size_t Rank>
507 struct PromotionTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank>,
508 ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
509 {};
510
512
513 template<class T, class Storage, std::size_t N, std::size_t Rank>
514 struct DenseMatVecTraits<
515 ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
516 {
517 using derived_type = ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank>;
518 using container_type = derived_type;
519 using value_type = ACFem::Tensor::DenseVectorViewElement<T, Storage, N-1, Rank>;
520 using size_type = std::size_t;
521 };
522
523 template<class T, class Storage, std::size_t Rank>
524 struct DenseMatVecTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, 1, Rank> >
525 {
526 using derived_type = ACFem::Tensor::DenseVectorViewElement<T, Storage, 1, Rank>;
527 using container_type = derived_type;
528 using value_type = typename std::decay_t<T>::FieldType;
529 using size_type = std::size_t;
530 };
531
532 template<class T, class Storage, std::size_t Rank>
533 struct DenseMatVecTraits<
534 ACFem::Tensor::DenseVectorView<T, Storage, Rank, Rank> >
535 {
536 using derived_type = ACFem::Tensor::DenseVectorView<T, Storage, Rank, Rank>;
537 using container_type = derived_type;
538 using value_type = ACFem::Tensor::DenseVectorViewElement<T, Storage, Rank-1, Rank>;
539 using size_type = std::size_t;
540 };
541
542 template<class T, class Storage>
543 struct DenseMatVecTraits<
544 ACFem::Tensor::DenseVectorView<T, Storage, 1, 1> >
545 {
546 using derived_type = ACFem::Tensor::DenseVectorView<T, Storage, 1, 1>;
547 using container_type = derived_type;
548 using value_type = typename std::decay_t<T>::FieldType;
549 using size_type = std::size_t;
550 };
551
552#if 0
553
554 template<class T, class Storage, std::size_t N, std::size_t Rank>
555 struct FieldTraits<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank> >
556 : FieldTraits<T>
557 {};
558
559 template<class T, class Storage, std::size_t N, std::size_t Rank>
560 struct FieldTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
561 : FieldTraits<T>
562 {};
563
564#else
565
566 // kludge the field-traits until the core-developers fix their things
567 template<class T, class Storage, std::size_t N, std::size_t Rank>
568 struct FieldTraits<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank> >
569 {
570 private:
571 using Signature = ACFem::TailPart<N, typename ACFem::TensorTraits<T>::Signature>;
572 public:
573 using field_type = ACFem::Tensor::FieldVectorSeqType<typename ACFem::TensorTraits<T>::FieldType,
574 Signature>;
575 using real_type = field_type;
576 };
577
578 // kludge the field-traits until the core-developers fix their things
579 template<class T, class Storage, std::size_t N, std::size_t Rank>
580 struct FieldTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
581 {
582 private:
583 using Signature = ACFem::TailPart<N, typename ACFem::TensorTraits<T>::Signature>;
584 public:
585 using field_type = ACFem::Tensor::FieldVectorSeqType<typename ACFem::TensorTraits<T>::FieldType,
586 Signature>;
587 using real_type = field_type;
588 };
589
590#endif
591
592 template<class T, int SIZE>
593 struct IsFieldVectorSizeCorrect<ACFem::Tensor::TensorResult<T>, SIZE>
594 : ACFem::BoolConstant<ACFem::TensorTraits<T>::template dim<0>() == SIZE>
595 {};
596
597 template<class T, class Storage, std::size_t N, std::size_t Rank, int SIZE>
598 struct IsFieldVectorSizeCorrect<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank>, SIZE>
599 : ACFem::BoolConstant<ACFem::TensorTraits<T>::template dim<ACFem::TensorTraits<T>::rank - N>() == SIZE>
600 {};
601
602 template<class T, class Storage, std::size_t N, std::size_t Rank, int SIZE>
603 struct IsFieldVectorSizeCorrect<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank>, SIZE>
604 : ACFem::BoolConstant<ACFem::TensorTraits<T>::template dim<ACFem::TensorTraits<T>::rank - N>() == SIZE>
605 {};
606
607 namespace Impl {
608
609 template<class DenseMatrix, class T>
610 class DenseMatrixAssigner<
611 DenseMatrix, ACFem::Tensor::TensorResult<T>,
612 std::enable_if_t<std::decay_t<T>::rank == 2> >
613 : public ACFem::Tensor::DenseMatrixAssigner
614 {};
615
616 template<class DenseMatrix, class T, class Storage, std::size_t Rank>
617 class DenseMatrixAssigner<
618 DenseMatrix, ACFem::Tensor::DenseVectorViewElement<T, Storage, 2, Rank> >
619 : public ACFem::Tensor::DenseMatrixAssigner
620 {};
621
622 template<class DenseMatrix, class T, class Storage, std::size_t Rank>
623 class DenseMatrixAssigner<
624 DenseMatrix, ACFem::Tensor::DenseVectorView<T, Storage, 2, Rank> >
625 : public ACFem::Tensor::DenseMatrixAssigner
626 {};
627
628 } // NS Impl
629
630} // NS Dune
631
632namespace std {
633
635 // their FieldVector and DenseVector
636 template<class T, class Field>
637 struct is_convertible<Dune::ACFem::Tensor::TensorResult<T>, Dune::FieldVector<Field, 1> >
638 : bool_constant<
639 ( std::is_same<
640 typename Dune::ACFem::TensorTraits<T>::Signature,
641 typename Dune::ACFem::TensorTraits<Dune::FieldVector<Field, 1> >::Signature
642 >::value
643 && std::is_convertible<
644 typename Dune::FieldTraits<T>::field_type,
645 typename Dune::FieldTraits<Field>::field_type
646 >::value
647 )>
648 {};
649
651 // their FieldVector and DenseVector
652 template<class Field, class T>
653 struct is_same<Dune::FieldVector<Field, 1>, Dune::DenseVector<T> >
654 : std::is_base_of<Dune::DenseVector<T>, Dune::FieldVector<Field, 1> >
655 {};
656
657 template<class T, class Storage, std::size_t N, std::size_t Rank, class Field>
658 struct is_convertible<Dune::ACFem::Tensor::DenseVectorView<T, Storage, N, Rank>, Dune::FieldVector<Field, 1> >
659 : bool_constant<
660 ( std::is_same<
661 Dune::ACFem::TailPart<N, typename Dune::ACFem::TensorTraits<T>::Signature>,
662 typename Dune::ACFem::TensorTraits<Dune::FieldVector<Field, 1> >::Signature
663 >::value
664 && std::is_convertible<
665 typename Dune::FieldTraits<T>::field_type,
666 typename Dune::FieldTraits<Field>::field_type
667 >::value
668 )>
669 {};
670
671}
672
673#endif // __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_DENSEVECTORVIEW_HH__
Definition: densevectorview.hh:34
Definition: densevectorview.hh:113
The wrapper class wrapped around each expression result.
Definition: tensorresult.hh:37
constexpr auto storage(const F &f, T &&... t)
Generate an expression storage container.
Definition: storage.hh:704
typename FloatingPointClosureHelper< T >::Type FloatingPointClosure
Template alias.
Definition: fieldpromotion.hh:74
IndexConstant< SizeV< std::decay_t< T > > > Size
Gives the number of elements in tuple-likes and std::integer_sequence.
Definition: size.hh:65
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
STL namespace.
Gets the type of the n-th element of a tuple-like or the std::integral_constant corresponding to the ...
Definition: access.hh:42
TrueType if T1 and T2 have the same decay types, otherwise FalseType.
Definition: types.hh:440
Definition: densevectorview.hh:400
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)