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
12{
17
18 template <class TYPE> std::string type_string()
19 {
20 int status = 0;
21 std::string name = abi::__cxa_demangle( typeid( TYPE ).name(), nullptr, nullptr, &status );
22 if( std::is_const<typename std::remove_reference<TYPE>::type>::value )
23 name = "const " + name;
24 if( std::is_reference<TYPE>() ) name = name + "&";
25 return name;
26 }
27
28 template <class TYPE> std::string type_string( const TYPE& ) { return type_string<TYPE>(); }
29
30 namespace detail {
31 template<typename T, typename... args> struct zeroType { typedef T type; };
32 }
33 template<int N, typename... args> using nthType = typename std::tuple_element<N, std::tuple<args...>>::type;
34
35 template<typename... args> using zeroType = typename detail::zeroType<args...>::type;
36
37 template <std::size_t I = 0, typename FuncT, typename... Tp>
38 typename std::enable_if_t<I == sizeof...( Tp ), void>
39 for_each( std::tuple<Tp...>&, FuncT ){}
40
41 template <std::size_t I = 0, typename FuncT, typename... Tp>
42 inline typename std::enable_if_t< I<sizeof...( Tp ), void> for_each( std::tuple<Tp...>& t, FuncT f )
43 {
44 f( std::get<I>( t ) );
45 for_each<I + 1, FuncT, Tp...>( t, f );
46 }
47 template <typename iterator, typename... transform_types>
48 void for_each_sequence( iterator begin, iterator end, transform_types... transforms)
49 {
50 for_each( std::tuple<transform_types...>(transforms...), [&](auto& transform){ std::for_each( begin, end, transform ); } );
51 }
52
53 template <std::size_t I = 0, typename FuncT, typename... Tp>
54 typename std::enable_if_t<I == sizeof...( Tp ), void>
55 for_each( const std::tuple<Tp...>&, FuncT ){}
56
57 template <std::size_t I = 0, typename FuncT, typename... Tp>
58 inline typename std::enable_if_t< I<sizeof...( Tp ), void> for_each( const std::tuple<Tp...>& t, FuncT f )
59 {
60 f( std::get<I>( t ) );
61 for_each<I + 1, FuncT, Tp...>( t, f );
62 }
63
64 template <std::size_t I = 0, typename FuncT, typename... Tp>
65 typename std::enable_if_t<I == sizeof...( Tp ), void>
66 for_each_with_counter( const std::tuple<Tp...>&, FuncT ){}
67
68 template <std::size_t I = 0, typename FuncT, typename... Tp>
69 inline typename std::enable_if_t< I<sizeof...( Tp ), void> for_each_with_counter( const std::tuple<Tp...>& t, FuncT f )
70 {
71 f( std::get<I>( t ), I);
72 for_each_with_counter<I + 1, FuncT, Tp...>( t, f );
73 }
74
75
76 template <typename R,
77 typename RT,
78 typename ARGS,
79 bool result = std::is_same<decltype( ( ( *(R*)nullptr ) )( ARGS() ) ), RT>::value>
80 constexpr bool typeHelper( int )
81 {
82 return result;
83 }
84
85 template <typename R,
86 typename RT,
87 typename ARGS>
88 constexpr bool typeHelper( ... )
89 {
90 return false;
91 }
92
93 template <typename R,
94 typename RT,
95 typename ARGS>
96 constexpr bool hasReturnType()
97 {
98 return typeHelper<R, RT, ARGS>( 0 );
99 }
100 template <typename T, typename... R> constexpr bool hasConstructor()
101 {
102 return std::is_constructible<T,R...>::value && (false == std::is_same<T, R...>::value);
103 }
104
105
106 template <typename arg=void, typename... args> std::vector<std::string> typelist()
107 {
108 std::vector< std::string > rt;
109 if( type_string<arg>() != "void" ) {
110 rt.emplace_back( type_string<arg>() );
111 auto rtp = typelist<args...>();
112 std::copy( rtp.begin(), rtp.end(), std::back_inserter(rt) );
113 }
114 return rt;
115 }
116
117 template <typename> struct isTuple: std::false_type {};
118 template <typename ...T> struct isTuple<std::tuple<T...>>: std::true_type {};
119 template <typename> struct isVector : std::false_type {};
120 template <typename T> struct isVector<std::vector<T>> : std::true_type {};
121 template <typename> struct is_array : std::false_type {};
122 template <typename T, std::size_t N> struct is_array<std::array<T,N>> : std::true_type {};
123
124
125#define def_has_function(function_name) \
126 template <typename T> \
127 struct has_##function_name { \
128 template<typename U> static auto test(int) -> decltype(std::declval<U>().function_name() == 1, std::true_type()); \
129 template<typename> static std::false_type test(...); \
130 static constexpr bool value = std::is_same<decltype(test<T>(0)), std::true_type>::value; \
131 };
132
133 template<typename ...T>
134 struct is_functor : std::false_type {};
135
136 template<typename T, typename rt, typename... args>
137 struct is_functor<T, rt(args...)> {
138 template<typename U>
139 static constexpr auto test(U*) -> decltype(std::declval<U>().operator()( std::declval<args>()...), std::true_type());
140 template<typename> static constexpr std::false_type test(...);
141 static constexpr bool value = std::is_same<decltype(test<T>(0)), std::true_type>::value ;
142 };
143
144 template <int A, int B> struct get_power
145 {
146 static const int value = A * get_power<A, B - 1>::value;
147 };
148 template <int A> struct get_power<A, 0>
149 {
150 static const int value = 1;
151 };
152
153} // namespace AmpGen
154
155#endif
typename detail::zeroType< args... >::type zeroType
Definition MetaUtils.h:35
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:18
typename std::tuple_element< N, std::tuple< args... > >::type nthType
Definition MetaUtils.h:33
std::enable_if_t< I==sizeof...(Tp), void > for_each(std::tuple< Tp... > &, FuncT)
Definition MetaUtils.h:39