ConceptsBase.hpp 1.29 KB
Newer Older
1
2
3
4
#pragma once

#include <type_traits>

5
6
7
8
9
10
11
#if defined(DOXYGEN)
  #define REQUIRES(...)
  #define CONCEPT constexpr
#else
  #define REQUIRES(...) std::enable_if_t<__VA_ARGS__ , int>* = nullptr
  #define CONCEPT constexpr
#endif
12

13
14
namespace AMDiS
{
15
  namespace Impl
16
  {
17
18
19
20
    // Workaround for MSVC (problems with alias templates in pack expansion)
    template <class... Args>
    struct VoidType { using type = void; };
  }
21

22
23
  template <class... Args>
  using Void_t = typename Impl::VoidType<Args...>::type;
24

25

26
  namespace Concepts
27
  {
28
29
30
31
32
33
    namespace _aux
    {
      template <class Concept, class = Void_t<>>
      struct models
          : std::false_type
      {};
34

35
36
37
38
      template <class Concept, class... Ts>
      struct models<Concept(Ts...), Void_t< decltype(std::declval<Concept>().requires_(std::declval<Ts>()...)) >>
          : std::true_type
      {};
39

40
41
42
43
      struct valid_expr
      {
        template <class... Ts>
        void operator()(Ts&&...) const;
44

45
46
47
48
49
#if defined(__GNUC__) && !defined(__clang__)
        template <class... Ts>
        void operator()(Ts const&...) const;
#endif
      };
50

51
    } // end namespace _aux
52

53
54
    template <class Concept>
    constexpr bool models = _aux::models<Concept>::value;
55

56
    constexpr _aux::valid_expr valid_expr = {};
57

58
  } // end namespace Concepts
59
60

} // end namespace AMDiS