Concepts.hpp 5.36 KB
Newer Older
1
2
3
4
5
#pragma once

#include <type_traits>

#include <dune/functions/common/functionconcepts.hh>
6
#include <dune/functions/functionspacebases/concepts.hh>
7

8
#include <amdis/common/ConceptsBase.hpp>
9
#include <amdis/common/Logical.hpp>
10
#include <amdis/common/TypeTraits.hpp>
11
12
13
14

namespace AMDiS
{
  /**
15
    * \defgroup Concepts Concepts
16
17
18
    * \brief Concept definitions
    * @{
    **/
19

20
  namespace Traits
21
22
  {
    template <class A, class B>
23
    struct IsSimilar
Praetorius, Simon's avatar
Praetorius, Simon committed
24
      : std::is_same<remove_cvref_t<A>, remove_cvref_t<B>> {};
25
26

    template <class A, class B>
27
28
    struct IsSimilar<Types<A>, Types<B>>
      : IsSimilar<A,B> {};
29
30

    template <>
31
    struct IsSimilar<Types<>, Types<>> : std::true_type {};
32
33

    template <class A0, class... As, class B0, class... Bs>
34
35
    struct IsSimilar<Types<A0,As...>, Types<B0,Bs...>>
      : and_t<IsSimilar<A0, B0>::value, IsSimilar<Types<As...>, Types<Bs...>>::value> {};
36

37
38
39
40
41
42
43
44
45
46
47
48

    template <class... Ts>
    struct IsSame;

    template <class T0, class... Ts>
    struct IsSame<T0, Ts...>
      : std::is_same<Types<T0,Ts...>, Types<Ts...,T0>> {};

    template <>
    struct IsSame<> : std::true_type {};


49
    template <class T>
50
    struct IsReferenceWrapper
51
52
53
      : std::false_type {};

    template <class T>
54
    struct IsReferenceWrapper<std::reference_wrapper<T>>
55
56
      : std::true_type {};

57
  } // end namespace Traits
58

Praetorius, Simon's avatar
Praetorius, Simon committed
59

60
61
62
63
64
65
66
67
68
  namespace Concepts
  {
#ifndef DOXYGEN
    namespace Definition
    {
      // f(args...)
      struct Callable
      {
        template <class F, class... Args>
Praetorius, Simon's avatar
Praetorius, Simon committed
69
70
71
        auto require(F&& f, Args&&... args) -> decltype(
          f(FWD(args)...)
        );
72
73
      };

74
75
76
77
      // idx[0]
      struct MultiIndex
      {
        template <class MI>
Praetorius, Simon's avatar
Praetorius, Simon committed
78
79
80
81
82
        auto require(MI&& idx) -> decltype(
          idx[0],
          idx.size(),
          idx.max_size()
        );
83
84
      };

85
86
87
    } // end namespace Definition
#endif // DOXYGEN

Praetorius, Simon's avatar
Praetorius, Simon committed
88

89
90
91
    /// Types are the same
    template <class... Ts>
    constexpr bool Same = Traits::IsSame<Ts...>::value;
92

Praetorius, Simon's avatar
Praetorius, Simon committed
93
94
95
96
    template <class... Ts>
    using Same_t = Traits::IsSame<Ts...>;


97
98
    /// Types are the same, up to decay of qualifiers
    template <class A, class B>
99
    constexpr bool Similar = Traits::IsSimilar<A, B>::value;
100

Praetorius, Simon's avatar
Praetorius, Simon committed
101
102
103
104
    template <class A, class B>
    using Similar_t = Traits::IsSimilar<A, B>;


105
106
107
108
109
110
111
112
113
    /// \brief A Collable is a function `F` that can be called with arguments of type `Args...`.
    /**
      * To be used as follows: `Concepts::Collable<F, Args...>`. Returns true, if
      * an instance of `F` can be called by `operator()` with arguments of type
      * `Args...`.
      **/
    template <class F, class... Args>
    constexpr bool Callable = models<Definition::Callable(F, Args...)>;

Praetorius, Simon's avatar
Praetorius, Simon committed
114
115
116
    template <class F, class... Args>
    using Callable_t = models_t<Definition::Callable(F, Args...)>;

117

118
119
120
121
122
123
124
125
126
    /// \brief A Functor is a function `F` with signature `Signature`.
    /**
      * To be used as follows: `Concepts::Functor<F, R(Args...)>`. Returns true, if
      * an instance of `F` can be called by `operator()` with arguments of type
      * `Args...` and returns a value of type `R`, i.e. `Signature := R(Args...)`.
      **/
    template <class F, class Signature> // F, Signature=Return(Arg)
    constexpr bool Functor = Dune::Functions::Concept::isFunction<F, Signature>();

Praetorius, Simon's avatar
Praetorius, Simon committed
127
128
129
130
    template <class F, class Signature> // F, Signature=Return(Arg)
    using Functor_t = bool_t<Functor<F,Signature>>;


131
132
133
134
    /// A predicate is a function that returns a boolean.
    template <class F, class... Args>
    constexpr bool Predicate = Functor<F, bool(Args...)>;

Praetorius, Simon's avatar
Praetorius, Simon committed
135
136
137
138
139
    template <class F, class... Args>
    using Predicate_t = Functor_t<F, bool(Args...)>;


    /// A multi-index type
140
141
142
    template <class MI>
    constexpr bool MultiIndex = models<Definition::MultiIndex(MI)>;

Praetorius, Simon's avatar
Praetorius, Simon committed
143
144
    template <class MI>
    using MultiIndex_t = models_t<Definition::MultiIndex(MI)>;
145

146

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    /// A Dune::Functions::HasIndexAccess type
    template <class Range, class Index>
    constexpr bool HasIndexAccess = models<Dune::Functions::Concept::HasIndexAccess(Range, Index)>;

    template <class Range, class Index>
    constexpr bool HasIndexAccess_t = models_t<Dune::Functions::Concept::HasIndexAccess(Range, Index)>;


    /// A Dune::Functions::BasisNode type
    template <class N>
    constexpr bool BasisNode = models<Dune::Functions::Concept::BasisNode(N)>;

    template <class N>
    constexpr bool BasisNode_t = models_t<Dune::Functions::Concept::BasisNode(N)>;


    /// A Dune::Functions::BasisTree type
    template <class Tree, class GV>
    constexpr bool BasisTree = models<Dune::Functions::Concept::BasisTree<GV>(Tree)>;

    template <class Tree, class GV>
    constexpr bool BasisTree_t = models_t<Dune::Functions::Concept::BasisTree<GV>(Tree)>;


171
    /// A Dune::Functions::LocalView type
172
173
174
175
176
177
178
179
180
181
    template <class LV, class GB = typename LV::GlobalBasis>
    constexpr bool LocalView = models<Dune::Functions::Concept::LocalView<GB>(LV)>;

    template <class LV, class GB = typename LV::GlobalBasis>
    using LocalView_t = models_t<Dune::Functions::Concept::LocalView<GB>(LV)>;


    /// A Dune::Functions::GlobalBasis type
    template <class GB, class GV = typename GB::GridView>
    constexpr bool GlobalBasis = models<Dune::Functions::Concept::GlobalBasis<GV>(GB)>;
182

183
184
    template <class GB, class GV = typename GB::GridView>
    using GlobalBasis_t = models_t<Dune::Functions::Concept::GlobalBasis<GV>(GB)>;
185

186
187
188
189
    /** @} **/

  } // end namespace Concepts
} // end namespace AMDiS