MultiTypeVector.hpp 3.57 KB
Newer Older
1
2
3
#pragma once

#include <tuple>
4
#include <type_traits>
5

6
#include <dune/common/ftraits.hh>
7
8
#include <dune/functions/common/indexaccess.hh>

9
10
11
#include <amdis/common/Concepts.hpp>
#include <amdis/common/Loops.hpp>
#include <amdis/common/Mpl.hpp>
12
13
#include <amdis/common/StaticSize.hpp>
#include <amdis/common/TypeTraits.hpp>
14
15
16
17
18
19
20
21
22
23
24
25
26

namespace AMDiS
{
  // forward declaration
  template <class... FV>
  class MultiTypeVector;
}

namespace Dune
{
  template <class... FV>
  struct FieldTraits<AMDiS::MultiTypeVector<FV...>>
  {
27
28
    using field_type = std::common_type_t<typename Dune::FieldTraits<FV>::field_type...>;
    using real_type = std::common_type_t<typename Dune::FieldTraits<FV>::real_type...>;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  };
}


namespace AMDiS
{
  template <class... FV>
  class MultiTypeVector
      : public std::tuple<FV...>
  {
    using Self = MultiTypeVector;
    using Super = std::tuple<FV...>;

  public:
    using field_type = typename Dune::FieldTraits<Self>::field_type;
    using real_type = typename Dune::FieldTraits<Self>::real_type;
    using size_type = std::size_t;

47
    static constexpr int dimension = std::tuple_size<Super>::value;
48
49
50
51

    template <class... FV_,
      REQUIRES( Concepts::Similar<Types<FV...>, Types<FV_...>> )>
    MultiTypeVector(FV_&&... fv)
52
      : Super(FWD(fv)...)
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    {}

    /// Default construction of tuple of FieldVectors
    MultiTypeVector() = default;

    /// Construct tuple by initializing all tuple elements with a constant value
    explicit MultiTypeVector(real_type value)
    {
      *this = value;
    }

    /// Assignment of real number to all tuple elements
    MultiTypeVector& operator=(real_type value)
    {
      forEach(*this, [value](auto& fv) { fv = value; });
      return *this;
    }

    // Compound assignment operator +=
    MultiTypeVector& operator+=(MultiTypeVector const& that)
    {
      forEach(range_<0,dimension>, [&that,this](auto const _i) { (*this)[_i] += that[_i]; });
      return *this;
    }

    // Compound assignment operator -=
    MultiTypeVector& operator-=(MultiTypeVector const& that)
    {
      forEach(range_<0,dimension>, [&that,this](auto const _i) { (*this)[_i] -= that[_i]; });
      return *this;
    }

    // Scaling of all tuple elements by a constant value
    MultiTypeVector& operator*=(real_type value)
    {
      forEach(*this, [value](auto& fv) { fv *= value; });
      return *this;
    }

    // Scaling of all tuple elements by the inverse of a constant value
    MultiTypeVector& operator/=(real_type value)
    {
      forEach(*this, [value](auto& fv) { fv /= value; });
      return *this;
    }

    /// Const access to the tuple elements
    template <std::size_t I>
    decltype(auto) operator[](const index_t<I>&) const
    {
      return std::get<I>(*this);
    }

    /// Mutable access to the tuple elements
    template <std::size_t I>
    decltype(auto) operator[](const index_t<I>&)
    {
      return std::get<I>(*this);
    }

    /// Const access to the vector using multi-indices
    template <class Index,
      REQUIRES( Concepts::MultiIndex<Index> )>
    decltype(auto) operator[](Index const& index) const
    {
      return Dune::Functions::hybridMultiIndexAccess<field_type const&>(*this, index);
    }

    /// Mutable access to the vector using multi-indices
    template <class Index,
      REQUIRES( Concepts::MultiIndex<Index> )>
    decltype(auto) operator[](Index const& index)
    {
      return Dune::Functions::hybridMultiIndexAccess<field_type&>(*this, index);
    }

    /// Return number of elements of the tuple
    static constexpr std::size_t size()
    {
      return dimension;
    }
  };

} // end namespace AMDiS