Mpl.hpp 4.31 KB
Newer Older
1
2
3
#pragma once

// std c++ headers
4
#include <tuple>
5
#include <type_traits>
6
#include <utility>
7
8
9
10
11

namespace AMDiS
{
  // introduce some shortcuts for integral constants
  // ---------------------------------------------------------------------------
12
13
14
15
16
17

  /// A wrapper for int type
  template <int I>
  using int_t = std::integral_constant<int, I>;

  /// Variable template to generate int-type
18
  template <int I>
19
20
  constexpr int_t<I> int_ = {};

21
  /// class that represents a sequence of integers
22
23
24
25
26
  template <int... I>
  using Ints = std::integer_sequence<int, I...>;

  template <std::size_t I, int... J>
  auto get(Ints<J...>) { return std::get<I>(std::make_tuple(int_<J>...)); }
27

28
29
30
31
32
33
34
35
36

  /// A wrapper for std::size_t type
  template <std::size_t I>
  using index_t = std::integral_constant<std::size_t, I>;

  /// Variable template to generate std::size_t-type
  template <std::size_t I>
  constexpr index_t<I> index_ = {};

37

38
  /// class that represents a sequence of indices
39
40
41
42
43
  template <std::size_t... I>
  using Indices = std::index_sequence<I...>;

  template <std::size_t I, std::size_t... J>
  auto get(Indices<J...>) { return std::get<I>(std::make_tuple(index_<J>...)); }
44
45
46
47
48
49
50


  /// A wrapper for bool types
  template <bool B>
  using bool_t  = std::integral_constant<bool, B>;

  /// Variable template to generate bool type
51
  template <bool B>
52
  constexpr bool_t<B> bool_ = {};
53

54
55
  static constexpr bool_t<true>  _true  {};
  static constexpr bool_t<false> _false {};
56

57
58

  namespace Impl
59
  {
60
61
62
63
64
    /// A range of indices [I,J)
    template <class Int, Int I, Int J>
    struct range_impl
    {
      using type = range_impl;
65

66
67
      /// Return the first element in the range
      static constexpr auto begin() { return std::integral_constant<Int, I>{}; }
68

69
70
      /// Returns the element after the last element in the range
      static constexpr auto end() { return std::integral_constant<Int, J>{}; }
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
      /// Returns the ith index in the range as integral constant
      template <std::size_t i>
      constexpr auto operator[](index_t<i>) const
      {
        return std::integral_constant<Int, I+Int(i)>{};
      }

      /// Return whether the range is empty
      static constexpr bool empty() { return I >= J; }

      /// Returns the size of the range
      static constexpr auto size() { return std::integral_constant<Int, J-I>{}; }
    };

    /// Extracts the Ith element element from the range
    template <std::size_t I, class Int, Int begin, Int end>
    constexpr auto get(range_impl<Int, begin, end> const& r) { return r[index_<I>]; }

  } // end namespace Impl

  template <std::size_t I, std::size_t J>
  using range_t = Impl::range_impl<std::size_t, I, J>;

  template <std::size_t I, std::size_t J>
  constexpr range_t<I,J> range_ = {};
97
98
99
100
101
102

  // some boolean operations
  // ---------------------------------------------------------------------------

  namespace Impl
  {
103
    template <bool...> struct all_helper {};
104

105
  } // end namespace Impl
106

107
108
  template <bool... Bs>
  using all_of_t = std::is_same<Impl::all_helper<true, Bs...>, Impl::all_helper<Bs..., true>>;
109

Praetorius, Simon's avatar
Praetorius, Simon committed
110
111
112
  template <bool... Bs>
  constexpr bool all_of_v = all_of_t<Bs...>::value;

113
114
  template <bool... Bs>
  using and_t = all_of_t<Bs...>;
115

116
117
  template <bool... Bs>
  using none_of_t = std::is_same<Impl::all_helper<false, Bs...>, Impl::all_helper<Bs..., false>>;
118

Praetorius, Simon's avatar
Praetorius, Simon committed
119
120
121
  template <bool... Bs>
  constexpr bool none_of_v = none_of_t<Bs...>::value;

122
123
  template <bool... Bs>
  using any_of_t = bool_t<not none_of_t<Bs...>::value>;
124

Praetorius, Simon's avatar
Praetorius, Simon committed
125
126
127
  template <bool... Bs>
  constexpr bool any_of_v = any_of_t<Bs...>::value;

128
  template <bool... Bs>
129
130
  using or_t = any_of_t<Bs...>;

131

132
133
134
135
136
  template <bool... Bs>
  constexpr bool_t<and_t<Bs...>::value> and_ = {};

  template <bool B0, bool B1>
  constexpr bool_t<B0 && B1> operator&&(bool_t<B0>, bool_t<B1>) { return {}; }
137
138
139


  template <bool... Bs>
140
  constexpr bool_t<or_t<Bs...>::value> or_ = {};
141

142
143
  template <bool B0, bool B1>
  constexpr bool_t<B0 || B1> operator||(bool_t<B0>, bool_t<B1>) { return {}; }
144
145


146
147
148
149
150
151
152
153
  template <bool B>
  using not_t = bool_t<!B>;

  template <bool B>
  constexpr bool_t<not_t<B>::value> not_ = {};

  template <bool B>
  constexpr bool_t<!B> operator!(bool_t<B>) { return {}; }
154
155


156
157
  template <class T, T value0, T... values>
  using is_equal = all_of_t<(value0 == values)...>;
158
159

  template <class T, class... Ts>
160
  using is_one_of = or_t<std::is_same<T, Ts>::value...>;
161
162

} // end namespace AMDiS