AmpGen 2.1
Loading...
Searching...
No Matches
MetaUtils.h
Go to the documentation of this file.
1#ifndef AMPGEN_METAUTILS_H
2#define AMPGEN_METAUTILS_H
3
4#include <memory>
5#include <tuple>
6#include <vector>
7#include <string>
8#include <cxxabi.h>
9#include <algorithm>
10
11namespace AmpGen {
16
17 template <class TYPE> std::string type_string() {
18 int status = 0;
19 std::string name = abi::__cxa_demangle(typeid(TYPE).name(), nullptr, nullptr, &status);
20 if(std::is_const<typename std::remove_reference<TYPE>::type>::value) name = "const " + name;
21 if(std::is_reference<TYPE>()) name = name + "&";
22 return name;
23 }
24
25 template <class TYPE> std::string type_string(const TYPE &) { return type_string<TYPE>(); }
26
27 namespace detail {
28 template <typename T, typename... args> struct zeroType {
29 typedef T type;
30 };
31 }
32 template <int N, typename... args> using nthType = typename std::tuple_element<N, std::tuple<args...>>::type;
33
34 template <typename... args> using zeroType = typename detail::zeroType<args...>::type;
35
36 template <std::size_t I = 0, typename FuncT, typename... Tp> typename std::enable_if_t<I == sizeof...(Tp), void> for_each(std::tuple<Tp...> &, FuncT) {}
37
38 template <std::size_t I = 0, typename FuncT, typename... Tp>
39 inline typename std::enable_if_t < I<sizeof...(Tp), void> for_each(std::tuple<Tp...> &t, FuncT f) {
40 f(std::get<I>(t));
41 for_each<I + 1, FuncT, Tp...>(t, f);
42 }
43 template <typename iterator, typename... transform_types> void for_each_sequence(iterator begin, iterator end, transform_types... transforms) {
44 for_each(std::tuple<transform_types...>(transforms...), [&](auto &transform) { std::for_each(begin, end, transform); });
45 }
46
47 template <std::size_t I = 0, typename FuncT, typename... Tp> typename std::enable_if_t<I == sizeof...(Tp), void> for_each(const std::tuple<Tp...> &, FuncT) {}
48
49 template <std::size_t I = 0, typename FuncT, typename... Tp>
50 inline typename std::enable_if_t < I<sizeof...(Tp), void> for_each(const std::tuple<Tp...> &t, FuncT f) {
51 f(std::get<I>(t));
52 for_each<I + 1, FuncT, Tp...>(t, f);
53 }
54
55 template <std::size_t I = 0, typename FuncT, typename... Tp>
56 typename std::enable_if_t<I == sizeof...(Tp), void> for_each_with_counter(const std::tuple<Tp...> &, FuncT) {}
57
58 template <std::size_t I = 0, typename FuncT, typename... Tp>
59 inline typename std::enable_if_t < I<sizeof...(Tp), void> for_each_with_counter(const std::tuple<Tp...> &t, FuncT f) {
60 f(std::get<I>(t), I);
61 for_each_with_counter<I + 1, FuncT, Tp...>(t, f);
62 }
63
64 template <typename R, typename RT, typename ARGS, bool result = std::is_same<decltype(((*(R *)nullptr))(ARGS())), RT>::value> constexpr bool typeHelper(int) {
65 return result;
66 }
67
68 template <typename R, typename RT, typename ARGS> constexpr bool typeHelper(...) { return false; }
69
70 template <typename R, typename RT, typename ARGS> constexpr bool hasReturnType() { return typeHelper<R, RT, ARGS>(0); }
71 template <typename T, typename... R> constexpr bool hasConstructor() {
72 return std::is_constructible<T, R...>::value && (false == std::is_same<T, R...>::value);
73 }
74
75 template <typename arg = void, typename... args> std::vector<std::string> typelist() {
76 std::vector<std::string> rt;
77 if(type_string<arg>() != "void") {
78 rt.emplace_back(type_string<arg>());
79 auto rtp = typelist<args...>();
80 std::copy(rtp.begin(), rtp.end(), std::back_inserter(rt));
81 }
82 return rt;
83 }
84
85 template <typename> struct isTuple : std::false_type {};
86 template <typename... T> struct isTuple<std::tuple<T...>> : std::true_type {};
87 template <typename> struct isVector : std::false_type {};
88 template <typename T> struct isVector<std::vector<T>> : std::true_type {};
89 template <typename> struct is_array : std::false_type {};
90 template <typename T, std::size_t N> struct is_array<std::array<T, N>> : std::true_type {};
91
92#define def_has_function(function_name) \
93 template <typename T> struct has_##function_name { \
94 template <typename U> static auto test(int) -> decltype(std::declval<U>().function_name() == 1, std::true_type()); \
95 template <typename> static std::false_type test(...); \
96 static constexpr bool value = std::is_same<decltype(test<T>(0)), std::true_type>::value; \
97 }
98
99 template <typename... T> struct is_functor : std::false_type {};
100
101 template <typename T, typename rt, typename... args> struct is_functor<T, rt(args...)> {
102 template <typename U> static constexpr auto test(U *) -> decltype(std::declval<U>().operator()(std::declval<args>()...), std::true_type());
103 template <typename> static constexpr std::false_type test(...);
104 static constexpr bool value = std::is_same<decltype(test<T>(0)), std::true_type>::value;
105 };
106
107 template <int A, int B> struct get_power {
108 static const int value = A * get_power<A, B - 1>::value;
109 };
110 template <int A> struct get_power<A, 0> {
111 static const int value = 1;
112 };
113
114} // namespace AmpGen
115
116#endif
typename detail::zeroType< args... >::type zeroType
Definition MetaUtils.h:34
const Expression I
std::string type_string()
Utility classes for compile-time metaprogramming, such as identifying the types of arguments for gene...
Definition MetaUtils.h:17
typename std::tuple_element< N, std::tuple< args... > >::type nthType
Definition MetaUtils.h:32
std::enable_if_t< I==sizeof...(Tp), void > for_each(std::tuple< Tp... > &, FuncT)
Definition MetaUtils.h:36