Basic.hpp 4.19 KB
Newer Older
1
2
3
#pragma once

#include <algorithm>
4
#include <utility>
5

6
#include <amdis/common/Index.hpp>
7
#include <amdis/common/ConceptsBase.hpp>
8
9
10

namespace AMDiS
{
11
12
13
14
15
16
  namespace Concepts
  {
    namespace Definition
    {
      struct HasFunctorOrder
      {
17
        template <class F, int... I>
Praetorius, Simon's avatar
Praetorius, Simon committed
18
        auto require(F&& f, std::integer_sequence<int,I...>) -> decltype( order(f, I...) );
19
20
21
      };
    }

22
23
    template <class F, int N>
    constexpr bool HasFunctorOrder = models<Definition::HasFunctorOrder(F, std::make_integer_sequence<int,N>)>;
Praetorius, Simon's avatar
Praetorius, Simon committed
24
25
26

    template <class F, int N>
    using HasFunctorOrder_t = bool_t<HasFunctorOrder<F,N>>;
27
28
  }

29
30
  namespace Operation
  {
31
    /** \addtogroup operations
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
     *  @{
     **/

    /// Functor representing a static constant value
    template <class T, T value>
    struct StaticConstant
    {
      template <class... Ts>
      constexpr T operator()(Ts const&... /*args*/) const
      {
        return value;
      }
    };

    using Zero = StaticConstant<int, 0>;
    using One = StaticConstant<int, 1>;

    template <class T, T value, class... Int>
50
    constexpr int order(StaticConstant<T,value> const&, Int... /*orders*/)
51
52
53
54
55
    {
      return 0;
    }

    template <class T, T value, std::size_t J>
56
    constexpr auto partial(StaticConstant<T,value> const&, index_t<J>)
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
    {
      return Zero{};
    }

    // -------------------------------------------------------------------------

    /// (Unary-)Functor representing the identity
    struct Id
    {
      template <class T>
      constexpr T const& operator()(T const& x) const
      {
        return x;
      }

72
      friend constexpr int order(Id const&, int d)
73
74
75
76
      {
        return d;
      }

77
      friend auto partial(Id const&, index_t<0>)
78
      {
79
        return One{};
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
      }
    };

    // -------------------------------------------------------------------------

    /// Functor representing a constant value
    template <class T>
    struct Constant
    {
      constexpr Constant(T value)
        : value_(value)
      {}

      template <class... Ts>
      constexpr T const& operator()(Ts const&... /*args*/) const
      {
        return value_;
      }

    private:
      T value_;
    };

    template <class T, class... Int>
104
    constexpr int order(Constant<T> const&, Int... /*orders*/)
105
106
107
108
109
110
111
112
113
114
115
116
    {
      return 0;
    }

    template <class T, std::size_t J>
    constexpr auto partial(Constant<T> const&, index_t<J>)
    {
      return Zero{};
    }

    // -------------------------------------------------------------------------

117
118
119
120
121
122
123
124
125
126
127
128
129
130

    template <class T0, class... Ts>
    inline constexpr decltype(auto) get_element(index_t<0>, T0&& t0, Ts&&... /*ts*/)
    {
      return FWD(t0);
    }

    template <std::size_t J, class T0, class... Ts>
    inline constexpr decltype(auto) get_element(index_t<J>, T0&& /*t0*/, Ts&&... ts)
    {
      static_assert(J <= sizeof...(Ts), "");
      return get_element(index_t<J-1>{}, FWD(ts)...);
    }

131
    template <std::size_t I>
132
    struct Arg
133
134
135
136
    {
      template <class... Ts>
      constexpr auto&& operator()(Ts&&... args) const
      {
137
        return get_element(index_t<I>{}, FWD(args)...);
138
139
140
141
      }
    };

    template <std::size_t I, class... Int>
142
    constexpr int order(Arg<I> const&, Int... orders)
143
    {
144
      return get_element(index_t<I>{}, orders...);
145
146
147
    }

    template <std::size_t I, std::size_t J>
148
    constexpr auto partial(Arg<I> const&, index_t<J>)
149
150
151
152
153
154
    {
      return StaticConstant<int,(I==J ? 1 : 0)>{};
    }

    // -------------------------------------------------------------------------

155
156
157
158
159
160
161
162
163
    template <std::size_t I>
    struct Get
    {
      template <class T, int N>
      constexpr T const& operator()(Dune::FieldVector<T,N> const& vec) const
      {
        return vec[I];
      }

164
      friend constexpr int order(Get const&, int d)
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
      {
        return d;
      }
    };

    struct Get_
    {
      explicit constexpr Get_(std::size_t i)
        : i_(i)
      {}

      template <class T, int N>
      constexpr T const& operator()(Dune::FieldVector<T,N> const& vec) const
      {
        return vec[i_];
      }

182
      friend constexpr int order(Get_ const&, int d)
183
184
185
186
187
188
189
      {
        return d;
      }

      std::size_t i_;
    };

190
191
192
193
    /** @} **/

  } // end namespace Operation
} // end namespace AMDiS