hmbdc
simplify-high-performance-messaging-programming
MetaUtils.hpp
1 #pragma once
2 #include "hmbdc/Compile.hpp"
3 
4 #include <type_traits>
5 #include <tuple>
6 
7 namespace hmbdc {
8 template <typename T>
9 struct function_traits: function_traits<decltype(&T::operator())>
10 {};
11 
12 template <typename ClassType, typename ReturnType, typename ...Args>
13 struct function_traits<ReturnType(ClassType::*)(Args...) const> {
14  enum { arity = sizeof...(Args) };
15  typedef ReturnType result_type;
16 
17  template <size_t i>
18  struct arg {
19  using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
20  };
21 };
22 
23 template <typename ClassType, typename ReturnType, typename ...Args>
24 struct function_traits<ReturnType(ClassType::*)(Args...)> {
25  enum { arity = sizeof...(Args) };
26 
27  typedef ReturnType result_type;
28 
29  template <size_t i>
30  struct arg {
31  using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
32  };
33 };
34 
35 template <typename Base, typename Derived>
37  enum {
38  value = std::is_base_of<Base, Derived>::value
39  //&& (Base const*)((Derived const*)0xffff) == ((Base const*)0xffff) - not supported on some compilers
40  };
41 };
42 
43 template <typename T, typename Tuple>
45 
46 template <typename T, typename ...Types>
47 struct index_in_tuple<T, std::tuple<T, Types...>> {
48  static const std::size_t value = 0;
49 };
50 
51 template <typename T>
52 struct index_in_tuple<T, std::tuple<>> {
53  static const std::size_t value = 0;
54 };
55 
56 template <typename T, typename U, typename ...Types>
57 struct index_in_tuple<T, std::tuple<U, Types...>> {
58  static const std::size_t value = 1 + index_in_tuple<T, std::tuple<Types...>>::value;
59 };
60 
61 
62 template <typename T, typename Tuple>
64  using type = std::tuple<T>;
65 };
66 
67 template <typename T, typename ...Types>
68 struct add_if_not_in_tuple<T, std::tuple<Types ...>> {
69 private:
70  using Tuple = std::tuple<Types ...>;
71 public:
72  using type = typename std::conditional<
73  index_in_tuple<T, Tuple>::value == sizeof...(Types)
74  , std::tuple<Types ..., T>
75  , Tuple
76  >::type;
77 };
78 
79 template <typename Tuple1, typename Tuple2>
81 
82 template <typename Tuple1>
83 struct merge_tuple_unique<Tuple1, std::tuple<>> {
84  using type = Tuple1;
85 };
86 
87 template <typename Tuple1, typename T, typename ...Types>
88 struct merge_tuple_unique<Tuple1, std::tuple<T, Types...>> {
89 private:
90  using step1 = typename add_if_not_in_tuple<T, Tuple1>::type;
91 public:
92  using type = typename merge_tuple_unique<step1, std::tuple<Types...>>::type;
93 };
94 
95 template <typename Tuple>
97  static const std::size_t value = 0;
98 };
99 
100 template <typename T, typename ...Ts>
101 struct max_size_in_tuple<std::tuple<T, Ts...>> {
102 private:
103  static const std::size_t step1 = max_size_in_tuple<std::tuple<Ts...>>::value;
104 public:
105  static const std::size_t value = step1 > sizeof(T) ? step1 : sizeof(T);
106 };
107 template <typename Tuple0, typename Tuple1>
109 
110 template <typename ...T, typename ...U>
111 struct concat_tuple<std::tuple<T...>, std::tuple<U...>> {
112  using type = std::tuple<T..., U...>;
113 };
114 
115 template <template <class, class> class pred, typename T, typename ...Ts>
117  using type = std::tuple<T>;
118 };
119 template <template <class, class> class pred, typename T
120  , typename T0, typename ...Ts>
121 struct insert_in_ordered_tuple<pred, T, std::tuple<T0, Ts...>> {
122  using type = typename std::conditional<
123  pred<T, T0>::value
124  , std::tuple<T, T0, Ts...>
125  , typename concat_tuple<
126  std::tuple<T0>
127  , typename insert_in_ordered_tuple<
128  pred, T, std::tuple<Ts...>
129  >::type
130  >::type
131  >::type;
132 };
133 
134 template <template <class, class> class pred, typename Tuple>
135 struct sort_tuple;
136 
137 template <template <class, class> class pred>
138 struct sort_tuple<pred, std::tuple<>> {
139  using type = std::tuple<>;
140 };
141 
142 template <template <class, class> class pred, typename T, typename ...Ts>
143 struct sort_tuple<pred, std::tuple<T, Ts...>> {
144  using type = typename insert_in_ordered_tuple<
145  pred
146  , T
147  , typename sort_tuple<pred, std::tuple<Ts...>>::type
148  >::type;
149 };
150 
151 #if __GNUC_PREREQ(9,0)
152 template <typename Tuple, size_t from = 0, size_t to = std::tuple_size<Tuple>::value>
153 struct bsearch_tuple;
154 
155 template <typename ...Ts, size_t from, size_t to>
156 struct bsearch_tuple<std::tuple<Ts...>, from, to> {
157  template <typename comp>
158  bool operator()(comp&& c) {
159  if constexpr (from >= to) {
160  return false;
161  } else {
162  constexpr auto at = (from + to) / 2;
163  using atType = typename std::tuple_element<at, std::tuple<Ts...>>::type;
164  int comp_res =
165  c((atType*)nullptr);
166  if (comp_res == 0)
167  return true;
168  else if (comp_res < 0)
169  return bsearch_tuple<std::tuple<Ts...>, from, at>()(
170  std::forward<comp>(c));
171  else
172  return bsearch_tuple<std::tuple<Ts...>, at + 1, to>()(
173  std::forward<comp>(c));
174  }
175  }
176 };
177 
178 template <template <class> class target_template, typename M>
179 constexpr bool is_template = false;
180 
181 template <template <class> class target_template, typename N>
182 constexpr bool is_template<target_template, target_template<N>> = true;
183 
184 #endif
185 
186 template <template <class> class target_template, typename Tuple>
188  using type = std::tuple<>;
189 };
190 
191 template <template <class> class target_template, typename T, typename ...Ts>
192 struct templatized_aggregator<target_template, std::tuple<T, Ts...>> {
193  using type =
194  typename templatized_aggregator<target_template, std::tuple<Ts...>>::type;
195 };
196 
197 template <template <class> class target_template, typename T, typename ...Ts>
198 struct templatized_aggregator<target_template, std::tuple<target_template<T>, Ts...>> {
200  , typename templatized_aggregator<target_template, std::tuple<Ts...>>::type
201  >::type;
202 };
203 
204 template <template <class> class target_template, typename Tuple>
206  using type = std::tuple<>;
207 };
208 
209 template <template <class> class target_template, typename T, typename ...Ts>
210 struct templatized_subtractor<target_template, std::tuple<T, Ts...>> {
211  using type = typename merge_tuple_unique<std::tuple<T>
212  , typename templatized_subtractor<target_template, std::tuple<Ts...>>::type
213  >::type;
214 };
215 
216 template <template <class> class target_template, typename T, typename ...Ts>
217 struct templatized_subtractor<target_template, std::tuple<target_template<T>, Ts...>> {
218  using type = typename templatized_subtractor<target_template, std::tuple<Ts...>>::type;
219 };
220 
221 template<typename T, size_t sz>
222 size_t length_of(T (&)[sz]) { return sz; }
223 }
Definition: MetaUtils.hpp:80
Definition: MetaUtils.hpp:116
Definition: MetaUtils.hpp:135
Definition: Topic.hpp:44
Definition: MetaUtils.hpp:44
Definition: MetaUtils.hpp:36
Definition: MetaUtils.hpp:205
Definition: MetaUtils.hpp:108
Definition: MetaUtils.hpp:63
Definition: MetaUtils.hpp:96
Definition: MetaUtils.hpp:187
Definition: Base.hpp:13
Definition: MetaUtils.hpp:9