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

#include <type_traits>

#include <dune/functions/common/functionconcepts.hh>

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

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

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

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

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

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

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

    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 {};


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

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

56
  } // end namespace Traits
57

Praetorius, Simon's avatar
Praetorius, Simon committed
58

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

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

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

Praetorius, Simon's avatar
Praetorius, Simon committed
87

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

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


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

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


104
105
106
107
108
109
110
111
112
    /// \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
113
114
115
    template <class F, class... Args>
    using Callable_t = models_t<Definition::Callable(F, Args...)>;

116

117
118
119
120
121
122
123
124
125
    /// \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
126
127
128
129
    template <class F, class Signature> // F, Signature=Return(Arg)
    using Functor_t = bool_t<Functor<F,Signature>>;


130
131
132
133
    /// 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
134
135
136
137
138
    template <class F, class... Args>
    using Predicate_t = Functor_t<F, bool(Args...)>;


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

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

145
146
147
148
    /** @} **/

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