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

#include <type_traits>

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

7
8
#include <amdis/common/ConceptsBase.hpp>
#include <amdis/common/Mpl.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
23
24
25
      : std::is_same<std::decay_t<A>, std::decay_t<B>> {};

    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
    template <class T>
37
    struct IsReferenceWrapper
38
39
40
      : std::false_type {};

    template <class T>
41
    struct IsReferenceWrapper<std::reference_wrapper<T>>
42
43
      : std::true_type {};

44
  } // end namespace Traits
45

46
47
48
49
50
51
52
53
54
  namespace Concepts
  {
#ifndef DOXYGEN
    namespace Definition
    {
      // f(args...)
      struct Callable
      {
        template <class F, class... Args>
55
        auto requires_(F&& f, Args&&... args) -> decltype( f(FWD(args)...));
56
57
      };

58
59
60
61
62
63
64
65
66
67
68
69
70
      // idx[0]
      struct MultiIndex
      {
        template <class MI>
        auto requires_(MI&& idx) -> decltype(
          Concepts::valid_expr(
            idx[0],
            idx.size(),
            idx.max_size()
            /* ,idx.resize() */
          ));
      };

71
72
73
    } // end namespace Definition
#endif // DOXYGEN

74

75
76
    /// Types are the same, up to decay of qualifiers
    template <class A, class B>
77
    constexpr bool Similar = Traits::IsSimilar<A, B>::value;
78
79
80
81
82
83
84
85
86
87

    /// \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...)>;

88

89
90
91
92
93
94
95
96
97
98
99
100
101
    /// \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>();

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

102
103
104
    template <class MI>
    constexpr bool MultiIndex = models<Definition::MultiIndex(MI)>;

105
106
107
108
109
    /** @} **/

  } // end namespace Concepts

} // end namespace AMDiS