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 #define HMBDC_CLASS_HAS_DECLARE(member_name) \
8  template <typename T> \
9  class has_##member_name \
10  { \
11  typedef char yes_type; \
12  typedef long no_type; \
13  template <typename U> static yes_type test(decltype(&U::member_name)); \
14  template <typename U> static no_type test(...); \
15  public: \
16  enum {value = sizeof(test<T>(0)) == sizeof(yes_type)}; \
17  }
18 
19 namespace hmbdc {
20 template <typename T>
21 struct function_traits: function_traits<decltype(&T::operator())>
22 {};
23 
24 template <typename ClassType, typename ReturnType, typename ...Args>
25 struct function_traits<ReturnType(ClassType::*)(Args...) const> {
26  enum { arity = sizeof...(Args) };
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 ClassType, typename ReturnType, typename ...Args>
36 struct function_traits<ReturnType(ClassType::*)(Args...)> {
37  enum { arity = sizeof...(Args) };
38 
39  typedef ReturnType result_type;
40 
41  template <size_t i>
42  struct arg {
43  using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
44  };
45 };
46 
47 template <typename T, typename Tuple>
49 
50 template <typename T, typename ...Types>
51 struct index_in_tuple<T, std::tuple<T, Types...>> {
52  static constexpr std::size_t value = 0;
53 };
54 
55 template <typename T>
56 struct index_in_tuple<T, std::tuple<>> {
57  static constexpr std::size_t value = 0;
58 };
59 
60 template <typename T, typename U, typename ...Types>
61 struct index_in_tuple<T, std::tuple<U, Types...>> {
62  static constexpr std::size_t value = 1 + index_in_tuple<T, std::tuple<Types...>>::value;
63 };
64 
65 
66 template <typename T, typename Tuple>
68  using type = std::tuple<T>;
69 };
70 
71 template <typename T, typename ...Types>
72 struct add_if_not_in_tuple<T, std::tuple<Types ...>> {
73 private:
74  using Tuple = std::tuple<Types ...>;
75 public:
76  using type = typename std::conditional<
77  index_in_tuple<T, Tuple>::value == sizeof...(Types)
78  , std::tuple<Types ..., T>
79  , Tuple
80  >::type;
81 };
82 
83 template <typename Tuple1, typename Tuple2>
85 
86 template <typename Tuple1>
87 struct merge_tuple_unique<Tuple1, std::tuple<>> {
88  using type = Tuple1;
89 };
90 
91 template <typename Tuple1, typename T, typename ...Types>
92 struct merge_tuple_unique<Tuple1, std::tuple<T, Types...>> {
93 private:
94  using step1 = typename add_if_not_in_tuple<T, Tuple1>::type;
95 public:
96  using type = typename merge_tuple_unique<step1, std::tuple<Types...>>::type;
97 };
98 
99 template <typename Tuple>
101  static constexpr std::size_t value = 0;
102 };
103 
104 template <typename T, typename ...Ts>
105 struct max_size_in_tuple<std::tuple<T, Ts...>> {
106 private:
107  static constexpr std::size_t step1 = max_size_in_tuple<std::tuple<Ts...>>::value;
108 public:
109  static constexpr std::size_t value = step1 > sizeof(T) ? step1 : sizeof(T);
110 };
111 template <typename Tuple0, typename Tuple1>
113 
114 template <typename ...T, typename ...U>
115 struct concat_tuple<std::tuple<T...>, std::tuple<U...>> {
116  using type = std::tuple<T..., U...>;
117 };
118 
119 template <template <class, class> class pred, typename T, typename ...Ts>
121  using type = std::tuple<T>;
122 };
123 template <template <class, class> class pred, typename T
124  , typename T0, typename ...Ts>
125 struct insert_in_ordered_tuple<pred, T, std::tuple<T0, Ts...>> {
126  using type = typename std::conditional<
127  pred<T, T0>::value
128  , std::tuple<T, T0, Ts...>
129  , typename concat_tuple<
130  std::tuple<T0>
131  , typename insert_in_ordered_tuple<
132  pred, T, std::tuple<Ts...>
133  >::type
134  >::type
135  >::type;
136 };
137 
138 template <template <class, class> class pred, typename Tuple>
139 struct sort_tuple;
140 
141 template <template <class, class> class pred>
142 struct sort_tuple<pred, std::tuple<>> {
143  using type = std::tuple<>;
144 };
145 
146 template <template <class, class> class pred, typename T, typename ...Ts>
147 struct sort_tuple<pred, std::tuple<T, Ts...>> {
148  using type = typename insert_in_ordered_tuple<
149  pred
150  , T
151  , typename sort_tuple<pred, std::tuple<Ts...>>::type
152  >::type;
153 };
154 
155 template <typename Tuple, size_t from = 0, size_t to = std::tuple_size<Tuple>::value>
157 
158 template <typename ...Ts, size_t from, size_t to>
159 struct bsearch_tuple<std::tuple<Ts...>, from, to> {
160  template <typename comp>
161  bool operator()(comp&& c) {
162  if constexpr (from >= to) {
163  return false;
164  } else {
165  constexpr auto at = (from + to) / 2;
166  using atType = typename std::tuple_element<at, std::tuple<Ts...>>::type;
167  int comp_res =
168  c((atType*)nullptr);
169  if (comp_res == 0)
170  return true;
171  else if (comp_res < 0)
172  return bsearch_tuple<std::tuple<Ts...>, from, at>()(
173  std::forward<comp>(c));
174  else
175  return bsearch_tuple<std::tuple<Ts...>, at + 1, to>()(
176  std::forward<comp>(c));
177  }
178  }
179 };
180 
181 template <template <class> class target_template, typename M>
182 constexpr bool is_template = false;
183 
184 template <template <class> class target_template, typename N>
185 constexpr bool is_template<target_template, target_template<N>> = true;
186 
187 template <template <class> class target_template, typename Tuple>
189  using type = std::tuple<>;
190 };
191 
192 template <template <class> class target_template, typename T, typename ...Ts>
193 struct templatized_aggregator<target_template, std::tuple<T, Ts...>> {
194  using type =
195  typename templatized_aggregator<target_template, std::tuple<Ts...>>::type;
196 };
197 
198 template <template <class> class target_template, typename T, typename ...Ts>
199 struct templatized_aggregator<target_template, std::tuple<target_template<T>, Ts...>> {
201  , typename templatized_aggregator<target_template, std::tuple<Ts...>>::type
202  >::type;
203 };
204 
205 template <template <class> class target_template, typename Tuple>
207  using type = std::tuple<>;
208 };
209 
210 template <template <class> class target_template, typename T, typename ...Ts>
211 struct templatized_subtractor<target_template, std::tuple<T, Ts...>> {
212  using type = typename merge_tuple_unique<std::tuple<T>
213  , typename templatized_subtractor<target_template, std::tuple<Ts...>>::type
214  >::type;
215 };
216 
217 template <template <class> class target_template, typename T, typename ...Ts>
218 struct templatized_subtractor<target_template, std::tuple<target_template<T>, Ts...>> {
219  using type = typename templatized_subtractor<target_template, std::tuple<Ts...>>::type;
220 };
221 
222 template<typename T, size_t sz>
223 size_t length_of(T (&)[sz]) { return sz; }
224 
225 template <typename Base, typename MTuple>
227  using type = std::tuple<>;
228 };
229 
230 template <typename Base, typename M, typename ...Ms>
231 struct filter_in_tuple_by_base<Base, std::tuple<M, Ms...>> {
232  using type = typename std::conditional<std::is_base_of<Base, M>::value
233  , typename add_if_not_in_tuple<M, typename filter_in_tuple_by_base<Base, std::tuple<Ms...>>::type>::type
234  , typename filter_in_tuple_by_base<Base, std::tuple<Ms...>>::type
235  >::type;
236 };
237 
238 template <typename Base, typename MTuple>
240  using type = std::tuple<>;
241 };
242 
243 template <typename Base, typename M, typename ...Ms>
244 struct filter_out_tuple_by_base<Base, std::tuple<M, Ms...>> {
245  using type = typename std::conditional<!std::is_base_of<Base, M>::value
246  , typename add_if_not_in_tuple<M, typename filter_out_tuple_by_base<Base, std::tuple<Ms...>>::type>::type
247  , typename filter_out_tuple_by_base<Base, std::tuple<Ms...>>::type
248  >::type;
249 };
250 
251 template <template <class> class target_pred_template, typename MTuple>
253  using type = std::tuple<>;
254 };
255 
256 template <template <class> class target_pred_template, typename M, typename ...Ms>
257 struct filter_in_tuple<target_pred_template, std::tuple<M, Ms...>> {
258  using type = typename std::conditional<target_pred_template<M>::value
259  , typename add_if_not_in_tuple<M, typename filter_in_tuple<target_pred_template, std::tuple<Ms...>>::type>::type
260  , typename filter_in_tuple<target_pred_template, std::tuple<Ms...>>::type
261  >::type;
262 };
263 
264 template <template <class> class target_pred_template, typename MTuple>
266  using type = std::tuple<>;
267 };
268 
269 template <template <class> class target_pred_template, typename M, typename ...Ms>
270 struct filter_out_tuple<target_pred_template, std::tuple<M, Ms...>> {
271  using type = typename std::conditional<target_pred_template<M>::value
272  , typename filter_out_tuple<target_pred_template, std::tuple<Ms...>>::type
273  , typename add_if_not_in_tuple<M, typename filter_out_tuple<target_pred_template, std::tuple<Ms...>>::type>::type
274  >::type;
275 };
276 
277 template <template <class> class apply, typename Tuple>
279  using type = std::tuple<>;
280 };
281 
282 template <template <class> class apply, typename T, typename ...Ts>
283 struct apply_template_on<apply, std::tuple<T, Ts...>> {
284  using type = typename concat_tuple<std::tuple<apply<T>>
285  , typename apply_template_on<apply, std::tuple<Ts...>>::type
286  >::type;
287 };
288 
289 template <typename Tuple>
291  using type = typename merge_tuple_unique<Tuple, std::tuple<>>::type;
292 };
293 
294 template <typename TupleSub, typename TupleSup>
295 struct is_subset {
296  enum {
297  value = std::tuple_size<
298  typename remove_duplicate<TupleSup>::type>::value
299  == std::tuple_size<
301  ? 1 : 0,
302  };
303 };
304 }
Definition: MetaUtils.hpp:84
Definition: MetaUtils.hpp:252
Definition: MetaUtils.hpp:156
Definition: MetaUtils.hpp:120
Definition: MetaUtils.hpp:139
Definition: TypedString.hpp:84
Definition: MetaUtils.hpp:48
Definition: MetaUtils.hpp:290
Definition: MetaUtils.hpp:295
Definition: MetaUtils.hpp:239
Definition: MetaUtils.hpp:206
Definition: MetaUtils.hpp:112
Definition: MetaUtils.hpp:265
Definition: MetaUtils.hpp:67
Definition: MetaUtils.hpp:278
Definition: MetaUtils.hpp:100
Definition: MetaUtils.hpp:226
Definition: MetaUtils.hpp:188
Definition: Base.hpp:12
Definition: MetaUtils.hpp:21